From 85d0f8dcbda75f477b1c1bbc14ebda644650db1e Mon Sep 17 00:00:00 2001 From: htt1997 Date: Fri, 28 Jun 2024 18:42:32 +0800 Subject: [PATCH] update Signed-off-by: htt1997 --- data_object/CMakeLists.txt | 2 +- data_object/bundle.json | 5 +- .../include/adaptor/flat_object_store.h | 8 +- .../include/adaptor/object_callback_impl.h | 14 +- .../innerkitsimpl/include/common/anonymous.h | 45 + .../include/common/object_radar_reporter.h | 72 + .../include/communicator/softbus_adapter.h | 57 +- .../innerkitsimpl/include/object_callback.h | 4 +- .../src/adaptor/distributed_object_impl.cpp | 2 + .../adaptor/distributed_object_store_impl.cpp | 6 + .../adaptor/flat_object_storage_engine.cpp | 16 +- .../src/adaptor/flat_object_store.cpp | 111 +- .../src/adaptor/object_callback_impl.cpp | 12 +- .../process_communicator_impl.cpp | 17 +- .../communicator/softbus_adapter_standard.cpp | 501 ++--- .../src/object_callback_stub.cpp | 10 +- .../test/unittest/mock/src/mock_soft_bus.cpp | 26 + .../test/unittest/src/app_pipe_mgr_test.cpp | 4 +- .../test/unittest/src/communicator_test.cpp | 115 +- .../test/unittest/src/object_store_test.cpp | 38 +- .../adaptor/js_distributedobjectstore.h | 1 - .../src/adaptor/js_distributedobjectstore.cpp | 15 - .../jskitsimpl/src/adaptor/js_watcher.cpp | 9 +- .../jskitsimpl/src/adaptor/notifier_impl.cpp | 13 +- data_object/interfaces/innerkits/BUILD.gn | 13 +- data_object/interfaces/jskits/BUILD.gn | 10 +- .../jskits/distributed_data_object.js | 53 +- data_share/OAT.xml | 67 + data_share/bundle.json | 6 +- data_share/datashare.gni | 14 - .../napi/common/src/datashare_error_impl.cpp | 2 +- .../common/src/datashare_predicates_proxy.cpp | 3 + .../frameworks/js/napi/dataShare/BUILD.gn | 13 +- .../js/napi/dataShare/src/async_call.cpp | 12 +- .../js/napi/datashare_ext_ability/BUILD.gn | 2 + .../datashare_ext_ability_context/BUILD.gn | 2 + .../native/common/include/callbacks_manager.h | 27 +- .../common/include/datashare_radar_reporter.h | 172 ++ .../common/include/datashare_string_utils.h | 2 + ...ibuteddata_data_share_ipc_interface_code.h | 2 +- .../common/include/idata_share_service.h | 2 +- .../common/src/datashare_string_utils.cpp | 8 + .../native/common/src/shared_block.cpp | 1 + .../src/general_controller_provider_impl.cpp | 9 +- .../src/general_controller_service_impl.cpp | 4 +- .../consumer/include/datashare_connection.h | 4 + .../consumer/src/datashare_connection.cpp | 85 +- .../native/consumer/src/datashare_helper.cpp | 89 +- .../consumer/src/datashare_helper_impl.cpp | 27 + .../permission/src/data_share_permission.cpp | 3 +- .../native/provider/include/datashare_stub.h | 1 + .../native/provider/src/datashare_stub.cpp | 15 +- .../provider/src/datashare_uv_queue.cpp | 4 +- .../proxy/include/data_share_manager_impl.h | 1 + .../proxy/include/data_share_service_proxy.h | 2 +- .../native/proxy/src/ams_mgr_proxy.cpp | 3 +- .../proxy/src/data_share_manager_impl.cpp | 7 +- .../proxy/src/data_share_service_proxy.cpp | 75 +- .../src/published_data_subscriber_manager.cpp | 15 +- .../proxy/src/rdb_subscriber_manager.cpp | 6 +- data_share/interfaces/inner_api/BUILD.gn | 50 +- .../interfaces/inner_api/common/BUILD.gn | 6 +- .../common/include/datashare_errno.h | 26 + .../consumer/include/datashare_helper.h | 19 +- data_share/test/native/BUILD.gn | 12 +- .../src/errorcode_test.cpp | 10 +- .../src/slientaccess_test.cpp | 45 + datamgr_service/bundle.json | 10 +- datamgr_service/datamgr_service.gni | 2 - .../distributeddataservice/adapter/BUILD.gn | 2 +- .../adapter/account/BUILD.gn | 3 +- .../src/account_delegate_default_impl.cpp | 6 + .../src/account_delegate_default_impl.h | 1 + .../src/account_delegate_normal_impl.cpp | 47 +- .../src/account_delegate_normal_impl.h | 3 + .../adapter/account/test/BUILD.gn | 10 +- .../account/test/account_delegate_test.cpp | 56 +- .../adapter/broadcaster/BUILD.gn | 2 + .../adapter/communicator/BUILD.gn | 3 +- .../src/device_manager_adapter.cpp | 74 +- .../src/softbus_adapter_standard.cpp | 9 +- .../communicator/src/softbus_client.cpp | 2 +- .../adapter/communicator/test/BUILD.gn | 41 +- .../communication_provider_impl_test.cpp | 240 +++ .../unittest/device_manager_adapter_test.cpp | 57 +- .../softbus_adapter_standard_test.cpp | 222 ++ .../adapter/dfx/BUILD.gn | 8 +- .../adapter/dfx/src/hiview_adapter.cpp | 299 ++- .../adapter/dfx/src/hiview_adapter.h | 4 +- .../adapter/dfx/src/radar_reporter.cpp | 72 + .../unittest/distributeddata_dfx_ut_test.cpp | 206 ++ .../include/account/account_delegate.h | 5 +- .../include/communicator/commu_types.h | 1 + .../communicator/communicator_context.h | 2 +- .../communicator/device_manager_adapter.h | 8 +- .../adapter/include/dfx/radar_reporter.h | 112 + .../adapter/permission/BUILD.gn | 2 + .../adapter/utils/BUILD.gn | 2 + .../distributeddataservice/app/BUILD.gn | 62 +- .../distributeddataservice/app/CMakeLists.txt | 1 + .../app/src/checker/BUILD.gn | 2 + .../app/src/feature_stub_impl.cpp | 8 + .../app/src/feature_stub_impl.h | 1 + .../app/src/flowctrl_manager/BUILD.gn | 8 +- .../app/src/installer/BUILD.gn | 16 +- .../app/src/installer/installer_impl.cpp | 11 + .../app/src/installer/installer_impl.h | 1 + .../app/src/kvstore_data_service.cpp | 56 +- .../app/src/kvstore_data_service.h | 5 +- .../app/src/kvstore_data_service_stub.cpp | 4 + .../app/src/kvstore_meta_manager.cpp | 226 +- .../app/src/kvstore_meta_manager.h | 20 +- .../app/src/security/security.cpp | 6 +- .../route_head_handler_impl.cpp | 7 + .../session_manager/route_head_handler_impl.h | 2 + .../src/session_manager/upgrade_manager.cpp | 80 +- .../app/src/session_manager/upgrade_manager.h | 10 +- .../distributeddataservice/app/test/BUILD.gn | 87 +- .../fuzztest/dataservicestub_fuzzer/BUILD.gn | 7 +- .../distributeddataservice/framework/BUILD.gn | 11 +- .../framework/CMakeLists.txt | 1 + .../changeevent/remote_change_event.cpp | 28 + .../framework/cloud/cloud_config_manager.cpp | 4 +- .../framework/cloud/cloud_info.cpp | 12 +- .../framework/cloud/cloud_server.cpp | 11 +- .../framework/cloud/schema_meta.cpp | 4 + .../framework/eventcenter/event_center.cpp | 3 +- .../framework/feature/feature_system.cpp | 5 + .../include/changeevent/remote_change_event.h | 49 + .../include/cloud/cloud_config_manager.h | 1 - .../framework/include/cloud/cloud_event.h | 3 +- .../framework/include/cloud/cloud_info.h | 8 +- .../framework/include/cloud/cloud_server.h | 7 +- .../framework/include/cloud/schema_meta.h | 12 + .../framework/include/cloud/sharing_center.h | 7 +- .../include/commonevent/data_change_event.h | 6 +- .../include/commonevent/data_sync_event.h | 51 + .../include/directory/directory_manager.h | 2 +- .../framework/include/eventcenter/event.h | 4 +- .../include/feature/feature_system.h | 1 + .../include/metadata/auto_launch_meta_data.h | 35 + .../include/metadata/matrix_meta_data.h | 2 +- .../include/metadata/meta_data_manager.h | 5 +- .../include/metadata/store_meta_data.h | 6 +- .../include/metadata/version_meta_data.h | 2 +- .../include/serializable/serializable.h | 10 +- .../framework/include/snapshot/bind_event.h | 2 +- .../framework/include/store/auto_cache.h | 4 +- .../framework/include/store/general_store.h | 24 +- .../framework/include/store/general_value.h | 1 + .../framework/include/utils/anonymous.h | 2 +- .../metadata/auto_launch_meta_data.cpp | 41 + .../framework/metadata/meta_data_manager.cpp | 53 +- .../framework/metadata/store_meta_data.cpp | 24 +- .../metadata/store_meta_data_local.cpp | 3 +- .../framework/store/auto_cache.cpp | 31 +- .../framework/test/BUILD.gn | 52 +- .../framework/test/cloud_test.cpp | 171 ++ .../framework/test/feature_test.cpp | 9 +- .../framework/test/general_store_test.cpp | 11 +- .../framework/test/meta_data_test.cpp | 83 +- .../test/store_meta_data_local_test.cpp | 34 +- .../framework/test/store_test.cpp | 89 +- .../framework/test/utils_test.cpp | 63 +- .../framework/utils/anonymous.cpp | 8 +- .../rust/connect_adapter/BUILD.gn | 3 + .../rust/extension/BUILD.gn | 2 + .../rust/extension/cloud_server_impl.cpp | 29 +- .../rust/extension/cloud_server_impl.h | 6 +- .../distributeddataservice/service/BUILD.gn | 14 +- .../service/CMakeLists.txt | 1 + .../service/cloud/cloud_service_impl.cpp | 279 ++- .../service/cloud/cloud_service_impl.h | 21 +- .../service/cloud/cloud_value_util.cpp | 21 + .../service/cloud/cloud_value_util.h | 3 + .../service/cloud/sync_manager.cpp | 258 ++- .../service/cloud/sync_manager.h | 24 +- .../service/common/xcollie.cpp | 27 + .../service/common/xcollie.h | 34 + .../service/data_share/BUILD.gn | 10 +- .../data_share/common/app_connect_manager.cpp | 3 + .../data_share/common/bundle_mgr_proxy.cpp | 27 +- .../data_share/common/bundle_mgr_proxy.h | 1 + .../service/data_share/common/db_delegate.cpp | 11 +- .../service/data_share/common/db_delegate.h | 2 - .../common/extension_ability_manager.cpp | 1 + .../data_share/common/rdb_delegate.cpp | 27 +- .../service/data_share/common/rdb_delegate.h | 4 +- .../data_share/common/scheduler_manager.cpp | 18 +- .../data_share/common/scheduler_manager.h | 3 +- .../service/data_share/common/uri_utils.h | 2 +- .../data_share/data_provider_config.cpp | 15 +- .../service/data_share/data_provider_config.h | 2 + .../data_share/data_share_db_config.cpp | 29 +- .../service/data_share/data_share_db_config.h | 2 + .../data_share/data_share_profile_config.cpp | 18 + .../data_share/data_share_profile_config.h | 9 + .../data_share/data_share_service_impl.cpp | 202 +- .../data_share/data_share_service_impl.h | 14 +- .../data_share/data_share_service_stub.cpp | 60 +- .../data_share/data_share_service_stub.h | 92 +- .../service/data_share/idata_share_service.h | 4 +- .../general/load_config_common_strategy.cpp | 2 +- .../rdb_subscriber_manager.cpp | 11 +- .../data_share/sys_event_subscriber.cpp | 56 + .../service/data_share/sys_event_subscriber.h | 36 + .../service/kvdb/kv_radar_reporter.h | 86 + .../service/kvdb/kvdb_general_store.cpp | 275 ++- .../service/kvdb/kvdb_general_store.h | 20 +- .../service/kvdb/kvdb_notifier_proxy.cpp | 16 +- .../service/kvdb/kvdb_notifier_proxy.h | 3 +- .../service/kvdb/kvdb_query.h | 4 +- .../service/kvdb/kvdb_service_impl.cpp | 676 +++--- .../service/kvdb/kvdb_service_impl.h | 33 +- .../service/kvdb/kvdb_service_stub.cpp | 45 +- .../service/kvdb/kvdb_service_stub.h | 12 +- .../service/kvdb/kvdb_watcher.cpp | 30 +- .../service/kvdb/kvdb_watcher.h | 7 +- .../service/kvdb/user_delegate.cpp | 8 +- .../service/matrix/include/device_matrix.h | 35 +- .../service/matrix/src/auto_sync_matrix.cpp | 48 +- .../service/matrix/src/device_matrix.cpp | 197 +- .../service/object/object_asset_loader.cpp | 42 +- .../service/object/object_asset_loader.h | 12 +- .../service/object/object_asset_machine.cpp | 4 +- .../service/object/object_callback_proxy.cpp | 8 +- .../service/object/object_callback_proxy.h | 4 +- .../service/object/object_data_listener.cpp | 21 +- .../service/object/object_data_listener.h | 14 +- .../service/object/object_manager.cpp | 403 ++-- .../service/object/object_manager.h | 54 +- .../service/object/object_service_impl.cpp | 19 +- .../service/object/object_service_impl.h | 3 +- .../service/object/object_snapshot.cpp | 5 +- .../permission/src/permit_delegate.cpp | 2 +- .../service/rdb/rdb_general_store.cpp | 124 +- .../service/rdb/rdb_general_store.h | 11 +- .../service/rdb/rdb_result_set_impl.cpp | 4 + .../service/rdb/rdb_result_set_stub.cpp | 10 - .../service/rdb/rdb_result_set_stub.h | 1 - .../service/rdb/rdb_service_impl.cpp | 24 +- .../service/rdb/rdb_service_impl.h | 6 +- .../service/test/BUILD.gn | 173 +- .../service/test/auto_sync_matrix_test.cpp | 23 + .../service/test/cache_cursor_test.cpp | 195 +- .../service/test/cloud_data_test.cpp | 421 +++- .../service/test/cloud_test.cpp | 33 +- .../test/data_share_profile_config_test.cpp | 1 + .../test/data_share_service_stub_test.cpp | 78 +- .../data_share_subscriber_managers_test.cpp | 1 - .../service/test/device_matrix_test.cpp | 101 +- .../service/test/fuzztest/BUILD.gn | 2 + .../fuzztest/cloudservicestub_fuzzer/BUILD.gn | 3 + .../customutdinstaller_fuzzer/BUILD.gn | 111 + .../customutdinstaller_fuzzer/corpus/init | 16 + .../customutdinstaller_fuzzer.cpp | 57 + .../customutdinstaller_fuzzer.h | 21 + .../customutdinstaller_fuzzer/project.xml | 25 + .../datashareservicestub_fuzzer/BUILD.gn | 5 + .../test/fuzztest/dumphelper_fuzzer/BUILD.gn | 87 + .../fuzztest/dumphelper_fuzzer/corpus/init | 16 + .../dumphelper_fuzzer/dumphelper_fuzzer.cpp | 57 + .../dumphelper_fuzzer/dumphelper_fuzzer.h | 21 + .../fuzztest/dumphelper_fuzzer/project.xml | 25 + .../fuzztest/kvdbservicestub_fuzzer/BUILD.gn | 1 + .../objectservicestub_fuzzer/BUILD.gn | 5 + .../fuzztest/rdbservicestub_fuzzer/BUILD.gn | 3 + .../service/test/kvdb_service_impl_test.cpp | 2 +- .../service/test/mock/BUILD.gn | 51 +- .../service/test/mock/checker_mock.cpp | 96 + .../service/test/mock/checker_mock.h | 49 + .../service/test/mock/cloud_server_mock.cpp | 9 +- .../service/test/mock/cloud_server_mock.h | 4 +- .../service/test/mock/cursor_mock.cpp | 3 +- .../service/test/mock/db_store_mock.cpp | 15 +- .../service/test/mock/db_store_mock.h | 5 + .../service/test/mock/general_store_mock.cpp | 139 +- .../service/test/mock/general_store_mock.h | 115 +- .../test/object_asset_machine_test.cpp | 83 +- .../service/test/rdb_asset_loader_test.cpp | 125 ++ .../service/test/rdb_cloud_test.cpp | 200 ++ .../service/test/rdb_cursor_test.cpp | 312 +++ .../service/test/rdb_general_store_test.cpp | 1018 +++++++++ .../service/test/rdb_query_test.cpp | 183 ++ .../service/test/rdb_result_set_impl_test.cpp | 93 + .../service/test/rdb_result_set_stub_test.cpp | 149 ++ .../service/test/udmf_run_time_store_test.cpp | 271 ++- .../test/water_version_manager_test.cpp | 236 +-- .../service/udmf/BUILD.gn | 8 +- .../permission/uri_permission_manager.cpp | 79 +- .../udmf/permission/uri_permission_manager.h | 21 +- .../udmf/preprocess/preprocess_utils.cpp | 23 + .../udmf/preprocess/preprocess_utils.h | 1 + .../service/udmf/store/runtime_store.cpp | 138 +- .../service/udmf/store/runtime_store.h | 11 +- .../service/udmf/store/store.h | 5 +- .../service/udmf/store/store_cache.cpp | 10 +- .../service/udmf/udmf_service_impl.cpp | 132 +- .../service/udmf/udmf_service_impl.h | 8 +- .../service/udmf/udmf_service_stub.cpp | 47 + .../service/udmf/udmf_service_stub.h | 8 +- .../service/udmf/utd/custom_utd_installer.cpp | 9 + .../waterversion/water_version_manager.cpp | 138 +- .../waterversion/water_version_manager.h | 26 +- ...application.DataShareExtensionAbility.d.ts | 1 + interface_sdk/api/@ohos.data.cloudData.d.ts | 77 +- interface_sdk/api/@ohos.data.commonType.d.ts | 69 +- interface_sdk/api/@ohos.data.dataShare.d.ts | 12 +- interface_sdk/api/@ohos.data.preferences.d.ts | 22 +- .../api/@ohos.data.relationalStore.d.ts | 222 +- .../api/@ohos.data.sendablePreferences.d.ets | 508 +++++ .../api/@ohos.data.unifiedDataChannel.d.ts | 45 +- .../api/@ohos.data.uniformTypeDescriptor.d.ts | 322 ++- kv_store/bundle.json | 4 +- kv_store/databaseutils/BUILD.gn | 2 + kv_store/databaseutils/src/acl.cpp | 6 +- .../cj/include/distributed_kv_store_ffi.h | 98 + .../cj/include/distributed_kv_store_impl.h | 245 +++ .../cj/include/distributed_kv_store_log.h | 36 + .../cj/include/distributed_kv_store_utils.h | 53 + .../cj/src/distributed_kv_store_ffi.cpp | 291 +++ .../cj/src/distributed_kv_store_impl.cpp | 568 +++++ .../cj/src/distributed_kv_store_utils.cpp | 33 + .../include/ikvdb_notifier.h | 3 +- .../src/distributed_kv_data_manager.cpp | 4 +- .../src/ikvstore_observer.cpp | 5 - .../src/kvdb_notifier_client.cpp | 69 +- .../src/kvdb_notifier_client.h | 11 +- .../src/kvdb_notifier_stub.cpp | 22 +- .../src/kvdb_notifier_stub.h | 1 + .../distributeddatafwk/test/BUILD.gn | 7 +- .../distributed_kv_data_manager_test.cpp | 4 + .../single_kvstore_async_get_test.cpp | 9 +- .../unittest/single_kvstore_client_test.cpp | 35 +- .../distributeddata_kvdb_ipc_interface_code.h | 3 + .../kvdb/include/kv_types_util.h | 30 + .../innerkitsimpl/kvdb/include/kvdb_service.h | 11 +- .../kvdb/include/kvdb_service_client.h | 10 +- .../kvdb/include/observer_bridge.h | 8 +- .../kvdb/include/single_store_impl.h | 11 +- .../innerkitsimpl/kvdb/include/store_util.h | 1 + .../kvdb/src/auto_sync_timer.cpp | 122 -- .../innerkitsimpl/kvdb/src/backup_manager.cpp | 2 +- .../innerkitsimpl/kvdb/src/kv_types_util.cpp | 59 +- .../kvdb/src/kvdb_service_client.cpp | 37 +- .../kvdb/src/observer_bridge.cpp | 22 +- .../src/process_system_api_adapter_impl.cpp | 2 +- .../kvdb/src/security_manager.cpp | 4 + .../kvdb/src/single_store_impl.cpp | 139 +- .../innerkitsimpl/kvdb/src/store_factory.cpp | 6 +- .../innerkitsimpl/kvdb/src/store_manager.cpp | 4 +- .../innerkitsimpl/kvdb/src/store_util.cpp | 40 +- .../innerkitsimpl/kvdb/src/system_api.cpp | 2 +- .../innerkitsimpl/kvdb/test/BUILD.gn | 10 +- .../kvdb/test/auto_sync_timer_test.cpp | 412 ---- .../kvdb/test/data_change_notifier_test.cpp | 4 + .../kvdb/test/single_store_impl_test.cpp | 45 +- .../kvdb/test/store_util_test.cpp | 71 + .../distributeddata/include/js_util.h | 2 +- .../src/js_kv_store_resultset.cpp | 21 +- .../distributeddata/src/js_schema.cpp | 2 +- .../distributeddata/src/js_util.cpp | 7 +- .../distributedkvstore/include/js_util.h | 2 +- .../src/js_kv_store_resultset.cpp | 21 +- .../distributedkvstore/src/js_schema.cpp | 2 +- .../distributedkvstore/src/js_util.cpp | 7 +- .../frameworks/libs/distributeddb/BUILD.gn | 23 +- .../common/include/auto_launch.h | 4 + .../include/cloud/asset_operation_utils.h | 2 +- .../common/include/cloud/cloud_db_constant.h | 7 +- .../common/include/cloud/cloud_db_types.h | 2 +- .../common/include/db_base64_utils.h | 29 + .../distributeddb/common/include/db_common.h | 17 +- .../common/include/db_constant.h | 4 + .../common/include/db_dfx_adapter.h | 61 +- .../common/include/param_check_utils.h | 4 +- .../common/include/query_utils.h | 28 + .../common/include/runtime_context.h | 2 + .../distributeddb/common/src/auto_launch.cpp | 69 +- .../src/cloud/asset_operation_utils.cpp | 36 +- .../common/src/db_base64_utils.cpp | 181 ++ .../distributeddb/common/src/db_common.cpp | 47 +- .../distributeddb/common/src/db_constant.cpp | 4 +- .../common/src/db_dfx_adapter.cpp | 32 +- .../common/src/evloop/src/event_loop_impl.cpp | 2 +- .../common/src/param_check_utils.cpp | 24 +- .../common/src/platform_specific.cpp | 4 +- .../common/src/query_expression.cpp | 2 +- .../distributeddb/common/src/query_utils.cpp | 59 + .../relational/relational_result_set_impl.cpp | 4 + .../common/src/relational/table_info.cpp | 2 + .../common/src/runtime_context_impl.cpp | 22 +- .../common/src/runtime_context_impl.h | 2 + .../common/src/schema_object.cpp | 13 +- .../distributeddb/common/src/schema_utils.cpp | 12 +- .../common/src/time_tick_monitor.cpp | 11 + .../common/src/time_tick_monitor.h | 5 + .../communicator/include/frame_retainer.h | 3 + .../src/communicator_aggregator.cpp | 4 +- .../communicator/src/communicator_linker.cpp | 6 +- .../communicator/src/db_status_adapter.cpp | 17 +- .../communicator/src/frame_combiner.cpp | 2 +- .../communicator/src/frame_retainer.cpp | 37 +- .../communicator/src/network_adapter.cpp | 53 +- .../libs/distributeddb/distributeddb.gni | 2 + .../libs/distributeddb/gaussdb_rd/BUILD.gn | 11 +- .../src/common/include/rd_db_constant.h | 2 +- .../src/interface/src/collection.cpp | 2 +- .../src/interface/src/document_key.cpp | 1 + .../src/interface/src/projection_tree.cpp | 1 + .../src/interface/src/result_set.cpp | 2 +- .../src/sqlite_store_executor_impl.cpp | 4 +- .../gaussdb_rd/test/unittest/BUILD.gn | 10 + .../include/cloud/cloud_store_types.h | 15 +- .../interfaces/include/intercepted_data.h | 1 + .../include/kv_store_delegate_manager.h | 3 + .../interfaces/include/kv_store_nb_delegate.h | 11 + .../relational/relational_store_delegate.h | 3 + .../relational/relational_store_manager.h | 3 + .../interfaces/include/store_types.h | 16 +- .../interfaces/src/intercepted_data_impl.cpp | 2 +- .../src/kv_store_delegate_manager.cpp | 36 +- .../src/kv_store_nb_delegate_impl.cpp | 89 +- .../src/kv_store_nb_delegate_impl.h | 9 +- .../src/kv_store_result_set_impl.cpp | 2 - .../relational_store_delegate_impl.cpp | 21 + .../relational_store_delegate_impl.h | 2 + .../relational/relational_store_manager.cpp | 15 +- .../relational_store_sqlite_ext.cpp | 43 +- .../relational/relational_sync_able_storage.h | 21 +- .../include/cloud/cloud_storage_utils.h | 6 +- .../storage/include/db_properties.h | 12 +- .../include/icloud_sync_storage_interface.h | 10 +- .../storage/include/ikvdb_connection.h | 7 + .../include/relational_store_connection.h | 2 + .../storage/include/storage_proxy.h | 6 +- .../storage/include/sync_generic_interface.h | 2 +- .../storage/src/cloud/cloud_storage_utils.cpp | 60 +- .../storage/src/cloud/schema_mgr.cpp | 1 + .../storage/src/db_properties.cpp | 20 +- .../rd_single_ver_natural_store.cpp | 11 +- .../gaussdb_rd/rd_single_ver_natural_store.h | 4 +- .../storage/src/gaussdb_rd/rd_utils.cpp | 2 +- .../src/kv/generic_kvdb_connection.cpp | 21 + .../storage/src/kv/generic_kvdb_connection.h | 8 + .../storage/src/kv/kvdb_manager.cpp | 7 + .../storage/src/kv/sync_able_kvdb.cpp | 60 +- .../storage/src/kv/sync_able_kvdb.h | 8 +- .../src/kv/sync_able_kvdb_connection.cpp | 12 +- .../src/kv/sync_able_kvdb_connection.h | 2 + .../src/multiver/multi_ver_natural_store.cpp | 8 +- .../src/multiver/multi_ver_natural_store.h | 4 +- .../storage/src/operation/database_oper.cpp | 2 +- .../operation/single_ver_database_oper.cpp | 2 +- .../relational/relational_store_instance.cpp | 7 + .../relational_sync_able_storage.cpp | 184 +- .../storage/src/single_ver_natural_store.h | 1 - .../cloud_sync_log_table_manager.cpp | 2 +- .../simple_tracker_log_table_manager.cpp | 2 +- .../sqlite_relational_database_upgrader.cpp | 13 +- .../relational/sqlite_relational_store.cpp | 84 +- .../relational/sqlite_relational_store.h | 2 + .../sqlite_relational_store_connection.cpp | 10 + .../sqlite_relational_store_connection.h | 2 + .../relational/sqlite_relational_utils.cpp | 11 +- ...qlite_single_relational_storage_engine.cpp | 2 + ...single_ver_relational_storage_executor.cpp | 43 +- ...e_single_ver_relational_storage_executor.h | 32 +- ...ver_relational_storage_executor_extend.cpp | 18 +- ...ver_relational_storage_extend_executor.cpp | 252 ++- .../sqlite/sqlite_cloud_kv_executor_utils.cpp | 141 +- .../sqlite/sqlite_cloud_kv_executor_utils.h | 15 +- .../src/sqlite/sqlite_cloud_kv_store.cpp | 115 +- .../src/sqlite/sqlite_cloud_kv_store.h | 11 + .../src/sqlite/sqlite_log_table_manager.cpp | 7 +- .../sqlite/sqlite_multi_ver_transaction.cpp | 38 +- .../src/sqlite/sqlite_query_helper.cpp | 24 +- .../storage/src/sqlite/sqlite_query_helper.h | 4 +- .../sqlite_single_ver_natural_store.cpp | 14 +- .../sqlite/sqlite_single_ver_natural_store.h | 14 +- ...te_single_ver_natural_store_connection.cpp | 82 +- ...lite_single_ver_natural_store_connection.h | 7 + ...sqlite_single_ver_natural_store_extend.cpp | 32 +- .../sqlite_single_ver_storage_engine.cpp | 18 +- .../sqlite_single_ver_storage_executor.h | 5 +- ...ite_single_ver_storage_executor_extend.cpp | 59 +- .../sqlite_single_ver_storage_executor_sql.h | 26 +- .../storage/src/sqlite/sqlite_utils.cpp | 27 +- .../storage/src/sqlite/sqlite_utils.h | 2 + .../storage/src/storage_proxy.cpp | 42 +- .../syncer/src/cloud/cloud_db_proxy.cpp | 71 +- .../syncer/src/cloud/cloud_db_proxy.h | 10 +- .../src/cloud/cloud_force_pull_strategy.cpp | 3 + .../syncer/src/cloud/cloud_merge_strategy.cpp | 5 +- .../src/cloud/cloud_sync_state_machine.cpp | 8 +- .../src/cloud/cloud_sync_state_machine.h | 2 +- .../syncer/src/cloud/cloud_sync_strategy.cpp | 2 +- .../src/cloud/cloud_sync_tag_assets.cpp | 171 +- .../syncer/src/cloud/cloud_sync_tag_assets.h | 2 + .../syncer/src/cloud/cloud_sync_utils.cpp | 9 +- .../syncer/src/cloud/cloud_syncer.cpp | 385 ++-- .../syncer/src/cloud/cloud_syncer.h | 64 +- .../syncer/src/cloud/cloud_syncer_extend.cpp | 396 ++-- .../syncer/src/cloud/icloud_syncer.h | 1 + .../syncer/src/cloud/process_notifier.cpp | 59 +- .../syncer/src/cloud/process_notifier.h | 9 +- .../syncer/src/device/ability_sync.cpp | 6 +- .../syncer/src/device/ability_sync.h | 1 - .../syncer/src/device/generic_syncer.cpp | 8 +- .../syncer/src/device/meta_data.cpp | 5 +- .../multiver/multi_ver_sync_state_machine.cpp | 9 +- .../src/device/multiver/value_slice_sync.cpp | 2 +- .../syncer/src/device/remote_executor.cpp | 36 +- .../syncer/src/device/remote_executor.h | 2 +- .../src/device/remote_executor_packet.cpp | 2 +- .../singlever/single_ver_data_packet.cpp | 12 + .../device/singlever/single_ver_data_packet.h | 4 + .../device/singlever/single_ver_data_sync.cpp | 82 +- .../device/singlever/single_ver_data_sync.h | 10 +- .../singlever/single_ver_data_sync_utils.cpp | 87 +- .../singlever/single_ver_data_sync_utils.h | 10 +- ...ingle_ver_relational_sync_task_context.cpp | 7 +- .../single_ver_relational_sync_task_context.h | 2 +- .../single_ver_serialize_manager.cpp | 16 +- .../single_ver_sync_state_machine.cpp | 3 +- .../singlever/single_ver_sync_state_machine.h | 2 +- .../single_ver_sync_task_context.cpp | 3 + .../syncer/src/device/sync_engine.cpp | 2 +- .../syncer/src/device/sync_task_context.cpp | 2 +- .../syncer/src/device/time_sync.cpp | 2 +- .../distributeddb/syncer/src/sync_types.h | 3 +- .../libs/distributeddb/test/BUILD.gn | 50 + .../cloudsync_fuzzer/cloudsync_fuzzer.cpp | 125 +- .../kvstoreresultset_fuzzer.h | 2 +- .../test/fuzztest/query_fuzzer/query_fuzzer.h | 8 +- .../storage_fuzzer/storage_fuzzer.cpp | 2 +- .../src/distributeddb_nb_batch_crud_test.cpp | 6 +- ...distributeddb_nb_local_batch_crud_test.cpp | 17 +- .../distributeddb_data_compression_test.cpp | 4 +- .../distributeddb_data_generate_unit_test.cpp | 2 +- .../distributeddb_data_generate_unit_test.h | 3 + .../distributeddb_json_precheck_unit_test.cpp | 6 +- .../common/common/evloop_timer_unit_test.cpp | 4 +- .../unittest/common/common/system_time.cpp | 2 +- .../distributeddb_communicator_common.h | 2 +- .../distributeddb_communicator_test.cpp | 2 + ...uteddb_cloud_interfaces_reference_test.cpp | 2 +- ...b_cloud_interfaces_relational_ext_test.cpp | 130 +- ...ces_relational_remove_device_data_test.cpp | 56 +- ...cloud_interfaces_set_cloud_schema_test.cpp | 55 + ...buteddb_interfaces_data_operation_test.cpp | 2 +- ...stributeddb_interfaces_data_value_test.cpp | 2 +- ...nterfaces_nb_delegate_local_batch_test.cpp | 325 --- ...tributeddb_interfaces_nb_delegate_test.cpp | 371 +--- ...uteddb_interfaces_relational_sync_test.cpp | 19 + ...stributeddb_interfaces_relational_test.cpp | 4 +- ...terfaces_relational_tracker_table_test.cpp | 5 +- ...teddb_interfaces_space_management_test.cpp | 2 +- ...teddb_cloud_assets_operation_sync_test.cpp | 49 +- .../distributeddb_cloud_check_sync_test.cpp | 239 ++- ..._cloud_interfaces_relational_sync_test.cpp | 7 +- .../distributeddb_cloud_task_merge_test.cpp | 150 ++ .../distributeddb_cloud_schema_mgr_test.cpp | 16 + ...distributeddb_query_object_helper_test.cpp | 2 +- ...relational_cloud_syncable_storage_test.cpp | 8 +- ...ributeddb_relational_remote_query_test.cpp | 4 +- ...rage_single_ver_natural_store_testcase.cpp | 14 +- .../common/syncer/cloud/cloud_syncer_test.h | 29 +- ...distributeddb_cloud_asset_compare_test.cpp | 147 +- .../distributeddb_cloud_db_proxy_test.cpp | 82 +- .../cloud/distributeddb_cloud_kv_test.cpp | 1038 ++++++++- ...eddb_cloud_syncer_download_assets_test.cpp | 144 +- ...stributeddb_cloud_syncer_download_test.cpp | 19 +- .../distributeddb_cloud_syncer_lock_test.cpp | 121 +- .../common/syncer/cloud/mock_asset_loader.h | 2 +- .../mock_icloud_sync_storage_interface.h | 1 + .../common/syncer/cloud/virtual_cloud_db.cpp | 34 +- .../common/syncer/cloud/virtual_cloud_db.h | 7 +- .../syncer/cloud/virtual_cloud_syncer.cpp | 10 + .../syncer/cloud/virtual_cloud_syncer.h | 2 + .../syncer/distributeddb_meta_data_test.cpp | 19 + ...buteddb_single_ver_multi_sub_user_test.cpp | 765 +++++++ ...stributeddb_single_ver_multi_user_test.cpp | 1 + ...teddb_single_ver_p2p_complex_sync_test.cpp | 103 + ...buteddb_single_ver_p2p_query_sync_test.cpp | 6 +- ...uteddb_single_ver_p2p_simple_sync_test.cpp | 56 +- ...ddb_single_ver_p2p_subscribe_sync_test.cpp | 53 +- ...buteddb_single_ver_p2p_sync_check_test.cpp | 123 +- ...stributeddb_syncer_device_manager_test.cpp | 3 +- .../common/syncer/kv_virtual_device.cpp | 6 + .../common/syncer/kv_virtual_device.h | 2 + .../common/syncer/virtual_communicator.cpp | 1 + .../virtual_communicator_aggregator.cpp | 28 +- .../syncer/virtual_communicator_aggregator.h | 14 +- ...virtual_relational_ver_sync_db_interface.h | 2 +- .../virtual_single_ver_sync_db_Interface.cpp | 28 +- .../virtual_single_ver_sync_db_Interface.h | 11 +- kv_store/interfaces/cj/BUILD.gn | 64 + .../innerkits/distributeddata/BUILD.gn | 8 +- .../distributeddata/include/end_point.h | 4 +- .../distributeddata/include/single_kvstore.h | 23 + .../innerkits/distributeddata/include/types.h | 37 + .../innerkits/distributeddatamgr/BUILD.gn | 2 + .../jskits/distributeddata/BUILD.gn | 10 +- .../jskits/distributedkvstore/BUILD.gn | 10 +- kv_store/kv_store.gni | 2 - .../cj/distributed_kv_store_mock.cpp | 72 + .../kvdb/include/single_store_impl.h | 1 + .../kvdb/src/single_store_impl.cpp | 40 +- .../distributeddata/src/js_util.cpp | 7 +- .../distributedkvdatamanager_fuzzer.cpp | 53 + .../singlekvstore_fuzzer.cpp | 33 + .../unittest/distributeddata/SchemaJsTest.js | 32 +- mock/CMakeLists.txt | 1 + mock/include/CMakeLists.txt | 13 +- .../include/uri_permission_manager_client.h | 2 +- .../include/common_event_support.h | 1420 +++++++------ .../include/distributed_event_listener.h | 11 +- .../include/distributed_sched_types.h | 60 + .../distributed_event/include/dms_client.h | 7 +- .../distributed_event/include/dms_handler.h | 2 + .../softbus_client/include/lnn/data_level.h | 2 +- .../include/asset/asset_adapter_sa_client.h | 52 + .../asset/asset_callback_interface_code.h | 31 + .../include/asset/asset_obj.h | 50 + .../include/asset/asset_recv_callback_stub.h | 39 + .../include/asset/asset_send_callback_stub.h | 40 + .../include/asset/i_asset_recv_callback.h | 46 + .../include/asset/i_asset_send_callback.h | 40 + .../distributed_file_daemon_manager_impl.h | 54 +- .../include/device/device_info.h | 53 + .../include/device/device_manager_agent.h | 141 ++ .../include/ipc/asset_callback_manager.h | 62 + .../include/ipc/asset_recv_callback_proxy.h | 45 + .../include/ipc/asset_send_callback_proxy.h | 40 + .../include/ipc/connection_detector.h | 55 + .../include/ipc/daemon.h | 129 ++ .../include/ipc/daemon_event.h | 42 + .../include/ipc/daemon_eventhandler.h | 40 + .../include/ipc/daemon_execute.h | 54 + .../include/ipc/daemon_stub.h | 56 + ...stributed_file_daemon_ipc_interface_code.h | 38 + .../ipc/distributed_file_daemon_manager.h | 57 + .../ipc/file_dfs_listener_interface_code.h | 27 + .../include/ipc/file_dfs_listener_proxy.h | 41 + .../include/ipc/file_trans_listener_proxy.h | 43 + .../include/ipc/hmdfs_info.h | 34 + .../include/ipc/i_daemon.h | 64 + .../include/ipc/i_file_dfs_listener.h | 40 + .../include/ipc/trans_mananger.h | 45 + .../include/mountpoint/mount_manager.h | 42 + .../include/mountpoint/mount_point.h | 58 + .../include/multiuser/os_account_observer.h | 59 +- .../include/network/base_session.h | 41 + .../include/network/devsl_dispatcher.h | 48 + .../include/network/kernel_talker.h | 104 + .../include/network/network_agent_template.h | 101 + .../include/network/session_pool.h | 58 + .../include/network/softbus/softbus_agent.h | 58 + .../softbus/softbus_asset_recv_listener.h | 56 + .../softbus/softbus_asset_send_listener.h | 40 + .../softbus/softbus_file_receive_listener.h | 46 + .../softbus/softbus_file_send_listener.h | 42 + .../include/network/softbus/softbus_handler.h | 60 + .../network/softbus/softbus_handler_asset.h | 100 + .../include/network/softbus/softbus_session.h | 52 + .../softbus/softbus_session_dispatcher.h | 50 + .../softbus/softbus_session_listener.h | 41 + .../network/softbus/softbus_session_name.h | 40 + .../network/softbus/softbus_session_pool.h | 49 + .../libhisysevent/include/hisysevent_c.h | 92 +- .../memmgrclient/include/bundle_priority.h | 37 + .../include/bundle_priority_list.h | 59 +- .../memmgr/memmgrclient/include/i_mem_mgr.h | 54 +- .../memmgrclient/include/mem_mgr_client.h | 45 +- .../include/mem_mgr_process_state_info.h | 78 + .../memmgrclient/include/mem_mgr_proxy.h | 8 +- .../include/mem_mgr_window_info.h | 71 + .../memmgrclient/include/single_instance.h | 44 + .../libaccountkits/include/account_info.h | 4 + .../include/ohos_account_kits.h | 186 +- mock/src/mock_access_token.cpp | 41 +- mock/src/mock_account.cpp | 44 +- mock/src/mock_dms.cpp | 5 + mock/src/mock_filemanagement.cpp | 100 +- mock/src/mock_hisysevent.cpp | 20 + mock/src/mock_mem_mgr.cpp | 159 ++ mock/src/mock_notification.cpp | 2 + mock/src/mock_uri_permission_manager.cpp | 11 +- mock/src/mock_xcollie.cpp | 31 + preferences/README_zh.md | 4 +- preferences/bundle.json | 7 +- preferences/frameworks/cj/BUILD.gn | 52 + .../frameworks/cj/src/preferences_ffi.cpp | 157 ++ .../frameworks/cj/src/preferences_ffi.h | 63 + .../frameworks/cj/src/preferences_impl.cpp | 496 +++++ .../frameworks/cj/src/preferences_impl.h | 91 + .../frameworks/cj/src/preferences_interface.h | 74 + .../frameworks/cj/src/preferences_log.h | 35 + .../frameworks/cj/src/preferences_mock.cpp | 32 + .../frameworks/cj/src/preferences_utils.cpp | 33 + .../frameworks/cj/src/preferences_utils.h | 32 + .../frameworks/common/include/log_print.h | 7 + .../frameworks/js/napi/common/BUILD.gn | 70 + .../include/{js_utils.h => js_common_utils.h} | 6 +- .../js/napi/common/include/js_observer.h | 7 +- .../js/napi/common/include/js_proxy.h | 62 + .../napi/common/include/js_sendable_utils.h | 171 ++ .../js/napi/common/include/napi_async_call.h | 3 +- .../common/include/napi_preferences_error.h | 27 +- .../include/napi_preferences_observer.h | 2 +- .../js/napi/common/include/uv_queue.h | 5 +- .../frameworks/js/napi/common/libcommon.map | 42 +- .../mock/cross_platform/src/js_ability.cpp | 2 +- .../js/napi/common/mock/src/js_ability.cpp | 2 +- .../src/{js_utils.cpp => js_common_utils.cpp} | 18 +- .../js/napi/common/src/js_observer.cpp | 33 +- .../js/napi/common/src/js_sendable_utils.cpp | 152 ++ .../js/napi/common/src/napi_async_call.cpp | 15 +- .../common/src/napi_preferences_error.cpp | 43 + .../common/src/napi_preferences_observer.cpp | 26 +- .../js/napi/common/src/uv_queue.cpp | 6 +- .../frameworks/js/napi/preferences/BUILD.gn | 61 +- .../preferences/include/napi_preferences.h | 2 +- .../napi/preferences/src/napi_preferences.cpp | 16 +- .../src/napi_preferences_helper.cpp | 2 +- .../js/napi/sendable_preferences/BUILD.gn | 71 + .../include/napi_preferences.h | 93 + .../include/napi_preferences_helper.h | 25 + .../sendable_preferences/src/entry_point.cpp | 51 + .../src/napi_preferences.cpp | 607 ++++++ .../src/napi_preferences_helper.cpp | 155 ++ .../frameworks/js/napi/storage/BUILD.gn | 21 +- .../js/napi/storage/src/napi_storage.cpp | 12 +- .../napi/storage/src/napi_storage_helper.cpp | 2 +- .../js/napi/system_storage/BUILD.gn | 17 +- .../src/napi_system_storage.cpp | 2 +- .../native/include/preferences_base.h | 5 + .../native/include/preferences_enhance_impl.h | 8 +- .../native/include/preferences_impl.h | 3 - .../native/include/preferences_utils.h | 4 +- .../native/include/preferences_value_parcel.h | 25 +- .../mock/c_utils/utils/base/src/refbase.cpp | 12 +- .../platform/include/preferences_db_adapter.h | 10 +- .../platform/src/preferences_db_adapter.cpp | 225 +- .../native/src/preferences_base.cpp | 10 +- .../native/src/preferences_enhance_impl.cpp | 103 +- .../native/src/preferences_helper.cpp | 93 +- .../native/src/preferences_impl.cpp | 17 +- .../native/src/preferences_utils.cpp | 8 +- .../native/src/preferences_value.cpp | 2 +- .../native/src/preferences_value_parcel.cpp | 48 +- .../native/src/preferences_xml_utils.cpp | 2 +- preferences/interfaces/inner_api/BUILD.gn | 18 +- .../inner_api/include/preferences.h | 41 +- .../inner_api/include/preferences_errno.h | 15 +- .../inner_api/include/preferences_helper.h | 3 +- .../inner_api/include/preferences_observer.h | 2 +- .../inner_api/include/preferences_value.h | 4 +- preferences/preferences.gni | 2 + .../src/PreferencesCallBackJsunit.test.js | 12 +- .../src/PreferencesPromiseJsunit.test.js | 19 +- .../src/PreferencesSyncJsunit.test.js | 2 +- .../src/PreferencesTaskpoolJsunit.test.js | 182 ++ .../src/V9_PreferencesCallBackJsunit.test.js | 40 +- .../src/V9_PreferencesPromiseJsunit.test.js | 45 +- .../storage/src/StorageCallBackJsunit.test.js | 18 +- .../storage/src/StorageSyncJsunit.test.js | 30 +- preferences/test/native/BUILD.gn | 6 + .../test/native/unittest/preferences_test.cpp | 41 + relational_store/CMakeLists.txt | 2 + relational_store/bundle.json | 7 +- relational_store/frameworks/cj/BUILD.gn | 69 + .../frameworks/cj/include/native_log.h | 41 + .../cj/include/relational_store_ffi.h | 232 +++ ...relational_store_impl_rdbpredicatesproxy.h | 112 + .../include/relational_store_impl_rdbstore.h | 124 ++ .../relational_store_impl_resultsetproxy.h | 99 + .../cj/include/relational_store_utils.h | 98 + .../cj/mock/relational_store_mock.cpp | 103 + .../cj/src/relational_store_ffi.cpp | 904 ++++++++ ...lational_store_impl_rdbpredicatesproxy.cpp | 245 +++ .../cj/src/relational_store_impl_rdbstore.cpp | 557 +++++ .../relational_store_impl_resultsetproxy.cpp | 315 +++ .../cj/src/relational_store_utils.cpp | 211 ++ .../frameworks/js/napi/cloud_data/BUILD.gn | 2 + .../cloud_extension/cloud_extension_stub.js | 43 + .../js/napi/common/include/js_uv_queue.h | 1 + .../napi/common/mock/include/event_handler.h | 37 + .../js/napi/common/src/js_uv_queue.cpp | 22 +- .../frameworks/js/napi/dataability/BUILD.gn | 2 + .../frameworks/js/napi/rdb/BUILD.gn | 5 + .../js/napi/rdb/src/napi_rdb_store.cpp | 2 +- .../js/napi/rdb/src/napi_result_set.cpp | 6 +- .../js/napi/relationalstore/BUILD.gn | 5 + .../relationalstore/include/napi_async_call.h | 4 +- .../include/napi_rdb_js_utils.h | 5 +- .../relationalstore/include/napi_rdb_store.h | 29 +- .../include/napi_rdb_store_observer.h | 16 +- .../mock/include/napi_rdb_store.h | 3 +- .../mock/include/napi_result_set.h | 3 + .../relationalstore/src/napi_async_call.cpp | 5 +- .../src/napi_rdb_const_properties.cpp | 1 + .../relationalstore/src/napi_rdb_error.cpp | 6 +- .../relationalstore/src/napi_rdb_js_utils.cpp | 22 + .../relationalstore/src/napi_rdb_store.cpp | 253 ++- .../src/napi_rdb_store_helper.cpp | 4 +- .../src/napi_rdb_store_observer.cpp | 98 +- .../relationalstore/src/napi_result_set.cpp | 39 +- .../native/appdatafwk/src/shared_block.cpp | 1 + .../native/dfx/include/rdb_radar_reporter.h | 80 + .../native/dfx/src/rdb_radar_reporter.cpp | 93 + .../native/rdb/include/connection.h | 9 + .../native/rdb/include/grd_api_manager.h | 10 + .../frameworks/native/rdb/include/grd_error.h | 1 + .../native/rdb/include/grd_type_export.h | 5 + .../native/rdb/include/rd_connection.h | 61 +- .../native/rdb/include/rd_result_set.h | 84 - .../native/rdb/include/rd_statement.h | 57 +- .../frameworks/native/rdb/include/rd_utils.h | 9 +- .../native/rdb/include/rdb_connection.h | 92 - .../native/rdb/include/rdb_connection_pool.h | 83 - .../native/rdb/include/rdb_platform.h | 13 +- .../native/rdb/include/rdb_security_manager.h | 2 +- .../native/rdb/include/rdb_sql_statistic.h | 57 + .../native/rdb/include/rdb_store_impl.h | 23 +- .../frameworks/native/rdb/include/rdb_trace.h | 4 + .../native/rdb/include/sqlite_connection.h | 16 +- .../rdb/include/sqlite_connection_pool.h | 7 +- .../native/rdb/include/sqlite_errno.h | 2 + .../native/rdb/include/sqlite_global_config.h | 2 +- .../rdb/include/sqlite_shared_result_set.h | 10 +- .../native/rdb/include/sqlite_sql_builder.h | 4 + .../native/rdb/include/sqlite_statement.h | 1 + .../frameworks/native/rdb/include/statement.h | 3 +- .../native/rdb/include/step_result_set.h | 14 +- .../native/rdb/include/string_utils.h | 2 + .../native/rdb/include/vdb_store_impl.h | 130 -- .../native/rdb/mock/include/connection.h | 10 + .../native/rdb/mock/include/hisysevent.h | 40 + .../native/rdb/mock/include/rdb_store_impl.h | 23 +- .../rdb/mock/include/sqlite_connection.h | 16 +- .../rdb/mock/include/sqlite_connection_pool.h | 6 +- .../native/rdb/mock/include/step_result_set.h | 14 +- .../native/rdb/mock/include/vdb_store_impl.h | 253 --- .../rdb/mock/src/rdb_radar_reporter.cpp | 53 + .../native/rdb/src/abs_rdb_predicates.cpp | 1 - .../native/rdb/src/abs_result_set.cpp | 47 +- .../native/rdb/src/abs_shared_result_set.cpp | 60 +- .../native/rdb/src/cache_result_set.cpp | 2 +- .../frameworks/native/rdb/src/connection.cpp | 58 + .../native/rdb/src/grd_api_manager.cpp | 5 + .../native/rdb/src/rd_connection.cpp | 231 ++- .../native/rdb/src/rd_result_set.cpp | 377 ---- .../native/rdb/src/rd_statement.cpp | 438 ++-- .../frameworks/native/rdb/src/rd_utils.cpp | 123 +- .../native/rdb/src/rdb_connection.cpp | 184 -- .../native/rdb/src/rdb_connection_pool.cpp | 262 --- .../frameworks/native/rdb/src/rdb_helper.cpp | 3 + .../native/rdb/src/rdb_manager_impl.cpp | 13 +- .../native/rdb/src/rdb_security_manager.cpp | 18 +- .../native/rdb/src/rdb_service_proxy.cpp | 3 +- .../native/rdb/src/rdb_sql_statistic.cpp | 139 ++ .../native/rdb/src/rdb_sql_utils.cpp | 12 + .../native/rdb/src/rdb_statement.cpp | 127 -- .../native/rdb/src/rdb_store_config.cpp | 58 + .../native/rdb/src/rdb_store_impl.cpp | 516 +++-- .../native/rdb/src/rdb_store_manager.cpp | 18 +- .../native/rdb/src/result_set_proxy.cpp | 23 +- .../frameworks/native/rdb/src/share_block.cpp | 21 +- .../native/rdb/src/sqlite_connection.cpp | 271 +-- .../native/rdb/src/sqlite_connection_pool.cpp | 90 +- .../native/rdb/src/sqlite_global_config.cpp | 12 +- .../rdb/src/sqlite_shared_result_set.cpp | 159 +- .../native/rdb/src/sqlite_sql_builder.cpp | 59 +- .../native/rdb/src/sqlite_statement.cpp | 102 +- .../native/rdb/src/sqlite_utils.cpp | 11 +- .../native/rdb/src/step_result_set.cpp | 189 +- .../native/rdb/src/string_utils.cpp | 10 + .../native/rdb/src/value_object.cpp | 2 +- .../native/rdb/src/vdb_store_impl.cpp | 427 ---- .../interfaces/inner_api/appdatafwk/BUILD.gn | 4 + .../interfaces/inner_api/cloud_data/BUILD.gn | 2 + .../cloud_data/include/cloud_service.h | 13 +- .../interfaces/inner_api/dataability/BUILD.gn | 6 +- .../interfaces/inner_api/rdb/BUILD.gn | 76 +- .../inner_api/rdb/include/abs_result_set.h | 4 +- .../rdb/include/abs_shared_result_set.h | 1 + .../inner_api/rdb/include/rdb_common.h | 1 + .../inner_api/rdb/include/rdb_errno.h | 16 +- .../inner_api/rdb/include/rdb_helper.h | 3 +- .../inner_api/rdb/include/rdb_store.h | 5 + .../inner_api/rdb/include/rdb_store_config.h | 22 +- .../inner_api/rdb/include/rdb_types.h | 14 + .../rdb/mock/include/abs_result_set.h | 3 + .../inner_api/rdb/mock/include/rdb_common.h | 1 + .../inner_api/rdb/mock/include/rdb_store.h | 2 + .../rdb/mock/include/rdb_store_config.h | 11 +- .../rdb_data_ability_adapter/BUILD.gn | 2 + .../inner_api/rdb_data_share_adapter/BUILD.gn | 2 + .../interfaces/ndk/include/data_asset.h | 38 +- .../interfaces/ndk/include/oh_values_bucket.h | 4 + .../interfaces/ndk/include/relational_store.h | 72 +- relational_store/interfaces/ndk/src/BUILD.gn | 3 + .../ndk/src/convertor_error_code.cpp | 95 + .../interfaces/ndk/src/convertor_error_code.h | 27 + .../interfaces/ndk/src/relational_cursor.cpp | 37 +- .../interfaces/ndk/src/relational_store.cpp | 166 +- .../ndk/src/relational_store_impl.h | 5 +- .../rdbmock/frameworks/native/rdb/file_ex.h | 33 + .../rdbmock/frameworks/native/rdb/hks_api.h | 96 + .../rdbmock/frameworks/native/rdb/hks_param.h | 74 + .../rdbmock/frameworks/native/rdb/hks_type.h | 103 + .../frameworks/native/rdb/lru_bucket.h | 226 ++ .../native/rdb/relational_store_client.h | 5 + .../unittest/src/RdbstoreInsertJsunit.test.js | 33 + .../src/RdbStoreCorruptJsunit.test.js | 4 +- .../src/RdbStoreDistributedJsunit.test.js | 8 +- .../unittest/src/RdbStoreQueryByStep.test.js | 79 + .../src/RdbStoreReadOnlyJsunit.test.js | 302 +++ .../src/RdbStoreResultSetSyncJsunit.test.js | 4 +- .../src/RdbStoreStatisticsJsunit.test.js | 581 ++++++ .../src/RdbstoreEncryptionJsunit.test.js | 2 +- .../unittest/src/RdbstoreInsertJsunit.test.js | 37 + .../src/RdbstoreInsertSyncJsUnit.test.js | 37 + .../src/RdbstoreLockRowJsunit.test.js | 8 +- .../src/RdbstorePredicatesJsunit.test.js | 218 +- .../src/RdbstoreStoreExcuteSqlJsunit.test.js | 51 + .../src/RdbstoreStoreExcuteSyncJsunit.test.js | 4 +- .../test/native/appdatafwk/BUILD.gn | 56 + .../appdatafwk/unittest/serializable_test.cpp | 175 ++ .../test/native/clouddata/BUILD.gn | 75 + .../clouddata/unittest/cloud_data_test.cpp | 253 +++ relational_store/test/native/rdb/BUILD.gn | 7 + .../native/rdb/unittest/rdb_delete_test.cpp | 4 +- .../rdb/unittest/rdb_predicates_test.cpp | 80 +- .../rdb/unittest/rdb_read_only_test.cpp | 506 +++++ .../rdb_sqlite_shared_result_set_test.cpp | 55 +- .../rdb/unittest/rdb_step_result_set_test.cpp | 76 +- .../rdb/unittest/rdb_store_config_test.cpp | 106 +- .../rdb/unittest/rdb_store_impl_test.cpp | 29 + .../rdb/unittest/rdb_store_subscribe_test.cpp | 287 +++ .../native/rdb/unittest/rdb_utils_test.cpp | 22 + .../unittest/data_ability_utils_test.cpp | 2 +- relational_store/test/ndk/BUILD.gn | 1 + .../test/ndk/unittest/rdb_cursor_test.cpp | 2 +- .../test/ndk/unittest/rdb_store_test.cpp | 430 +++- test/CMakeLists.txt | 4 + udmf/BUILD.gn | 1 + udmf/bundle.json | 23 +- .../common/custom_utd_json_parser.cpp | 3 +- .../framework/common/custom_utd_json_parser.h | 2 +- udmf/framework/common/custom_utd_store.h | 2 +- udmf/framework/common/graph.cpp | 19 +- udmf/framework/common/graph.h | 1 - udmf/framework/common/tlv_object.h | 4 +- udmf/framework/common/tlv_util.cpp | 13 +- udmf/framework/common/tlv_util.h | 140 +- udmf/framework/common/udmf_radar_reporter.h | 83 + udmf/framework/common/udmf_types_util.h | 34 +- udmf/framework/common/udmf_utils.cpp | 31 + udmf/framework/common/udmf_utils.h | 5 + udmf/framework/common/utd_cfgs_checker.h | 3 +- udmf/framework/common/utd_common.h | 2 +- udmf/framework/common/utd_graph.cpp | 8 +- udmf/framework/common/utd_graph.h | 2 +- .../innerkitsimpl/client/udmf_client.cpp | 126 +- .../innerkitsimpl/client/utd_client.cpp | 35 + .../innerkitsimpl/common/unified_meta.cpp | 475 +++++ .../innerkitsimpl/data/flexible_type.cpp | 2 +- .../data/preset_type_descriptors.cpp | 1847 ++++++++++++++++- .../data/preset_type_descriptors.h | 4 +- .../innerkitsimpl/data/type_descriptor.cpp | 4 +- .../innerkitsimpl/data/unified_data.cpp | 12 +- .../data/unified_data_helper.cpp | 7 +- .../distributeddata_udmf_ipc_interface_code.h | 3 + .../innerkitsimpl/service/udmf_service.h | 3 + .../service/udmf_service_client.cpp | 31 + .../service/udmf_service_client.h | 3 + .../service/udmf_service_proxy.cpp | 41 + .../service/udmf_service_proxy.h | 4 +- .../innerkitsimpl/test/unittest/BUILD.gn | 37 +- .../test/unittest/graph_test.cpp | 270 ++- .../unittest/udmf_client_system_hap_test.cpp | 325 +++ .../test/unittest/udmf_client_test.cpp | 54 + .../test/unittest/utd_client_test.cpp | 166 +- .../jskitsimpl/common/napi_error_utils.cpp | 6 +- .../jskitsimpl/data/type_descriptor_napi.cpp | 3 +- .../data/unified_data_channel_napi.cpp | 64 + .../data/unified_data_properties_napi.cpp | 1 + .../jskitsimpl/data/unified_record_napi.cpp | 10 +- .../data/uniform_type_descriptor_napi.cpp | 6 +- udmf/interfaces/innerkits/BUILD.gn | 67 +- .../interfaces/innerkits/client/udmf_client.h | 20 +- udmf/interfaces/innerkits/client/utd_client.h | 5 +- udmf/interfaces/innerkits/common/error_code.h | 6 +- .../interfaces/innerkits/common/unified_key.h | 4 +- .../innerkits/common/unified_meta.h | 562 ++--- .../innerkits/common/unified_types.h | 1 + .../data/application_defined_record.h | 4 +- udmf/interfaces/innerkits/data/audio.h | 4 +- udmf/interfaces/innerkits/data/file.h | 4 +- .../interfaces/innerkits/data/flexible_type.h | 3 +- udmf/interfaces/innerkits/data/folder.h | 4 +- udmf/interfaces/innerkits/data/html.h | 3 +- udmf/interfaces/innerkits/data/image.h | 3 +- udmf/interfaces/innerkits/data/link.h | 3 +- udmf/interfaces/innerkits/data/plain_text.h | 4 +- .../innerkits/data/system_defined_appitem.h | 3 +- .../innerkits/data/system_defined_form.h | 4 +- .../innerkits/data/system_defined_pixelmap.h | 4 +- .../innerkits/data/system_defined_record.h | 4 +- udmf/interfaces/innerkits/data/text.h | 4 +- .../innerkits/data/type_descriptor.h | 9 +- udmf/interfaces/innerkits/data/unified_data.h | 4 +- .../innerkits/data/unified_data_helper.h | 6 +- .../innerkits/data/unified_data_properties.h | 6 +- .../innerkits/data/unified_record.h | 4 +- udmf/interfaces/innerkits/data/video.h | 4 +- udmf/interfaces/jskits/BUILD.gn | 17 +- .../jskits/common/napi_data_utils.h | 4 +- .../jskits/common/napi_error_utils.h | 14 +- udmf/interfaces/jskits/data/summary_napi.h | 3 +- .../jskits/data/unified_data_channel_napi.h | 2 + .../jskits/data/unified_data_napi.h | 4 +- .../include/system_ability_definition.h | 216 +- 1026 files changed, 43560 insertions(+), 11614 deletions(-) create mode 100644 data_object/frameworks/innerkitsimpl/include/common/anonymous.h create mode 100644 data_object/frameworks/innerkitsimpl/include/common/object_radar_reporter.h create mode 100644 data_share/OAT.xml create mode 100644 data_share/frameworks/native/common/include/datashare_radar_reporter.h create mode 100644 datamgr_service/services/distributeddataservice/adapter/communicator/test/unittest/softbus_adapter_standard_test.cpp create mode 100644 datamgr_service/services/distributeddataservice/adapter/dfx/src/radar_reporter.cpp create mode 100644 datamgr_service/services/distributeddataservice/adapter/include/dfx/radar_reporter.h create mode 100644 datamgr_service/services/distributeddataservice/framework/changeevent/remote_change_event.cpp create mode 100644 datamgr_service/services/distributeddataservice/framework/include/changeevent/remote_change_event.h create mode 100644 datamgr_service/services/distributeddataservice/framework/include/commonevent/data_sync_event.h create mode 100644 datamgr_service/services/distributeddataservice/framework/include/metadata/auto_launch_meta_data.h create mode 100644 datamgr_service/services/distributeddataservice/framework/metadata/auto_launch_meta_data.cpp create mode 100644 datamgr_service/services/distributeddataservice/service/common/xcollie.cpp create mode 100644 datamgr_service/services/distributeddataservice/service/common/xcollie.h create mode 100644 datamgr_service/services/distributeddataservice/service/data_share/sys_event_subscriber.cpp create mode 100644 datamgr_service/services/distributeddataservice/service/data_share/sys_event_subscriber.h create mode 100644 datamgr_service/services/distributeddataservice/service/kvdb/kv_radar_reporter.h create mode 100644 datamgr_service/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/BUILD.gn create mode 100644 datamgr_service/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/corpus/init create mode 100644 datamgr_service/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/customutdinstaller_fuzzer.cpp create mode 100644 datamgr_service/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/customutdinstaller_fuzzer.h create mode 100644 datamgr_service/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/project.xml create mode 100644 datamgr_service/services/distributeddataservice/service/test/fuzztest/dumphelper_fuzzer/BUILD.gn create mode 100644 datamgr_service/services/distributeddataservice/service/test/fuzztest/dumphelper_fuzzer/corpus/init create mode 100644 datamgr_service/services/distributeddataservice/service/test/fuzztest/dumphelper_fuzzer/dumphelper_fuzzer.cpp create mode 100644 datamgr_service/services/distributeddataservice/service/test/fuzztest/dumphelper_fuzzer/dumphelper_fuzzer.h create mode 100644 datamgr_service/services/distributeddataservice/service/test/fuzztest/dumphelper_fuzzer/project.xml rename kv_store/frameworks/libs/distributeddb/cfi_blocklist.txt => datamgr_service/services/distributeddataservice/service/test/mock/BUILD.gn (35%) create mode 100644 datamgr_service/services/distributeddataservice/service/test/mock/checker_mock.cpp create mode 100644 datamgr_service/services/distributeddataservice/service/test/mock/checker_mock.h create mode 100644 datamgr_service/services/distributeddataservice/service/test/rdb_asset_loader_test.cpp create mode 100644 datamgr_service/services/distributeddataservice/service/test/rdb_cloud_test.cpp create mode 100644 datamgr_service/services/distributeddataservice/service/test/rdb_cursor_test.cpp create mode 100644 datamgr_service/services/distributeddataservice/service/test/rdb_general_store_test.cpp create mode 100644 datamgr_service/services/distributeddataservice/service/test/rdb_query_test.cpp create mode 100644 datamgr_service/services/distributeddataservice/service/test/rdb_result_set_stub_test.cpp create mode 100644 interface_sdk/api/@ohos.data.sendablePreferences.d.ets create mode 100644 kv_store/frameworks/cj/include/distributed_kv_store_ffi.h create mode 100644 kv_store/frameworks/cj/include/distributed_kv_store_impl.h create mode 100644 kv_store/frameworks/cj/include/distributed_kv_store_log.h create mode 100644 kv_store/frameworks/cj/include/distributed_kv_store_utils.h create mode 100644 kv_store/frameworks/cj/src/distributed_kv_store_ffi.cpp create mode 100644 kv_store/frameworks/cj/src/distributed_kv_store_impl.cpp create mode 100644 kv_store/frameworks/cj/src/distributed_kv_store_utils.cpp delete mode 100644 kv_store/frameworks/innerkitsimpl/kvdb/src/auto_sync_timer.cpp delete mode 100644 kv_store/frameworks/innerkitsimpl/kvdb/test/auto_sync_timer_test.cpp create mode 100644 kv_store/frameworks/libs/distributeddb/common/include/db_base64_utils.h create mode 100644 kv_store/frameworks/libs/distributeddb/common/include/query_utils.h create mode 100644 kv_store/frameworks/libs/distributeddb/common/src/db_base64_utils.cpp create mode 100644 kv_store/frameworks/libs/distributeddb/common/src/query_utils.cpp create mode 100644 kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_multi_sub_user_test.cpp create mode 100644 kv_store/interfaces/cj/BUILD.gn create mode 100644 kv_store/kvstoremock/frameworks/cj/distributed_kv_store_mock.cpp create mode 100644 mock/innerkits/dmsfwk_standard/distributed_event/include/distributed_sched_types.h create mode 100644 mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/asset/asset_adapter_sa_client.h create mode 100644 mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/asset/asset_callback_interface_code.h create mode 100644 mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/asset/asset_obj.h create mode 100644 mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/asset/asset_recv_callback_stub.h create mode 100644 mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/asset/asset_send_callback_stub.h create mode 100644 mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/asset/i_asset_recv_callback.h create mode 100644 mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/asset/i_asset_send_callback.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/device/device_info.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/device/device_manager_agent.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/asset_callback_manager.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/asset_recv_callback_proxy.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/asset_send_callback_proxy.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/connection_detector.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/daemon.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/daemon_event.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/daemon_eventhandler.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/daemon_execute.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/daemon_stub.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/distributed_file_daemon_ipc_interface_code.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/distributed_file_daemon_manager.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/file_dfs_listener_interface_code.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/file_dfs_listener_proxy.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/file_trans_listener_proxy.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/hmdfs_info.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/i_daemon.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/i_file_dfs_listener.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/trans_mananger.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/mountpoint/mount_manager.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/mountpoint/mount_point.h rename relational_store/frameworks/native/rdb/include/rdb_statement.h => mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/multiuser/os_account_observer.h (32%) create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/base_session.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/devsl_dispatcher.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/kernel_talker.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/network_agent_template.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/session_pool.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_agent.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_asset_recv_listener.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_asset_send_listener.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_file_receive_listener.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_file_send_listener.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_handler.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_handler_asset.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_session.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_session_dispatcher.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_session_listener.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_session_name.h create mode 100644 mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_session_pool.h create mode 100644 mock/innerkits/memmgr/memmgrclient/include/bundle_priority.h rename kv_store/frameworks/innerkitsimpl/kvdb/include/auto_sync_timer.h => mock/innerkits/memmgr/memmgrclient/include/bundle_priority_list.h (35%) create mode 100644 mock/innerkits/memmgr/memmgrclient/include/mem_mgr_process_state_info.h create mode 100644 mock/innerkits/memmgr/memmgrclient/include/mem_mgr_window_info.h create mode 100644 mock/innerkits/memmgr/memmgrclient/include/single_instance.h create mode 100644 mock/src/mock_hisysevent.cpp create mode 100644 mock/src/mock_mem_mgr.cpp create mode 100644 mock/src/mock_xcollie.cpp create mode 100644 preferences/frameworks/cj/BUILD.gn create mode 100644 preferences/frameworks/cj/src/preferences_ffi.cpp create mode 100644 preferences/frameworks/cj/src/preferences_ffi.h create mode 100644 preferences/frameworks/cj/src/preferences_impl.cpp create mode 100644 preferences/frameworks/cj/src/preferences_impl.h create mode 100644 preferences/frameworks/cj/src/preferences_interface.h create mode 100644 preferences/frameworks/cj/src/preferences_log.h create mode 100644 preferences/frameworks/cj/src/preferences_mock.cpp create mode 100644 preferences/frameworks/cj/src/preferences_utils.cpp create mode 100644 preferences/frameworks/cj/src/preferences_utils.h create mode 100644 preferences/frameworks/js/napi/common/BUILD.gn rename preferences/frameworks/js/napi/common/include/{js_utils.h => js_common_utils.h} (96%) create mode 100644 preferences/frameworks/js/napi/common/include/js_proxy.h create mode 100644 preferences/frameworks/js/napi/common/include/js_sendable_utils.h rename kv_store/interfaces/innerkits/distributeddata/cfi_blocklist.txt => preferences/frameworks/js/napi/common/libcommon.map (50%) rename preferences/frameworks/js/napi/common/src/{js_utils.cpp => js_common_utils.cpp} (95%) create mode 100644 preferences/frameworks/js/napi/common/src/js_sendable_utils.cpp create mode 100644 preferences/frameworks/js/napi/common/src/napi_preferences_error.cpp create mode 100644 preferences/frameworks/js/napi/sendable_preferences/BUILD.gn create mode 100644 preferences/frameworks/js/napi/sendable_preferences/include/napi_preferences.h create mode 100644 preferences/frameworks/js/napi/sendable_preferences/include/napi_preferences_helper.h create mode 100644 preferences/frameworks/js/napi/sendable_preferences/src/entry_point.cpp create mode 100644 preferences/frameworks/js/napi/sendable_preferences/src/napi_preferences.cpp create mode 100644 preferences/frameworks/js/napi/sendable_preferences/src/napi_preferences_helper.cpp create mode 100644 preferences/test/js/unittest/preferences/src/PreferencesTaskpoolJsunit.test.js create mode 100644 relational_store/frameworks/cj/BUILD.gn create mode 100644 relational_store/frameworks/cj/include/native_log.h create mode 100644 relational_store/frameworks/cj/include/relational_store_ffi.h create mode 100644 relational_store/frameworks/cj/include/relational_store_impl_rdbpredicatesproxy.h create mode 100644 relational_store/frameworks/cj/include/relational_store_impl_rdbstore.h create mode 100644 relational_store/frameworks/cj/include/relational_store_impl_resultsetproxy.h create mode 100644 relational_store/frameworks/cj/include/relational_store_utils.h create mode 100644 relational_store/frameworks/cj/mock/relational_store_mock.cpp create mode 100644 relational_store/frameworks/cj/src/relational_store_ffi.cpp create mode 100644 relational_store/frameworks/cj/src/relational_store_impl_rdbpredicatesproxy.cpp create mode 100644 relational_store/frameworks/cj/src/relational_store_impl_rdbstore.cpp create mode 100644 relational_store/frameworks/cj/src/relational_store_impl_resultsetproxy.cpp create mode 100644 relational_store/frameworks/cj/src/relational_store_utils.cpp create mode 100644 relational_store/frameworks/js/napi/common/mock/include/event_handler.h create mode 100644 relational_store/frameworks/native/dfx/include/rdb_radar_reporter.h create mode 100644 relational_store/frameworks/native/dfx/src/rdb_radar_reporter.cpp delete mode 100644 relational_store/frameworks/native/rdb/include/rd_result_set.h delete mode 100644 relational_store/frameworks/native/rdb/include/rdb_connection.h delete mode 100644 relational_store/frameworks/native/rdb/include/rdb_connection_pool.h create mode 100644 relational_store/frameworks/native/rdb/include/rdb_sql_statistic.h delete mode 100644 relational_store/frameworks/native/rdb/include/vdb_store_impl.h create mode 100644 relational_store/frameworks/native/rdb/mock/include/hisysevent.h delete mode 100644 relational_store/frameworks/native/rdb/mock/include/vdb_store_impl.h create mode 100644 relational_store/frameworks/native/rdb/mock/src/rdb_radar_reporter.cpp delete mode 100644 relational_store/frameworks/native/rdb/src/rd_result_set.cpp delete mode 100644 relational_store/frameworks/native/rdb/src/rdb_connection.cpp delete mode 100644 relational_store/frameworks/native/rdb/src/rdb_connection_pool.cpp create mode 100644 relational_store/frameworks/native/rdb/src/rdb_sql_statistic.cpp delete mode 100644 relational_store/frameworks/native/rdb/src/rdb_statement.cpp delete mode 100644 relational_store/frameworks/native/rdb/src/vdb_store_impl.cpp create mode 100644 relational_store/interfaces/ndk/src/convertor_error_code.cpp create mode 100644 relational_store/interfaces/ndk/src/convertor_error_code.h create mode 100644 relational_store/rdbmock/frameworks/native/rdb/file_ex.h create mode 100644 relational_store/rdbmock/frameworks/native/rdb/hks_api.h create mode 100644 relational_store/rdbmock/frameworks/native/rdb/hks_param.h create mode 100644 relational_store/rdbmock/frameworks/native/rdb/hks_type.h create mode 100644 relational_store/rdbmock/frameworks/native/rdb/lru_bucket.h create mode 100644 relational_store/test/js/relationalstore/unittest/src/RdbStoreReadOnlyJsunit.test.js create mode 100644 relational_store/test/js/relationalstore/unittest/src/RdbStoreStatisticsJsunit.test.js create mode 100644 relational_store/test/native/appdatafwk/BUILD.gn create mode 100644 relational_store/test/native/appdatafwk/unittest/serializable_test.cpp create mode 100644 relational_store/test/native/clouddata/BUILD.gn create mode 100644 relational_store/test/native/clouddata/unittest/cloud_data_test.cpp create mode 100644 relational_store/test/native/rdb/unittest/rdb_read_only_test.cpp create mode 100644 udmf/framework/common/udmf_radar_reporter.h create mode 100644 udmf/framework/innerkitsimpl/test/unittest/udmf_client_system_hap_test.cpp diff --git a/data_object/CMakeLists.txt b/data_object/CMakeLists.txt index 41520278..318c5f41 100644 --- a/data_object/CMakeLists.txt +++ b/data_object/CMakeLists.txt @@ -21,7 +21,6 @@ aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/jskitsimpl/src/adapt aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/jskitsimpl/src/common data_object_src) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/innerkitsimpl/include/adaptor) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/innerkitsimpl/include/common) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/innerkitsimpl/include/communicator) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/innerkitsimpl/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/jskitsimpl/include/adaptor) @@ -36,5 +35,6 @@ include(${KV_STORE_DIR}/interfaces/CMakeLists.txt OPTIONAL) set(links secure mock adapter distributeddb kvdb) add_library(data_object SHARED ${data_object_src}) target_link_libraries(data_object ${links}) +target_include_directories(data_object PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/frameworks/innerkitsimpl/include/common) target_include_directories(data_object PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/innerkits) target_include_directories(data_object PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../relational_store/interfaces/inner_api/common_type/include) \ No newline at end of file diff --git a/data_object/bundle.json b/data_object/bundle.json index b23a7250..146b70fc 100644 --- a/data_object/bundle.json +++ b/data_object/bundle.json @@ -47,6 +47,7 @@ "ability_runtime", "hitrace", "dsoftbus", + "bounds_checking_function", "napi", "samgr", "ipc", @@ -55,8 +56,10 @@ "c_utils", "device_manager", "kv_store", + "libuv", "common_event_service", - "dmsfwk" + "dmsfwk", + "hisysevent" ], "third_party": [ "libuv", 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 3408cbb0..8ab380d2 100644 --- a/data_object/frameworks/innerkitsimpl/include/adaptor/flat_object_store.h +++ b/data_object/frameworks/innerkitsimpl/include/adaptor/flat_object_store.h @@ -41,9 +41,9 @@ public: const std::map> &objectData); uint32_t RevokeSave(const std::string &bundleName, const std::string &sessionId); int32_t ResumeObject(const std::string &bundleName, const std::string &sessionId, - std::function> &data)> &callback); + std::function> &data, bool allReady)> &callback); int32_t SubscribeDataChange(const std::string &bundleName, const std::string &sessionId, - std::function> &data)> &callback); + std::function> &data, bool allReady)> &callback); int32_t UnregisterDataChange(const std::string &bundleName, const std::string &sessionId); int32_t DeleteSnapshot(const std::string &bundleName, const std::string &sessionId); private: @@ -62,12 +62,12 @@ public: ~FlatObjectStore(); std::string GetBundleName(); uint32_t CreateObject(const std::string &sessionId); + void ResumeObject(const std::string &sessionId); + void SubscribeDataChange(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 SetStatusNotifier(std::shared_ptr sharedPtr); - uint32_t SyncAllData(const std::string &sessionId, - const std::function &)> &onComplete); uint32_t Save(const std::string &sessionId, const std::string &deviceId); uint32_t RevokeSave(const std::string &sessionId); void CheckRetrieveCache(const std::string &sessionId); diff --git a/data_object/frameworks/innerkitsimpl/include/adaptor/object_callback_impl.h b/data_object/frameworks/innerkitsimpl/include/adaptor/object_callback_impl.h index e6bb57c0..f61b0594 100644 --- a/data_object/frameworks/innerkitsimpl/include/adaptor/object_callback_impl.h +++ b/data_object/frameworks/innerkitsimpl/include/adaptor/object_callback_impl.h @@ -41,20 +41,22 @@ private: class ObjectRetrieveCallback : public ObjectRetrieveCallbackStub { public: - ObjectRetrieveCallback(const std::function> &)> &callback); - void Completed(const std::map> &results) override; + ObjectRetrieveCallback( + const std::function> &, bool)> &callback); + void Completed(const std::map> &results, bool allReady) override; private: - const std::function> &)> callback_; + const std::function> &, bool)> callback_; }; class ObjectChangeCallback : public ObjectChangeCallbackStub { public: - ObjectChangeCallback(const std::function> &)> &callback); - void Completed(const std::map> &results) override; + ObjectChangeCallback( + const std::function> &, bool)> &callback); + void Completed(const std::map> &results, bool allReady) override; private: - const std::function> &)> callback_; + const std::function> &, bool)> callback_; }; } // namespace ObjectStore } // namespace OHOS diff --git a/data_object/frameworks/innerkitsimpl/include/common/anonymous.h b/data_object/frameworks/innerkitsimpl/include/common/anonymous.h new file mode 100644 index 00000000..654dae2d --- /dev/null +++ b/data_object/frameworks/innerkitsimpl/include/common/anonymous.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_OBJECTSTORE_ANONYMOUS_H +#define OHOS_OBJECTSTORE_ANONYMOUS_H + +#include + +namespace OHOS { +namespace ObjectStore { +class Anonymous { +public: + static std::string Change(const std::string &data) + { + if (data.size() <= HEAD_SIZE) { + return DEFAULT_ANONYMOUS; + } + if (data.size() < MIN_SIZE) { + return (data.substr(0, HEAD_SIZE) + REPLACE_CHAIN); + } + return (data.substr(0, HEAD_SIZE) + REPLACE_CHAIN + data.substr(data.size() - END_SIZE, END_SIZE)); + } + +private: + static constexpr size_t HEAD_SIZE = 3; + static constexpr size_t END_SIZE = 3; + static constexpr size_t MIN_SIZE = HEAD_SIZE + END_SIZE + 3; + static constexpr const char *REPLACE_CHAIN = "***"; + static constexpr const char *DEFAULT_ANONYMOUS = "******"; +}; +} // namespace ObjectStore +} // namespace OHOS +#endif // OHOS_OBJECTSTORE_ANONYMOUS_H \ No newline at end of file diff --git a/data_object/frameworks/innerkitsimpl/include/common/object_radar_reporter.h b/data_object/frameworks/innerkitsimpl/include/common/object_radar_reporter.h new file mode 100644 index 00000000..95181502 --- /dev/null +++ b/data_object/frameworks/innerkitsimpl/include/common/object_radar_reporter.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBJECT_RADAR_REPORTER_H +#define OBJECT_RADAR_REPORTER_H + +#include "hisysevent.h" + +namespace OHOS::ObjectStore { +enum BizScene { + CREATE = 1, + SAVE = 2, +}; +enum CreateStage { + INIT_STORE = 1, + CREATE_TABLE = 2, + RESTORE = 3, + TRANSFER = 4, +}; +enum SaveStage { + SAVE_TO_SERVICE = 1, + SAVE_TO_STORE = 2, + PUSH_ASSETS = 3, +}; +enum StageRes { + IDLE = 0, + RADAR_SUCCESS = 1, + RADAR_FAILED = 2, + CANCELLED = 3, +}; +enum BizState { + START = 1, + FINISHED = 2, +}; +enum ErrorCode { + OFFSET = 27525120, + DUPLICATE_CREATE = OFFSET, + NO_MEMORY = OFFSET + 1, + SA_DIED = OFFSET + 2, + TIMEOUT = OFFSET + 3, + IPC_ERROR = OFFSET + 4, + NO_PERMISSION = OFFSET + 5, + GETKV_FAILED = OFFSET + 6, + DB_NOT_INIT = OFFSET + 7, +}; +static constexpr char DOMAIN[] = "DISTDATAMGR"; +const std::string EVENT_NAME = "DISTRIBUTED_DATA_OBJECT_BEHAVIOR"; +static constexpr HiviewDFX::HiSysEvent::EventType TYPE = HiviewDFX::HiSysEvent::EventType::BEHAVIOR; +const std::string ORG_PKG = "distributeddata"; +const std::string ERROR_CODE = "ERROR_CODE"; +const std::string BIZ_STATE = "BIZ_STATE"; + +#define RADAR_REPORT(bizScene, bizStage, stageRes, ...) \ +({ \ + HiSysEventWrite(ObjectStore::DOMAIN, ObjectStore::EVENT_NAME, ObjectStore::TYPE, \ + "ORG_PKG", ObjectStore::ORG_PKG, "FUNC", __FUNCTION__, \ + "BIZ_SCENE", bizScene, "BIZ_STAGE", bizStage, "STAGE_RES", stageRes, ##__VA_ARGS__); \ +}) +} // namespace OHOS::ObjectStore +#endif // OBJECT_RADAR_REPORTER_H diff --git a/data_object/frameworks/innerkitsimpl/include/communicator/softbus_adapter.h b/data_object/frameworks/innerkitsimpl/include/communicator/softbus_adapter.h index eaa8e103..74869706 100644 --- a/data_object/frameworks/innerkitsimpl/include/communicator/softbus_adapter.h +++ b/data_object/frameworks/innerkitsimpl/include/communicator/softbus_adapter.h @@ -26,6 +26,7 @@ #include "app_types.h" #include "concurrent_map.h" #include "session.h" +#include "socket.h" #include "softbus_bus_center.h" #include "task_scheduler.h" @@ -62,43 +63,39 @@ public: bool IsSameStartedOnPeer(const struct PipeInfo &pipeInfo, const struct DeviceId &peer); - void SetMessageTransFlag(const PipeInfo &pipeInfo, bool flag); - int CreateSessionServerAdapter(const std::string &sessionName); int RemoveSessionServerAdapter(const std::string &sessionName) const; void UpdateRelationship(const std::string &networkid, const DeviceChangeType &type); - void InsertSession(const std::string &sessionName); + void NotifyDataListeners(const uint8_t *ptr, const int size, const std::string &deviceId, const PipeInfo &pipeInfo); - void DeleteSession(const std::string &sessionName); + void OnClientShutdown(int32_t socket); - void NotifyDataListeners(const uint8_t *ptr, const int size, const std::string &deviceId, const PipeInfo &pipeInfo); + void OnBind(int32_t socket, PeerSocketInfo info); - std::string ToNodeID(const std::string &nodeId) const; + void OnServerShutdown(int32_t socket); - void OnSessionOpen(int32_t sessionId, int32_t status); + bool GetPeerSocketInfo(int32_t socket, PeerSocketInfo &info); - void OnSessionClose(int32_t sessionId); + std::string ToNodeID(const std::string &nodeId) const; private: struct BytesMsg { uint8_t *ptr; uint32_t size; }; - static constexpr uint32_t P2P_SIZE_THRESHOLD = 0x10000u; // 64KB static constexpr uint32_t VECTOR_SIZE_THRESHOLD = 100; - static constexpr float SWITCH_DELAY_FACTOR = 0.6f; + static constexpr uint32_t QOS_COUNT = 3; + static constexpr QosTV Qos[QOS_COUNT] = { + { .qos = QOS_TYPE_MIN_BW, .value = 90 * 1024 * 1024 }, + { .qos = QOS_TYPE_MAX_LATENCY, .value = 10000 }, + { .qos = QOS_TYPE_MIN_LATENCY, .value = 2000 } }; Status CacheData(const std::string &deviceId, const DataInfo &dataInfo); - uint32_t GetSize(const std::string &deviceId); - RouteType GetRouteType(int sessionId); - RecOperate CalcRecOperate(uint32_t dataSize, RouteType currentRouteType, bool &isP2P) const; - void CacheSession(int32_t sessionId); void DoSend(); - int GetDeviceId(int sessionId, std::string &deviceId); - int GetSessionId(const std::string &deviceId); - SessionAttribute GetSessionAttribute(bool isP2P); + int GetSocket(const PipeInfo &pipeInfo, const DeviceId &deviceId); + int CreateClientSocket(const PipeInfo &pipeInfo, const DeviceId &deviceId); mutable std::mutex networkMutex_{}; mutable std::map networkId2Uuid_{}; DeviceInfo localInfo_{}; @@ -107,28 +104,28 @@ private: std::set listeners_{}; std::mutex dataChangeMutex_{}; std::map dataChangeListeners_{}; - std::mutex busSessionMutex_{}; - std::map busSessionMap_{}; - bool flag_ = true; // only for br flag - ISessionListener sessionListener_{}; - std::mutex statusMutex_{}; std::mutex sendDataMutex_{}; - std::mutex mapLock_; - std::mutex deviceSessionLock_; - std::map sessionIds_; + std::mutex socketLock_; std::mutex deviceDataLock_; std::map> dataCaches_; std::shared_ptr taskQueue_; std::mutex localDeviceLock_{}; + std::map sockets_; + int32_t socketServer_{0}; + ConcurrentMap peerSocketInfos_; + ISocketListener clientListener_{}; + ISocketListener serverListener_{}; }; class AppDataListenerWrap { public: static void SetDataHandler(SoftBusAdapter *handler); - static int OnSessionOpened(int sessionId, int result); - static void OnSessionClosed(int sessionId); - static void OnMessageReceived(int sessionId, const void *data, unsigned int dataLen); - static void OnBytesReceived(int sessionId, const void *data, unsigned int dataLen); + static void OnClientShutdown(int32_t socket, ShutdownReason reason); + static void OnClientBytesReceived(int32_t socket, const void *data, uint32_t dataLen); + + static void OnServerBind(int32_t socket, PeerSocketInfo info); + static void OnServerShutdown(int32_t socket, ShutdownReason reason); + static void OnServerBytesReceived(int32_t socket, const void *data, uint32_t dataLen); public: // notifiy all listeners when received message @@ -138,4 +135,4 @@ public: }; } // namespace ObjectStore } // namespace OHOS -#endif /* DISTRIBUTEDDATAFWK_SRC_SOFTBUS_ADAPTER_H */ \ No newline at end of file +#endif /* DISTRIBUTEDDATAFWK_SRC_SOFTBUS_ADAPTER_H */ diff --git a/data_object/frameworks/innerkitsimpl/include/object_callback.h b/data_object/frameworks/innerkitsimpl/include/object_callback.h index c1f74875..ecd209b1 100644 --- a/data_object/frameworks/innerkitsimpl/include/object_callback.h +++ b/data_object/frameworks/innerkitsimpl/include/object_callback.h @@ -38,12 +38,12 @@ public: class IObjectRetrieveCallback { public: - virtual void Completed(const std::map> &results) = 0; + virtual void Completed(const std::map> &results, bool allReady) = 0; }; class IObjectChangeCallback { public: - virtual void Completed(const std::map> &results) = 0; + virtual void Completed(const std::map> &results, bool allReady) = 0; }; } // namespace DistributedObject } // namespace OHOS 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 833cd059..17b7c15b 100644 --- a/data_object/frameworks/innerkitsimpl/src/adaptor/distributed_object_impl.cpp +++ b/data_object/frameworks/innerkitsimpl/src/adaptor/distributed_object_impl.cpp @@ -20,6 +20,7 @@ #include "string_utils.h" #include "dev_manager.h" #include "bytes_utils.h" +#include "object_radar_reporter.h" namespace OHOS::ObjectStore { DistributedObjectImpl::~DistributedObjectImpl() @@ -90,6 +91,7 @@ uint32_t DistributedObjectImpl::GetComplex(const std::string &key, std::vectorSave(sessionId_, deviceId); if (status != SUCCESS) { LOG_ERROR("DistributedObjectImpl:Save failed. status = %{public}d", status); 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 20b95f85..8abff6e4 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 @@ -23,6 +23,7 @@ #include "softbus_adapter.h" #include "string_utils.h" #include "asset_change_timer.h" +#include "object_radar_reporter.h" namespace OHOS::ObjectStore { DistributedObjectStoreImpl::DistributedObjectStoreImpl(FlatObjectStore *flatObjectStore) @@ -124,6 +125,7 @@ uint32_t DistributedObjectStoreImpl::DeleteObject(const std::string &sessionId) uint32_t DistributedObjectStoreImpl::Get(const std::string &sessionId, DistributedObject **object) { + std::unique_lock cacheLock(dataMutex_); auto iter = objects_.begin(); while (iter != objects_.end()) { if ((*iter)->GetSessionId() == sessionId) { @@ -255,6 +257,7 @@ void WatcherProxy::SetAssetChangeCallBack(const AssetChangeCallback &assetChange DistributedObjectStore *DistributedObjectStore::GetInstance(const std::string &bundleName) { + RADAR_REPORT(CREATE, INIT_STORE, IDLE, BIZ_STATE, START); static std::mutex instLock_; static DistributedObjectStore *instPtr = nullptr; if (instPtr == nullptr) { @@ -264,6 +267,7 @@ DistributedObjectStore *DistributedObjectStore::GetInstance(const std::string &b FlatObjectStore *flatObjectStore = new (std::nothrow) FlatObjectStore(bundleName); if (flatObjectStore == nullptr) { LOG_ERROR("no memory for FlatObjectStore malloc!"); + RADAR_REPORT(CREATE, INIT_STORE, RADAR_FAILED, ERROR_CODE, NO_MEMORY, BIZ_STATE, FINISHED); return nullptr; } // Use instMemory to make sure this singleton not free before other object. @@ -272,10 +276,12 @@ DistributedObjectStore *DistributedObjectStore::GetInstance(const std::string &b if (instPtr == nullptr) { delete flatObjectStore; LOG_ERROR("no memory for DistributedObjectStoreImpl malloc!"); + RADAR_REPORT(CREATE, INIT_STORE, RADAR_FAILED, ERROR_CODE, NO_MEMORY, BIZ_STATE, FINISHED); return nullptr; } } } + RADAR_REPORT(CREATE, INIT_STORE, RADAR_SUCCESS); return instPtr; } diff --git a/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_storage_engine.cpp b/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_storage_engine.cpp index 380dd7f6..77fdee13 100644 --- a/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_storage_engine.cpp +++ b/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_storage_engine.cpp @@ -21,6 +21,7 @@ #include "softbus_adapter.h" #include "string_utils.h" #include "types_export.h" +#include "object_radar_reporter.h" namespace OHOS::ObjectStore { FlatObjectStorageEngine::~FlatObjectStorageEngine() @@ -84,20 +85,22 @@ void FlatObjectStorageEngine::OnComplete(const std::string &key, uint32_t FlatObjectStorageEngine::CreateTable(const std::string &key) { + RADAR_REPORT(CREATE, CREATE_TABLE, IDLE); if (!isOpened_) { + RADAR_REPORT(CREATE, CREATE_TABLE, RADAR_FAILED, ERROR_CODE, DB_NOT_INIT, BIZ_STATE, FINISHED); return ERR_DB_NOT_INIT; } { std::lock_guard lock(operationMutex_); if (delegates_.count(key) != 0) { LOG_ERROR("FlatObjectStorageEngine::CreateTable %{public}s already created", key.c_str()); + RADAR_REPORT(CREATE, CREATE_TABLE, RADAR_FAILED, ERROR_CODE, DUPLICATE_CREATE, BIZ_STATE, FINISHED); return ERR_EXIST; } } DistributedDB::KvStoreNbDelegate *kvStore = nullptr; DistributedDB::DBStatus status; - DistributedDB::KvStoreNbDelegate::Option option = { true, true, - false }; // createIfNecessary, isMemoryDb, isEncryptedDb + DistributedDB::KvStoreNbDelegate::Option option = { true, true, false }; LOG_INFO("start create table"); storeManager_->GetKvStore(key, option, [&status, &kvStore](DistributedDB::DBStatus dbStatus, DistributedDB::KvStoreNbDelegate *kvStoreNbDelegate) { @@ -107,6 +110,7 @@ uint32_t FlatObjectStorageEngine::CreateTable(const std::string &key) }); if (status != DistributedDB::DBStatus::OK || kvStore == nullptr) { LOG_ERROR("FlatObjectStorageEngine::CreateTable %{public}s getkvstore fail[%{public}d]", key.c_str(), status); + RADAR_REPORT(CREATE, CREATE_TABLE, RADAR_FAILED, ERROR_CODE, status, BIZ_STATE, FINISHED); return ERR_DB_GETKV_FAIL; } bool autoSync = true; @@ -115,6 +119,7 @@ uint32_t FlatObjectStorageEngine::CreateTable(const std::string &key) status = kvStore->Pragma(DistributedDB::AUTO_SYNC, data); if (status != DistributedDB::DBStatus::OK) { LOG_ERROR("FlatObjectStorageEngine::CreateTable %{public}s Pragma fail[%{public}d]", key.c_str(), status); + RADAR_REPORT(CREATE, CREATE_TABLE, RADAR_FAILED, ERROR_CODE, status, BIZ_STATE, FINISHED); return ERR_DB_GETKV_FAIL; } LOG_INFO("create table %{public}s success", key.c_str()); @@ -122,7 +127,6 @@ uint32_t FlatObjectStorageEngine::CreateTable(const std::string &key) std::lock_guard lock(operationMutex_); delegates_.insert_or_assign(key, kvStore); } - auto onComplete = [key, this](const std::map &devices) { OnComplete(key, devices, statusWatcher_); }; @@ -132,6 +136,7 @@ uint32_t FlatObjectStorageEngine::CreateTable(const std::string &key) deviceIds.push_back(item.deviceId); } SyncAllData(key, deviceIds, onComplete); + RADAR_REPORT(CREATE, CREATE_TABLE, RADAR_SUCCESS); return SUCCESS; } @@ -345,8 +350,9 @@ uint32_t FlatObjectStorageEngine::SetStatusNotifier(std::shared_ptr &devices) { for (auto item : devices) { - LOG_INFO("%{public}s pull data result %{public}d in device %{public}s", storeId.c_str(), - item.second, SoftBusAdapter::GetInstance()->ToNodeID(item.first).c_str()); + LOG_INFO("%{public}s pull data result %{public}d in device %{public}s", + SoftBusAdapter::ToBeAnonymous(storeId).c_str(), item.second, + SoftBusAdapter::ToBeAnonymous(SoftBusAdapter::GetInstance()->ToNodeID(item.first)).c_str()); } if (statusWatcher_ != nullptr) { for (auto item : devices) { 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 b9aaf0b1..7ac84b78 100644 --- a/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_store.cpp +++ b/data_object/frameworks/innerkitsimpl/src/adaptor/flat_object_store.cpp @@ -21,6 +21,7 @@ #include "distributed_objectstore_impl.h" #include "logger.h" #include "object_callback_impl.h" +#include "object_radar_reporter.h" #include "object_service_proxy.h" #include "objectstore_errors.h" #include "softbus_adapter.h" @@ -59,44 +60,55 @@ uint32_t FlatObjectStore::CreateObject(const std::string &sessionId) LOG_ERROR("FlatObjectStore::CreateObject createTable err %{public}d", status); return status; } - std::function> &data)> callback = - [sessionId, this]( - const std::map> &data) { - if (data.size() > 0) { - LOG_INFO("objectstore, retrieve success"); - { - std::lock_guard lck(mutex_); - if (find(retrievedCache_.begin(), retrievedCache_.end(), sessionId) == retrievedCache_.end()) { - retrievedCache_.push_back(sessionId); - } + ResumeObject(sessionId); + SubscribeDataChange(sessionId); + return SUCCESS; +} + +void FlatObjectStore::ResumeObject(const std::string &sessionId) +{ + std::function> &data, bool allReady)> callback = + [sessionId, this]( + const std::map> &data, bool allReady) { + if (data.size() == 0) { + LOG_INFO("retrieve empty"); + return; + } + LOG_INFO("retrieve success, data.size:%{public}zu, allReady:%{public}d", data.size(), allReady); + auto result = storageEngine_->UpdateItems(sessionId, data); + if (result != SUCCESS) { + LOG_ERROR("UpdateItems failed, status = %{public}d", result); + } + if (allReady) { + std::lock_guard lck(mutex_); + if (find(retrievedCache_.begin(), retrievedCache_.end(), sessionId) == retrievedCache_.end()) { + retrievedCache_.push_back(sessionId); + } + storageEngine_->NotifyStatus(sessionId, "local", "restored"); + } + }; + cacheManager_->ResumeObject(bundleName_, sessionId, callback); +} + +void FlatObjectStore::SubscribeDataChange(const std::string &sessionId) +{ + std::function> &data, bool allReady)> remoteResumeCallback = + [sessionId, this](const std::map> &data, bool allReady) { + LOG_INFO("DataChange callback. data.size:%{public}zu, allReady:%{public}d", data.size(), allReady); + std::map> filteredData = data; + FilterData(sessionId, filteredData); + if (!filteredData.empty()) { + auto status = storageEngine_->UpdateItems(sessionId, filteredData); + if (status != SUCCESS) { + LOG_ERROR("UpdateItems failed, status = %{public}d", status); } - auto result = storageEngine_->UpdateItems(sessionId, data); + storageEngine_->NotifyChange(sessionId, filteredData); + } + if (allReady) { storageEngine_->NotifyStatus(sessionId, "local", "restored"); - if (result != SUCCESS) { - LOG_ERROR("UpdateItems failed, status = %{public}d", result); - } - } else { - LOG_INFO("objectstore, retrieve empty"); } }; - std::function> &data)> remoteResumeCallback = - [sessionId, this]( - const std::map> &data) { - LOG_INFO("SubscribeDataChange callback success."); - std::map> filteredData = data; - FilterData(sessionId, filteredData); - if (!filteredData.empty()) { - auto status = storageEngine_->UpdateItems(sessionId, filteredData); - if (status != SUCCESS) { - LOG_ERROR("UpdateItems failed, status = %{public}d", status); - } - storageEngine_->NotifyChange(sessionId, filteredData); - } - storageEngine_->NotifyStatus(sessionId, "local", "restored"); - }; - cacheManager_->ResumeObject(bundleName_, sessionId, callback); cacheManager_->SubscribeDataChange(bundleName_, sessionId, remoteResumeCallback); - return SUCCESS; } uint32_t FlatObjectStore::Delete(const std::string &sessionId) @@ -168,21 +180,6 @@ uint32_t FlatObjectStore::SetStatusNotifier(std::shared_ptr notif return storageEngine_->SetStatusNotifier(notifier); } -uint32_t FlatObjectStore::SyncAllData(const std::string &sessionId, - const std::function &)> &onComplete) -{ - if (!storageEngine_->isOpened_ && storageEngine_->Open(bundleName_) != SUCCESS) { - LOG_ERROR("FlatObjectStore::DB has not inited"); - return ERR_DB_NOT_INIT; - } - std::vector devices = SoftBusAdapter::GetInstance()->GetDeviceList(); - std::vector deviceIds; - for (auto item : devices) { - deviceIds.push_back(item.deviceId); - } - return storageEngine_->SyncAllData(sessionId, deviceIds, onComplete); -} - uint32_t FlatObjectStore::Save(const std::string &sessionId, const std::string &deviceId) { if (cacheManager_ == nullptr) { @@ -193,6 +190,7 @@ uint32_t FlatObjectStore::Save(const std::string &sessionId, const std::string & uint32_t status = storageEngine_->GetItems(sessionId, objectData); if (status != SUCCESS) { LOG_ERROR("FlatObjectStore::GetItems fail"); + RADAR_REPORT(SAVE, SAVE_TO_SERVICE, RADAR_FAILED, ERROR_CODE, status, BIZ_STATE, FINISHED); return status; } return cacheManager_->Save(bundleName_, sessionId, deviceId, objectData); @@ -392,6 +390,9 @@ uint32_t CacheManager::Save(const std::string &bundleName, const std::string &se LOG_INFO("CacheManager::start wait"); auto [timeout, res] = block->GetValue(); LOG_INFO("CacheManager::end wait, timeout: %{public}d, result: %{public}d", timeout, res); + if (timeout) { + RADAR_REPORT(SAVE, SAVE_TO_SERVICE, RADAR_FAILED, ERROR_CODE, TIMEOUT, BIZ_STATE, FINISHED); + } return res; } @@ -420,19 +421,25 @@ int32_t CacheManager::SaveObject(const std::string &bundleName, const std::strin sptr proxy = ClientAdaptor::GetObjectService(); if (proxy == nullptr) { LOG_ERROR("proxy is nullptr."); + RADAR_REPORT(SAVE, SAVE_TO_SERVICE, RADAR_FAILED, ERROR_CODE, SA_DIED, BIZ_STATE, FINISHED); return ERR_PROCESSING; } sptr objectSaveCallback = new (std::nothrow) ObjectSaveCallback(callback); if (objectSaveCallback == nullptr) { LOG_ERROR("CacheManager::SaveObject no memory for ObjectSaveCallback malloc!"); + RADAR_REPORT(SAVE, SAVE_TO_SERVICE, RADAR_FAILED, ERROR_CODE, NO_MEMORY, BIZ_STATE, FINISHED); return ERR_NULL_PTR; } int32_t status = proxy->ObjectStoreSave( bundleName, sessionId, deviceId, objectData, objectSaveCallback->AsObject().GetRefPtr()); if (status != SUCCESS) { LOG_ERROR("object save failed code=%d.", static_cast(status)); + if (status == ERR_IPC) { + RADAR_REPORT(SAVE, SAVE_TO_SERVICE, RADAR_FAILED, ERROR_CODE, IPC_ERROR, BIZ_STATE, FINISHED); + } } LOG_INFO("object save successful"); + RADAR_REPORT(SAVE, SAVE_TO_SERVICE, RADAR_SUCCESS); return status; } @@ -460,29 +467,33 @@ int32_t CacheManager::RevokeSaveObject( } int32_t CacheManager::ResumeObject(const std::string &bundleName, const std::string &sessionId, - std::function> &data)> &callback) + std::function> &data, bool allReady)> &callback) { + RADAR_REPORT(CREATE, RESTORE, IDLE); sptr proxy = ClientAdaptor::GetObjectService(); if (proxy == nullptr) { LOG_ERROR("proxy is nullptr."); + RADAR_REPORT(CREATE, RESTORE, RADAR_FAILED, ERROR_CODE, SA_DIED, BIZ_STATE, FINISHED); return ERR_NULL_PTR; } sptr objectRetrieveCallback = new (std::nothrow) ObjectRetrieveCallback(callback); if (objectRetrieveCallback == nullptr) { LOG_ERROR("CacheManager::ResumeObject no memory for ObjectRetrieveCallback malloc!"); + RADAR_REPORT(CREATE, RESTORE, RADAR_FAILED, ERROR_CODE, NO_MEMORY, BIZ_STATE, FINISHED); return ERR_NULL_PTR; } int32_t status = proxy->ObjectStoreRetrieve( bundleName, sessionId, objectRetrieveCallback->AsObject().GetRefPtr()); if (status != SUCCESS) { LOG_ERROR("object resume failed code=%d.", static_cast(status)); + RADAR_REPORT(CREATE, RESTORE, RADAR_FAILED, ERROR_CODE, IPC_ERROR, BIZ_STATE, FINISHED); } LOG_INFO("object resume successful"); return status; } int32_t CacheManager::SubscribeDataChange(const std::string &bundleName, const std::string &sessionId, - std::function> &data)> &callback) + std::function> &data, bool allReady)> &callback) { sptr proxy = ClientAdaptor::GetObjectService(); if (proxy == nullptr) { diff --git a/data_object/frameworks/innerkitsimpl/src/adaptor/object_callback_impl.cpp b/data_object/frameworks/innerkitsimpl/src/adaptor/object_callback_impl.cpp index 6e887f8a..9cf4d9a5 100644 --- a/data_object/frameworks/innerkitsimpl/src/adaptor/object_callback_impl.cpp +++ b/data_object/frameworks/innerkitsimpl/src/adaptor/object_callback_impl.cpp @@ -34,24 +34,24 @@ ObjectRevokeSaveCallback::ObjectRevokeSaveCallback(const std::function> &results) +void ObjectRetrieveCallback::Completed(const std::map> &results, bool allReady) { - callback_(results); + callback_(results, allReady); } ObjectRetrieveCallback::ObjectRetrieveCallback( - const std::function> &)> &callback) + const std::function> &, bool)> &callback) : callback_(callback) { } -void ObjectChangeCallback::Completed(const std::map> &results) +void ObjectChangeCallback::Completed(const std::map> &results, bool allReady) { - callback_(results); + callback_(results, allReady); } ObjectChangeCallback::ObjectChangeCallback( - const std::function> &)> &callback) + const std::function> &, bool)> &callback) : callback_(callback) { } diff --git a/data_object/frameworks/innerkitsimpl/src/communicator/process_communicator_impl.cpp b/data_object/frameworks/innerkitsimpl/src/communicator/process_communicator_impl.cpp index 502e8c6b..778f5eb7 100644 --- a/data_object/frameworks/innerkitsimpl/src/communicator/process_communicator_impl.cpp +++ b/data_object/frameworks/innerkitsimpl/src/communicator/process_communicator_impl.cpp @@ -17,6 +17,8 @@ #include +#include "anonymous.h" + namespace OHOS { namespace ObjectStore { using namespace DistributedDB; @@ -181,14 +183,15 @@ void ProcessCommunicatorImpl::OnDeviceChanged(const DeviceInfo &info, const Devi LOG_ERROR("onDeviceChangeHandler_ invalid."); return; } - std::vector canHandleDev = CommunicationProvider::GetInstance().GetDeviceList(); - if (canHandleDev.empty()) { - LOG_WARN("Can handle device is empty"); - return; + std::vector devices = CommunicationProvider::GetInstance().GetDeviceList(); + for (const auto &device : devices) { + if (info.deviceId == device.deviceId) { + DeviceInfos devInfo{ info.deviceId }; + onDeviceChangeHandler_(devInfo, (type == DeviceChangeType::DEVICE_ONLINE)); + return; + } } - DeviceInfos devInfo; - devInfo.identifier = info.deviceId; - onDeviceChangeHandler_(devInfo, (type == DeviceChangeType::DEVICE_ONLINE)); + LOG_WARN("Not a collaboration device, uuid: %{public}s.", Anonymous::Change(info.deviceId).c_str()); } } // namespace ObjectStore } // namespace OHOS diff --git a/data_object/frameworks/innerkitsimpl/src/communicator/softbus_adapter_standard.cpp b/data_object/frameworks/innerkitsimpl/src/communicator/softbus_adapter_standard.cpp index 4d233a01..1b2f7aef 100644 --- a/data_object/frameworks/innerkitsimpl/src/communicator/softbus_adapter_standard.cpp +++ b/data_object/frameworks/innerkitsimpl/src/communicator/softbus_adapter_standard.cpp @@ -14,12 +14,12 @@ */ #include - #include #include #include "dev_manager.h" #include "dms_handler.h" +#include "anonymous.h" #include "kv_store_delegate_manager.h" #include "process_communicator_impl.h" #include "securec.h" @@ -35,13 +35,8 @@ constexpr int32_t MIN_SIZE = HEAD_SIZE + END_SIZE + 3; constexpr const char *REPLACE_CHAIN = "***"; constexpr const char *DEFAULT_ANONYMOUS = "******"; constexpr int32_t SOFTBUS_OK = 0; -constexpr int32_t SOFTBUS_ERR = 1; -constexpr int32_t INVALID_SESSION_ID = -1; -constexpr int32_t SESSION_NAME_SIZE_MAX = 65; -constexpr int32_t DEVICE_ID_SIZE_MAX = 65; +constexpr int32_t INVALID_SOCKET_ID = 0; constexpr size_t TASK_CAPACITY_MAX = 15; -constexpr int32_t SELF_SIDE = 1; - using namespace std; SoftBusAdapter *AppDataListenerWrap::softBusAdapter_; std::shared_ptr SoftBusAdapter::instance_; @@ -52,10 +47,14 @@ SoftBusAdapter::SoftBusAdapter() taskQueue_ = std::make_shared(TASK_CAPACITY_MAX, "data_object"); AppDataListenerWrap::SetDataHandler(this); - sessionListener_.OnSessionOpened = AppDataListenerWrap::OnSessionOpened; - sessionListener_.OnSessionClosed = AppDataListenerWrap::OnSessionClosed; - sessionListener_.OnBytesReceived = AppDataListenerWrap::OnBytesReceived; - sessionListener_.OnMessageReceived = AppDataListenerWrap::OnMessageReceived; + clientListener_.OnShutdown = AppDataListenerWrap::OnClientShutdown; + clientListener_.OnBytes = AppDataListenerWrap::OnClientBytesReceived; + clientListener_.OnMessage = AppDataListenerWrap::OnClientBytesReceived; + + serverListener_.OnBind = AppDataListenerWrap::OnServerBind; + serverListener_.OnShutdown = AppDataListenerWrap::OnServerShutdown; + serverListener_.OnBytes = AppDataListenerWrap::OnServerBytesReceived; + serverListener_.OnMessage = AppDataListenerWrap::OnServerBytesReceived; } SoftBusAdapter::~SoftBusAdapter() @@ -65,7 +64,7 @@ SoftBusAdapter::~SoftBusAdapter() taskQueue_ = nullptr; } dataCaches_.clear(); - sessionIds_.clear(); + sockets_.clear(); } Status SoftBusAdapter::StartWatchDeviceChange( @@ -155,43 +154,33 @@ void SoftBusAdapter::NotifyAll(const DeviceInfo &deviceInfo, const DeviceChangeT std::vector SoftBusAdapter::GetDeviceList() const { - DistributedSchedule::ContinueInfo continueInfo; - int32_t result = DistributedSchedule::DmsHandler::GetInstance().GetContinueInfo(continueInfo); - if (result != 0) { - LOG_ERROR("GetContinueInfo failed, error code: %{public}d", result); - } - if (!continueInfo.srcNetworkId_.empty() && !continueInfo.dstNetworkId_.empty()) { - DevManager::DetailInfo localDevice = DevManager::GetInstance()->GetLocalDevice(); - LOG_DEBUG("LocalNetworkId: %{public}s. srcNetworkId: %{public}s. dstNetworkId: %{public}s.", - ToBeAnonymous(localDevice.networkId).c_str(), ToBeAnonymous(continueInfo.srcNetworkId_).c_str(), - ToBeAnonymous(continueInfo.dstNetworkId_).c_str()); - if (localDevice.networkId == continueInfo.srcNetworkId_ - || localDevice.networkId == continueInfo.dstNetworkId_) { - LOG_INFO("Local device is continuing."); - return {}; + std::vector events; + int32_t res = DistributedSchedule::DmsHandler::GetInstance().GetDSchedEventInfo( + DistributedSchedule::DMS_COLLABORATION, events); + if (res != ERR_OK) { + LOG_ERROR("Get collaboration events failed, error code = %{public}d", res); + return {}; + } + DevManager::DetailInfo localDevice = DevManager::GetInstance()->GetLocalDevice(); + std::set remoteDevices; + for (const auto &event : events) { + if (localDevice.networkId == event.srcNetworkId_) { + std::string uuid = DevManager::GetInstance()->GetUuidByNodeId(event.dstNetworkId_); + remoteDevices.insert(uuid); + } else if (localDevice.networkId == event.dstNetworkId_) { + std::string uuid = DevManager::GetInstance()->GetUuidByNodeId(event.srcNetworkId_); + remoteDevices.insert(uuid); } + LOG_DEBUG("Collaboration evnet, srcNetworkId: %{public}s, dstNetworkId: %{public}s", + Anonymous::Change(event.srcNetworkId_).c_str(), Anonymous::Change(event.dstNetworkId_).c_str()); } - std::vector dis; - NodeBasicInfo *info = nullptr; - int32_t infoNum = 0; - dis.clear(); - - int32_t ret = GetAllNodeDeviceInfo("ohos.objectstore", &info, &infoNum); - if (ret != SOFTBUS_OK) { - LOG_ERROR("GetAllNodeDeviceInfo error"); - return dis; - } - LOG_DEBUG("GetAllNodeDeviceInfo success infoNum=%{public}d", infoNum); - - for (int i = 0; i < infoNum; i++) { - std::string uuid = DevManager::GetInstance()->GetUuidByNodeId(std::string(info[i].networkId)); - DeviceInfo deviceInfo = { uuid, std::string(info[i].deviceName), std::to_string(info[i].deviceTypeId) }; - dis.push_back(deviceInfo); - } - if (info != nullptr) { - FreeNodeInfo(info); + std::vector deviceInfos; + for (const auto &deviceId : remoteDevices) { + DeviceInfo deviceInfo{ deviceId }; + deviceInfos.push_back(deviceInfo); } - return dis; + LOG_INFO("Collaboration deivces size:%{public}zu", deviceInfos.size()); + return deviceInfos; } DeviceInfo SoftBusAdapter::GetLocalDevice() @@ -292,8 +281,6 @@ std::string SoftBusAdapter::ToNodeID(const std::string &nodeId) const } } } - - LOG_WARN("get the network id from devices."); std::vector devices; NodeBasicInfo *info = nullptr; int32_t infoNum = 0; @@ -367,42 +354,20 @@ Status SoftBusAdapter::StopWatchDataChange( return Status::ERROR; } -RecOperate SoftBusAdapter::CalcRecOperate(uint32_t dataSize, RouteType currentRouteType, bool &isP2P) const +Status SoftBusAdapter::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, + uint32_t totalLength, const MessageInfo &info) { - if (currentRouteType == RouteType::WIFI_STA) { - return KEEP; - } - if (currentRouteType == RouteType::INVALID_ROUTE_TYPE || currentRouteType == BT_BR || currentRouteType == BT_BLE) { - if (dataSize > P2P_SIZE_THRESHOLD) { - isP2P = true; - return CHANGE_TO_P2P; - } - } - if (currentRouteType == WIFI_P2P) { - if (dataSize < P2P_SIZE_THRESHOLD * SWITCH_DELAY_FACTOR) { - return CHANGE_TO_BLUETOOTH; - } - isP2P = true; + lock_guard lock(sendDataMutex_); + auto result = CacheData(deviceId.deviceId, dataInfo); + if (result != Status::SUCCESS) { + return result; } - return KEEP; -} - -SessionAttribute SoftBusAdapter::GetSessionAttribute(bool isP2P) -{ - SessionAttribute attr; - attr.dataType = TYPE_BYTES; - // If the dataType is BYTES, the default strategy is wifi_5G > wifi_2.4G > BR, without P2P; - if (!isP2P) { - return attr; + int clientSocket = GetSocket(pipeInfo, deviceId); + if (clientSocket == INVALID_SOCKET_ID) { + return Status::ERROR; } - - int index = 0; - attr.linkType[index++] = LINK_TYPE_WIFI_WLAN_5G; - attr.linkType[index++] = LINK_TYPE_WIFI_WLAN_2G; - attr.linkType[index++] = LINK_TYPE_WIFI_P2P; - attr.linkType[index++] = LINK_TYPE_BR; - attr.linkTypeNum = index; - return attr; + DoSend(); + return Status::SUCCESS; } Status SoftBusAdapter::CacheData(const std::string &deviceId, const DataInfo &dataInfo) @@ -431,69 +396,53 @@ Status SoftBusAdapter::CacheData(const std::string &deviceId, const DataInfo &da return Status::SUCCESS; } -uint32_t SoftBusAdapter::GetSize(const std::string &deviceId) +int SoftBusAdapter::GetSocket(const PipeInfo &pipeInfo, const DeviceId &deviceId) { - uint32_t dataSize = 0; - lock_guard lock(deviceDataLock_); - auto it = dataCaches_.find(deviceId); - if (it == dataCaches_.end() || it->second.empty()) { - return dataSize; - } - for (const auto &msg : it->second) { - dataSize += msg.size; - } - return dataSize; -} - -RouteType SoftBusAdapter::GetRouteType(int sessionId) -{ - RouteType routeType = RouteType::INVALID_ROUTE_TYPE; - int ret = GetSessionOption(sessionId, SESSION_OPTION_LINK_TYPE, &routeType, sizeof(routeType)); - if (ret != SOFTBUS_OK) { - LOG_ERROR("getSessionOption failed, ret is %{public}d.", ret); - } - return routeType; -} - -Status SoftBusAdapter::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, - uint32_t totalLength, const MessageInfo &info) -{ - lock_guard lock(sendDataMutex_); - auto result = CacheData(deviceId.deviceId, dataInfo); - if (result != Status::SUCCESS) { - return result; - } - uint32_t dataSize = GetSize(deviceId.deviceId) + totalLength; - int sessionId = GetSessionId(deviceId.deviceId); - bool isP2P = false; - RouteType currentRouteType = GetRouteType(sessionId); - RecOperate recOperate = CalcRecOperate(dataSize, currentRouteType, isP2P); - if (recOperate != KEEP && sessionId != INVALID_SESSION_ID) { - LOG_INFO("close session : %{public}d, currentRouteType : %{public}d, recOperate : %{public}d", sessionId, - currentRouteType, recOperate); - CloseSession(sessionId); - } - SessionAttribute attr = GetSessionAttribute(isP2P); - OpenSession(pipeInfo.pipeId.c_str(), pipeInfo.pipeId.c_str(), ToNodeID(deviceId.deviceId).c_str(), - "GROUP_ID", &attr); - return Status::SUCCESS; -} - -void SoftBusAdapter::CacheSession(int32_t sessionId) -{ - std::string deviceId; - if (GetDeviceId(sessionId, deviceId) == SOFTBUS_OK) { - lock_guard lock(deviceSessionLock_); - sessionIds_[deviceId] = sessionId; + lock_guard lock(socketLock_); + auto it = sockets_.find(deviceId.deviceId); + if (it != sockets_.end()) { + return it->second; } + int socketId = CreateClientSocket(pipeInfo, deviceId); + if (socketId == INVALID_SOCKET_ID) { + return INVALID_SOCKET_ID; + } + sockets_[deviceId.deviceId] = socketId; + return socketId; +} + +int SoftBusAdapter::CreateClientSocket(const PipeInfo &pipeInfo, const DeviceId &deviceId) +{ + SocketInfo socketInfo; + socketInfo.name = const_cast(pipeInfo.pipeId.c_str()); + socketInfo.peerName = const_cast(pipeInfo.pipeId.c_str()); + std::string networkId = ToNodeID(deviceId.deviceId); + socketInfo.peerNetworkId = const_cast(networkId.c_str()); + + std::string pkgName = "ohos.objectstore"; + socketInfo.pkgName = pkgName.data(); + socketInfo.dataType = DATA_TYPE_BYTES; + int socketId = Socket(socketInfo); + if (socketId <= 0) { + LOG_ERROR("Create socket failed, error code: %{public}d, name:%{public}s", socketId, socketInfo.name); + return INVALID_SOCKET_ID; + } + int32_t res = Bind(socketId, Qos, QOS_COUNT, &clientListener_); + if (res != 0) { + LOG_ERROR("Bind failed, error code: %{public}d, peerName: %{public}s, peerNetworkId: %{public}s", + res, socketInfo.peerName, Anonymous::Change(networkId).c_str()); + Shutdown(socketId); + return INVALID_SOCKET_ID; + } + return socketId; } void SoftBusAdapter::DoSend() { auto task([this]() { - lock_guard lockSession(deviceSessionLock_); - for (auto &it : sessionIds_) { - if (it.second == INVALID_SESSION_ID) { + lock_guard lock(socketLock_); + for (auto &it : sockets_) { + if (it.second <= INVALID_SOCKET_ID) { continue; } lock_guard lock(deviceDataLock_); @@ -516,121 +465,54 @@ void SoftBusAdapter::DoSend() taskQueue_->Execute(std::move(task)); } -int SoftBusAdapter::GetDeviceId(int sessionId, std::string &deviceId) -{ - char peerDevId[DEVICE_ID_SIZE_MAX] = ""; - int ret = GetPeerDeviceId(sessionId, peerDevId, sizeof(peerDevId)); - if (ret != SOFTBUS_OK) { - LOG_ERROR("get peerDeviceId failed, sessionId :%{public}d", sessionId); - return ret; - } - lock_guard lock(networkMutex_); - auto it = networkId2Uuid_.find(std::string(peerDevId)); - if (it != networkId2Uuid_.end()) { - deviceId = it->second; - } - return ret; -} - -int SoftBusAdapter::GetSessionId(const std::string &deviceId) -{ - lock_guard lock(deviceSessionLock_); - auto it = sessionIds_.find(deviceId); - if (it != sessionIds_.end()) { - return it->second; - } - return INVALID_SESSION_ID; -} - -void SoftBusAdapter::OnSessionOpen(int32_t sessionId, int32_t status) -{ - if (status != SOFTBUS_OK) { - LOG_DEBUG("[OnSessionOpen] OpenSession failed"); - return; - } - if (GetSessionSide(sessionId) != SELF_SIDE) { - return; - } - CacheSession(sessionId); - DoSend(); -} - -void SoftBusAdapter::OnSessionClose(int32_t sessionId) +void SoftBusAdapter::OnClientShutdown(int32_t socket) { - std::string deviceId; - if (GetSessionSide(sessionId) != SELF_SIDE) { - return; - } - if (GetDeviceId(sessionId, deviceId) == SOFTBUS_OK) { - lock_guard lock(deviceSessionLock_); - if (sessionIds_.find(deviceId) != sessionIds_.end()) { - sessionIds_.erase(deviceId); + lock_guard lock(socketLock_); + for (auto iter = sockets_.begin(); iter != sockets_.end();) { + if (iter->second == socket) { + iter = sockets_.erase(iter); + } else { + iter++; } } - DoSend(); } bool SoftBusAdapter::IsSameStartedOnPeer( const struct PipeInfo &pipeInfo, __attribute__((unused)) const struct DeviceId &peer) { - LOG_INFO( - "pipeInfo:%{public}s peer.deviceId:%{public}s", pipeInfo.pipeId.c_str(), ToBeAnonymous(peer.deviceId).c_str()); - { - lock_guard lock(busSessionMutex_); - if (busSessionMap_.find(pipeInfo.pipeId + peer.deviceId) != busSessionMap_.end()) { - LOG_INFO("Found session in map. Return true."); - return true; - } - } - SessionAttribute attr; - attr.dataType = TYPE_BYTES; - int sessionId = OpenSession( - pipeInfo.pipeId.c_str(), pipeInfo.pipeId.c_str(), ToNodeID(peer.deviceId).c_str(), "GROUP_ID", &attr); - LOG_INFO("[IsSameStartedOnPeer] sessionId=%{public}d", sessionId); - if (sessionId == INVALID_SESSION_ID) { - LOG_ERROR("OpenSession return null, pipeInfo:%{public}s. Return false.", pipeInfo.pipeId.c_str()); - return false; - } - LOG_INFO("session started, pipeInfo:%{public}s. sessionId:%{public}d Return " - "true. ", - pipeInfo.pipeId.c_str(), sessionId); - return true; -} - -void SoftBusAdapter::SetMessageTransFlag(const PipeInfo &pipeInfo, bool flag) -{ - LOG_INFO("pipeInfo: %{public}s flag: %{public}d", pipeInfo.pipeId.c_str(), static_cast(flag)); - flag_ = flag; + int socket = GetSocket(pipeInfo, peer); + return socket != INVALID_SOCKET_ID; } int SoftBusAdapter::CreateSessionServerAdapter(const std::string &sessionName) { - LOG_DEBUG("begin"); - return CreateSessionServer("ohos.objectstore", sessionName.c_str(), &sessionListener_); + SocketInfo socketInfo; + socketInfo.name = const_cast(sessionName.c_str()); + std::string pkgName = "ohos.objectstore"; + socketInfo.pkgName = pkgName.data(); + socketServer_ = Socket(socketInfo); + if (socketServer_ <= 0) { + LOG_ERROR("Create socket failed, error code: %{public}d, name:%{public}s", socketServer_, socketInfo.name); + return static_cast(Status::ERROR); + } + int res = Listen(socketServer_, Qos, QOS_COUNT, &serverListener_); + if (res != SOFTBUS_OK) { + LOG_ERROR("Listen socket failed, error code: %{public}d, socket:%{public}d", res, socketServer_); + return static_cast(Status::ERROR); + } + return SOFTBUS_OK; } int SoftBusAdapter::RemoveSessionServerAdapter(const std::string &sessionName) const { - LOG_DEBUG("begin"); - return RemoveSessionServer("ohos.objectstore", sessionName.c_str()); -} - -void SoftBusAdapter::InsertSession(const std::string &sessionName) -{ - lock_guard lock(busSessionMutex_); - busSessionMap_.insert({ sessionName, true }); -} - -void SoftBusAdapter::DeleteSession(const std::string &sessionName) -{ - lock_guard lock(busSessionMutex_); - busSessionMap_.erase(sessionName); + Shutdown(socketServer_); + LOG_INFO("Shutdown server socket: %{public}d", socketServer_); + return 0; } void SoftBusAdapter::NotifyDataListeners( const uint8_t *ptr, const int size, const std::string &deviceId, const PipeInfo &pipeInfo) { - LOG_DEBUG("begin"); lock_guard lock(dataChangeMutex_); auto it = dataChangeListeners_.find(pipeInfo.pipeId); if (it != dataChangeListeners_.end()) { @@ -643,138 +525,69 @@ void SoftBusAdapter::NotifyDataListeners( LOG_WARN("no listener %{public}s.", pipeInfo.pipeId.c_str()); } -void AppDataListenerWrap::SetDataHandler(SoftBusAdapter *handler) +bool SoftBusAdapter::GetPeerSocketInfo(int32_t socket, PeerSocketInfo &info) { - LOG_INFO("begin"); - softBusAdapter_ = handler; + auto it = peerSocketInfos_.Find(socket); + if (it.first) { + info = it.second; + return true; + } + return false; } -int AppDataListenerWrap::OnSessionOpened(int sessionId, int result) +void SoftBusAdapter::OnBind(int32_t socket, PeerSocketInfo info) { - LOG_DEBUG("[SessionOpen] sessionId:%{public}d, result:%{public}d", sessionId, result); - char mySessionName[SESSION_NAME_SIZE_MAX] = ""; - char peerSessionName[SESSION_NAME_SIZE_MAX] = ""; - char peerDevId[DEVICE_ID_SIZE_MAX] = ""; - softBusAdapter_->OnSessionOpen(sessionId, result); - if (result != SOFTBUS_OK) { - LOG_WARN("session %{public}d open failed, result:%{public}d.", sessionId, result); - return result; - } - int ret = GetMySessionName(sessionId, mySessionName, sizeof(mySessionName)); - if (ret != SOFTBUS_OK) { - LOG_WARN("get my session name failed, session id is %{public}d.", sessionId); - return SOFTBUS_ERR; - } - ret = GetPeerSessionName(sessionId, peerSessionName, sizeof(peerSessionName)); - if (ret != SOFTBUS_OK) { - LOG_WARN("get my peer session name failed, session id is %{public}d.", sessionId); - return SOFTBUS_ERR; - } - ret = GetPeerDeviceId(sessionId, peerDevId, sizeof(peerDevId)); - if (ret != SOFTBUS_OK) { - LOG_WARN("get my peer device id failed, session id is %{public}d.", sessionId); - return SOFTBUS_ERR; - } - std::string peerUuid = DevManager::GetInstance()->GetUuidByNodeId(std::string(peerDevId)); - LOG_DEBUG("[SessionOpen] mySessionName:%{public}s, " - "peerSessionName:%{public}s, peerDevId:%{public}s", - mySessionName, peerSessionName, SoftBusAdapter::ToBeAnonymous(peerUuid).c_str()); + peerSocketInfos_.Insert(socket, info); +} - if (strlen(peerSessionName) < 1) { - softBusAdapter_->InsertSession(std::string(mySessionName) + peerUuid); - } else { - softBusAdapter_->InsertSession(std::string(peerSessionName) + peerUuid); - } - return 0; +void SoftBusAdapter::OnServerShutdown(int32_t socket) +{ + peerSocketInfos_.Erase(socket); } -void AppDataListenerWrap::OnSessionClosed(int sessionId) +void AppDataListenerWrap::SetDataHandler(SoftBusAdapter *handler) { - LOG_INFO("[SessionClosed] sessionId:%{public}d", sessionId); - char mySessionName[SESSION_NAME_SIZE_MAX] = ""; - char peerSessionName[SESSION_NAME_SIZE_MAX] = ""; - char peerDevId[DEVICE_ID_SIZE_MAX] = ""; + softBusAdapter_ = handler; +} - softBusAdapter_->OnSessionClose(sessionId); - int ret = GetMySessionName(sessionId, mySessionName, sizeof(mySessionName)); - if (ret != SOFTBUS_OK) { - LOG_WARN("get my session name failed, session id is %{public}d.", sessionId); - return; - } - ret = GetPeerSessionName(sessionId, peerSessionName, sizeof(peerSessionName)); - if (ret != SOFTBUS_OK) { - LOG_WARN("get my peer session name failed, session id is %{public}d.", sessionId); - return; - } - ret = GetPeerDeviceId(sessionId, peerDevId, sizeof(peerDevId)); - if (ret != SOFTBUS_OK) { - LOG_WARN("get my peer device id failed, session id is %{public}d.", sessionId); - return; - } - std::string peerUuid = DevManager::GetInstance()->GetUuidByNodeId(std::string(peerDevId)); - LOG_DEBUG("[SessionClosed] mySessionName:%{public}s, " - "peerSessionName:%{public}s, peerDevId:%{public}s", - mySessionName, peerSessionName, SoftBusAdapter::ToBeAnonymous(peerUuid).c_str()); - if (strlen(peerSessionName) < 1) { - softBusAdapter_->DeleteSession(std::string(mySessionName) + peerUuid); - } else { - softBusAdapter_->DeleteSession(std::string(peerSessionName) + peerUuid); - } +void AppDataListenerWrap::OnClientShutdown(int32_t socket, ShutdownReason reason) +{ + softBusAdapter_->OnClientShutdown(socket); + LOG_INFO("Client socket shutdown, socket: %{public}d, reason: %{public}d", socket, reason); } -void AppDataListenerWrap::OnMessageReceived(int sessionId, const void *data, unsigned int dataLen) +void AppDataListenerWrap::OnClientBytesReceived(int32_t socket, const void *data, uint32_t dataLen) {} + +void AppDataListenerWrap::OnServerBind(int32_t socket, PeerSocketInfo info) { - LOG_INFO("begin"); - if (sessionId == INVALID_SESSION_ID) { - return; - } - char peerSessionName[SESSION_NAME_SIZE_MAX] = ""; - char peerDevId[DEVICE_ID_SIZE_MAX] = ""; - int ret = GetPeerSessionName(sessionId, peerSessionName, sizeof(peerSessionName)); - if (ret != SOFTBUS_OK) { - LOG_WARN("get my peer session name failed, session id is %{public}d.", sessionId); - return; - } - ret = GetPeerDeviceId(sessionId, peerDevId, sizeof(peerDevId)); - if (ret != SOFTBUS_OK) { - LOG_WARN("get my peer device id failed, session id is %{public}d.", sessionId); - return; - } - std::string peerUuid = DevManager::GetInstance()->GetUuidByNodeId(std::string(peerDevId)); - LOG_DEBUG("[MessageReceived] session id:%{public}d, " - "peerSessionName:%{public}s, peerDevId:%{public}s", - sessionId, peerSessionName, SoftBusAdapter::ToBeAnonymous(peerUuid).c_str()); - NotifyDataListeners(reinterpret_cast(data), dataLen, peerUuid, { std::string(peerSessionName) }); + softBusAdapter_->OnBind(socket, info); + LOG_INFO("Server on bind, socket: %{public}d, peer networkId: %{public}s", socket, + SoftBusAdapter::ToBeAnonymous(info.networkId).c_str()); } -void AppDataListenerWrap::OnBytesReceived(int sessionId, const void *data, unsigned int dataLen) +void AppDataListenerWrap::OnServerShutdown(int32_t socket, ShutdownReason reason) { - if (sessionId == INVALID_SESSION_ID) { - return; - } - char peerSessionName[SESSION_NAME_SIZE_MAX] = ""; - char peerDevId[DEVICE_ID_SIZE_MAX] = ""; - int ret = GetPeerSessionName(sessionId, peerSessionName, sizeof(peerSessionName)); - if (ret != SOFTBUS_OK) { - LOG_WARN("get my peer session name failed, session id is %{public}d.", sessionId); - return; - } - ret = GetPeerDeviceId(sessionId, peerDevId, sizeof(peerDevId)); - if (ret != SOFTBUS_OK) { - LOG_WARN("get my peer device id failed, session id is %{public}d.", sessionId); + softBusAdapter_->OnServerShutdown(socket); + LOG_INFO("Server socket shutdown, socket: %{public}d, reason: %{public}d", socket, reason); +} + +void AppDataListenerWrap::OnServerBytesReceived(int32_t socket, const void *data, uint32_t dataLen) +{ + PeerSocketInfo info; + if (!softBusAdapter_->GetPeerSocketInfo(socket, info)) { + LOG_ERROR("Get peer socket info failed, socket: %{public}d", socket); return; - } - std::string peerUuid = DevManager::GetInstance()->GetUuidByNodeId(std::string(peerDevId)); - LOG_DEBUG("[BytesReceived] session id:%{public}d, peerSessionName:%{public}s, " - "peerDevId:%{public}s", - sessionId, peerSessionName, SoftBusAdapter::ToBeAnonymous(peerUuid).c_str()); - NotifyDataListeners(reinterpret_cast(data), dataLen, peerUuid, { std::string(peerSessionName) }); + }; + LOG_DEBUG("Server receive bytes, socket: %{public}d, networkId: %{public}s, dataLen: %{public}u", socket, + Anonymous::Change(info.networkId).c_str(), dataLen); + std::string peerDevUuid = DevManager::GetInstance()->GetUuidByNodeId(std::string(info.networkId)); + NotifyDataListeners(reinterpret_cast(data), dataLen, peerDevUuid, { info.name }); } -void AppDataListenerWrap::NotifyDataListeners( - const uint8_t *ptr, const int size, const std::string &deviceId, const PipeInfo &pipeInfo) +void AppDataListenerWrap::NotifyDataListeners(const uint8_t *ptr, const int size, const std::string &deviceId, + const PipeInfo &pipeInfo) { - return softBusAdapter_->NotifyDataListeners(ptr, size, deviceId, pipeInfo); + softBusAdapter_->NotifyDataListeners(ptr, size, deviceId, pipeInfo); } } // namespace ObjectStore } // namespace OHOS diff --git a/data_object/frameworks/innerkitsimpl/src/object_callback_stub.cpp b/data_object/frameworks/innerkitsimpl/src/object_callback_stub.cpp index 4fc7cac8..0acee40b 100644 --- a/data_object/frameworks/innerkitsimpl/src/object_callback_stub.cpp +++ b/data_object/frameworks/innerkitsimpl/src/object_callback_stub.cpp @@ -78,11 +78,12 @@ int ObjectRetrieveCallbackStub::OnRemoteRequest( } if (code == COMPLETED) { std::map> results; - if (!ITypesUtil::Unmarshal(data, results)) { + bool allReady; + if (!ITypesUtil::Unmarshal(data, results, allReady)) { ZLOGE("write descriptor failed"); return -1; } - Completed(results); + Completed(results, allReady); return 0; } return IPCObjectStub::OnRemoteRequest(code, data, reply, option); @@ -100,11 +101,12 @@ int ObjectChangeCallbackStub::OnRemoteRequest( } if (code == COMPLETED) { std::map> results; - if (!ITypesUtil::Unmarshal(data, results)) { + bool allReady; + if (!ITypesUtil::Unmarshal(data, results, allReady)) { ZLOGE("write descriptor failed"); return -1; } - Completed(results); + Completed(results, allReady); return 0; } return IPCObjectStub::OnRemoteRequest(code, data, reply, option); diff --git a/data_object/frameworks/innerkitsimpl/test/unittest/mock/src/mock_soft_bus.cpp b/data_object/frameworks/innerkitsimpl/test/unittest/mock/src/mock_soft_bus.cpp index e599f843..6fe83b9b 100644 --- a/data_object/frameworks/innerkitsimpl/test/unittest/mock/src/mock_soft_bus.cpp +++ b/data_object/frameworks/innerkitsimpl/test/unittest/mock/src/mock_soft_bus.cpp @@ -18,6 +18,7 @@ #include #include +#include "socket.h" #include "softbus_bus_center.h" static std::map> sessionListeners; @@ -89,4 +90,29 @@ int CreateSessionServer(const char *pkgName, const char *sessionName, const ISes return -1; } return 0; +} + +int Socket(SocketInfo info) +{ + const char *invalidSessionName = "INVALID_SESSION_NAME"; + if (!strcmp(info.name, invalidSessionName)) { + return 0; + } + return 1; +} + +int Listen(int32_t socket, const QosTV *qos, uint32_t qosCount, const ISocketListener *listener) +{ + if (socket <= 0) { + return -1; + } + return 0; +} + +int Bind(int32_t socket, const QosTV *qos, uint32_t qosCount, const ISocketListener *listener) +{ + if (socket <= 0) { + return -1; + } + return 0; } \ No newline at end of file diff --git a/data_object/frameworks/innerkitsimpl/test/unittest/src/app_pipe_mgr_test.cpp b/data_object/frameworks/innerkitsimpl/test/unittest/src/app_pipe_mgr_test.cpp index c5dbfcbe..d4073f50 100644 --- a/data_object/frameworks/innerkitsimpl/test/unittest/src/app_pipe_mgr_test.cpp +++ b/data_object/frameworks/innerkitsimpl/test/unittest/src/app_pipe_mgr_test.cpp @@ -243,7 +243,7 @@ HWTEST_F(NativeAppPipeMgrTest, NativeAppPipeMgrTest_Stop_002, TestSize.Level1) auto ret = appPipeMgr->Start(pipeInfo); EXPECT_EQ(Status::SUCCESS, ret); ret = appPipeMgr->Stop(pipeInfo); - EXPECT_EQ(Status::ERROR, ret); + EXPECT_EQ(Status::SUCCESS, ret); } /** @@ -369,6 +369,6 @@ HWTEST_F(NativeAppPipeMgrTest, NativeAppPipeMgrTest_IsSameStartedOnPeer_003, Tes AppPipeMgr appPipeMgr; appPipeMgr.Start(pipeInfo); auto ret = appPipeMgr.IsSameStartedOnPeer(pipeInfo, deviceId); - EXPECT_EQ(false, ret); + EXPECT_EQ(true, ret); } } // namespace diff --git a/data_object/frameworks/innerkitsimpl/test/unittest/src/communicator_test.cpp b/data_object/frameworks/innerkitsimpl/test/unittest/src/communicator_test.cpp index 94c9f160..31fbf902 100644 --- a/data_object/frameworks/innerkitsimpl/test/unittest/src/communicator_test.cpp +++ b/data_object/frameworks/innerkitsimpl/test/unittest/src/communicator_test.cpp @@ -231,24 +231,7 @@ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_IsSameStartedOnPeer_001, TestSiz DeviceId deviceId = { "deviceId01" }; SoftBusAdapter softBusAdapter; auto ret = softBusAdapter.IsSameStartedOnPeer(pipeInfo, deviceId); - EXPECT_EQ(false, ret); -} - -/** - * @tc.name: SoftBusAdapter_IsSameStartedOnPeer_002 - * @tc.desc: test SoftBusAdapter IsSameStartedOnPeer. - * @tc.type: FUNC - */ -HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_IsSameStartedOnPeer_002, TestSize.Level1) -{ - PipeInfo pipeInfo = { "pipInfo002" }; - DeviceId deviceId = { "deviceId02" }; - SoftBusAdapter softBusAdapter; - std::string sessionName = "pipInfo002deviceId02"; - softBusAdapter.InsertSession(sessionName); - auto ret = softBusAdapter.IsSameStartedOnPeer(pipeInfo, deviceId); EXPECT_EQ(true, ret); - softBusAdapter.DeleteSession(sessionName); } /** @@ -480,7 +463,7 @@ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_GetDeviceList_001, TestSize.Leve { SoftBusAdapter softBusAdapter; auto ret = softBusAdapter.GetDeviceList(); - EXPECT_EQ(false, ret.empty()); + EXPECT_EQ(true, ret.empty()); } /** @@ -504,7 +487,7 @@ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_GetLocalDevice_001, TestSize.Lev */ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_SendData_001, TestSize.Level1) { - PipeInfo pipeInfo = {}; + PipeInfo pipeInfo = {"INVALID_SESSION_NAME"}; DeviceId deviceId = {"devideId01"}; uint32_t size = 1; uint8_t tmpNum = 1; @@ -513,74 +496,52 @@ HWTEST_F(NativeCommunicatorTest, SoftBusAdapter_SendData_001, TestSize.Level1) MessageInfo messageInfo = {MessageType::DEFAULT}; SoftBusAdapter softBusAdapter; auto ret = softBusAdapter.SendData(pipeInfo, deviceId, dataInfo, size, messageInfo); - EXPECT_EQ(Status::SUCCESS, ret); -} - -/** - * @tc.name: AppDataListenerWrap_OnSessionOpened_001 - * @tc.desc: test AppDataListenerWrap OnSessionOpened. - * @tc.type: FUNC - */ -HWTEST_F(NativeCommunicatorTest, AppDataListenerWrap_OnSessionOpened_001, TestSize.Level1) -{ - int sessionId = 1; - int result = 0; - AppDataListenerWrap::SetDataHandler(&softBusAdapter_); - auto ret = AppDataListenerWrap::OnSessionOpened(sessionId, result); - EXPECT_EQ(0, ret); - AppDataListenerWrap::OnSessionClosed(sessionId); + EXPECT_EQ(Status::ERROR, ret); } /** - * @tc.name: AppDataListenerWrap_OnSessionOpened_002 - * @tc.desc: test AppDataListenerWrap OnSessionOpened. + * @tc.name: AppDataListenerWrap_OnServerBind_001 + * @tc.desc: test AppDataListenerWrap OnServerBind. * @tc.type: FUNC */ -HWTEST_F(NativeCommunicatorTest, AppDataListenerWrap_OnSessionOpened_002, TestSize.Level1) +HWTEST_F(NativeCommunicatorTest, AppDataListenerWrap_OnServerBind_001, TestSize.Level1) { - int sessionId = 1; - int result = 1; AppDataListenerWrap::SetDataHandler(&softBusAdapter_); - auto ret = AppDataListenerWrap::OnSessionOpened(sessionId, result); - EXPECT_EQ(1, ret); - AppDataListenerWrap::OnSessionClosed(sessionId); -} - -/** - * @tc.name: AppDataListenerWrap_OnMessageReceived_001 - * @tc.desc: test AppDataListenerWrap OnMessageReceived. - * @tc.type: FUNC - */ -HWTEST_F(NativeCommunicatorTest, AppDataListenerWrap_OnMessageReceived_001, TestSize.Level1) -{ - PipeInfo pipeInfo = { "" }; + int32_t socket = 9999; + std::string name = "OnServiceBind_001"; + std::string networkId = "1234567890"; + std::string pkgName = "ohos.objectstore"; + PeerSocketInfo mockInfo = { + .name = name.data(), + .networkId = networkId.data(), + .pkgName = pkgName.data(), + .dataType = DATA_TYPE_BYTES + }; + AppDataListenerWrap::OnServerBind(socket, mockInfo); + PeerSocketInfo info; + auto ret = softBusAdapter_.GetPeerSocketInfo(socket, info); + EXPECT_TRUE(ret); + EXPECT_EQ(mockInfo.name, info.name); + AppDataListenerWrap::OnServerShutdown(socket, SHUTDOWN_REASON_LOCAL); + ret = softBusAdapter_.GetPeerSocketInfo(socket, info); + EXPECT_FALSE(ret); +} + +/** + * @tc.name: AppDataListenerWrap_OnServerBytesReceived_001 + * @tc.desc: test AppDataListenerWrap OnServerBytesReceived. + * @tc.type: FUNC + */ +HWTEST_F(NativeCommunicatorTest, AppDataListenerWrap_OnServerBytesReceived_001, TestSize.Level1) +{ + PipeInfo pipeInfo = { "OnServerBytesReceived_001" }; SoftBusAdapter softBusAdapter; MockAppDataChangeListener observer; auto ret = softBusAdapter.StartWatchDataChange(&observer, pipeInfo); EXPECT_EQ(Status::SUCCESS, ret); - int sessionId = 1; - AppDataListenerWrap::SetDataHandler(&softBusAdapter); - std::string data = "OnMessageReceived"; - AppDataListenerWrap::OnMessageReceived(sessionId, reinterpret_cast(data.c_str()), data.size()); - EXPECT_EQ(data, observer.data); -} - -/** - * @tc.name: AppDataListenerWrap_OnBytesReceived_001 - * @tc.desc: test AppDataListenerWrap OnBytesReceived. - * @tc.type: FUNC - */ -HWTEST_F(NativeCommunicatorTest, AppDataListenerWrap_OnBytesReceived_001, TestSize.Level1) -{ - PipeInfo pipeInfo = { "" }; - SoftBusAdapter softBusAdapter; - MockAppDataChangeListener observer; - auto ret = softBusAdapter.StartWatchDataChange(&observer, pipeInfo); - EXPECT_EQ(Status::SUCCESS, ret); - int sessionId = 1; - AppDataListenerWrap::SetDataHandler(&softBusAdapter); - std::string data = "OnBytesReceived"; - AppDataListenerWrap::OnBytesReceived(sessionId, reinterpret_cast(data.c_str()), data.size()); + int socket = 1; + std::string data = ""; + AppDataListenerWrap::OnServerBytesReceived(socket, reinterpret_cast(data.c_str()), data.size()); EXPECT_EQ(data, observer.data); } @@ -608,4 +569,4 @@ HWTEST_F(NativeCommunicatorTest, DevManager_GetLocalDevice_001, TestSize.Level1) DevManager::DetailInfo detailInfo = devManager->GetLocalDevice(); EXPECT_EQ(detailInfo.networkId, ""); } -} \ No newline at end of file +} 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 4b4d6a37..61cd98e1 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 @@ -26,7 +26,6 @@ #include "distributed_objectstore_impl.h" #include "flat_object_storage_engine.h" #include "flat_object_store.h" -#include "hilog/log.h" #include "ipc_skeleton.h" #include "kv_store_delegate_manager.h" #include "mock_flat_object_watcher.h" @@ -40,10 +39,8 @@ using namespace testing::ext; using namespace OHOS::ObjectStore; using namespace OHOS::Security::AccessToken; -using namespace OHOS::HiviewDFX; namespace { constexpr static double SALARY = 100.5; -constexpr HiLogLabel LABEL = { LOG_CORE, 0, "DistributedTest" }; class TableWatcherImpl : public TableWatcher { public: explicit TableWatcherImpl(const std::string &sessionId) : TableWatcher(sessionId) {} @@ -1106,33 +1103,6 @@ HWTEST_F(NativeObjectStoreTest, FlatObjectStore_CheckRetrieveCache_001, TestSize EXPECT_EQ(SUCCESS, ret); } -/** - * @tc.name: FlatObjectStore_SyncAllData_001 - * @tc.desc: test FlatObjectStore SyncAllData. - * @tc.type: FUNC - */ -HWTEST_F(NativeObjectStoreTest, FlatObjectStore_SyncAllData_001, TestSize.Level1) -{ - std::string sessionId = "session258"; - std::string bundleName = "default07"; - std::shared_ptr flatObjectStore = std::make_shared(bundleName); - uint32_t ret = flatObjectStore->CreateObject(sessionId); - EXPECT_EQ(SUCCESS, ret); - auto onComplete = [sessionId](const std::map &devices) { - for (auto item : devices) { - (void)HILOG_IMPL(LABEL.type, LOG_INFO, LABEL.domain, LABEL.tag, - "%{public}s pull data result %{public}d in device %{public}s", - sessionId.c_str(), item.second, (item.first).c_str()); - } - }; - ret = flatObjectStore->SyncAllData(sessionId, onComplete); - EXPECT_EQ(SUCCESS, ret); - ret = flatObjectStore->SyncAllData("", onComplete); - EXPECT_EQ(ERR_DB_NOT_EXIST, ret); - ret = flatObjectStore->Delete(sessionId); - EXPECT_EQ(SUCCESS, ret); -} - /** * @tc.name: FlatObjectStore_Delete_001 * @tc.desc: test FlatObjectStore Delete. wrong sessionId @@ -1280,8 +1250,8 @@ HWTEST_F(NativeObjectStoreTest, CacheManager_ResumeObject_001, TestSize.Level1) std::string bundleName = ""; std::string sessionId = ""; CacheManager cacheManager; - std::function> &data)> callback = - [](const std::map> &data) {}; + std::function> &data, bool allReady)> callback = + [](const std::map> &data, bool allReady) {}; auto ret = cacheManager.ResumeObject(bundleName, sessionId, callback); EXPECT_EQ(DistributedDB::DBStatus::INVALID_ARGS, ret); } @@ -1296,8 +1266,8 @@ HWTEST_F(NativeObjectStoreTest, CacheManager_SubscribeDataChange_001, TestSize.L std::string bundleName = ""; std::string sessionId = ""; CacheManager cacheManager; - std::function> &data)> callback = - [](const std::map> &data) {}; + std::function> &data, bool allReady)> callback = + [](const std::map> &data, bool allReady) {}; auto ret = cacheManager.SubscribeDataChange(bundleName, sessionId, callback); EXPECT_EQ(DistributedDB::DBStatus::INVALID_ARGS, ret); } diff --git a/data_object/frameworks/jskitsimpl/include/adaptor/js_distributedobjectstore.h b/data_object/frameworks/jskitsimpl/include/adaptor/js_distributedobjectstore.h index d231d575..98afe9e0 100644 --- a/data_object/frameworks/jskitsimpl/include/adaptor/js_distributedobjectstore.h +++ b/data_object/frameworks/jskitsimpl/include/adaptor/js_distributedobjectstore.h @@ -41,7 +41,6 @@ private: const std::string &objectId, napi_value callback); static bool DelCallback(napi_env env, ConcurrentMap> &callbacks, const std::string &sessionId, napi_value callback = nullptr); - static bool CheckSyncPermission(); static void RestoreWatchers(napi_env env, JSObjectWrapper *wrapper, const std::string &objectId); static bool GetBundleNameWithContext(napi_env env, napi_value argv, std::string &bundleName); static std::string GetBundleName(napi_env env); diff --git a/data_object/frameworks/jskitsimpl/src/adaptor/js_distributedobjectstore.cpp b/data_object/frameworks/jskitsimpl/src/adaptor/js_distributedobjectstore.cpp index 7a06ac30..6af72368 100644 --- a/data_object/frameworks/jskitsimpl/src/adaptor/js_distributedobjectstore.cpp +++ b/data_object/frameworks/jskitsimpl/src/adaptor/js_distributedobjectstore.cpp @@ -169,9 +169,6 @@ napi_value JSDistributedObjectStore::JSCreateObjectSync(napi_env env, napi_callb std::make_shared("1 or 2")); NAPI_ASSERT_ERRCODE_V9(env, !IsSandBox(), version, innerError); LOG_INFO("start JSCreateObjectSync"); - NAPI_ASSERT_ERRCODE_V9(env, JSDistributedObjectStore::CheckSyncPermission(), version, - std::make_shared()); - status = JSUtil::GetValue(env, argv[1], sessionId); NAPI_ASSERT_ERRCODE_V9(env, status == napi_ok, version, std::make_shared("sessionId", "string")); @@ -493,18 +490,6 @@ napi_value JSDistributedObjectStore::JSEquenceNum(napi_env env, napi_callback_in return result; } -bool JSDistributedObjectStore::CheckSyncPermission() -{ - int32_t ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken( - AbilityRuntime::Context::GetApplicationContext()->GetApplicationInfo()->accessTokenId, DISTRIBUTED_DATASYNC); - if (ret == Security::AccessToken::PermissionState::PERMISSION_DENIED) { - LOG_ERROR("VerifyPermission %{public}d: PERMISSION_DENIED", - AbilityRuntime::Context::GetApplicationContext()->GetApplicationInfo()->accessTokenId); - return false; - } - return true; -} - // don't create distributed data object while this application is sandbox bool JSDistributedObjectStore::IsSandBox() { diff --git a/data_object/frameworks/jskitsimpl/src/adaptor/js_watcher.cpp b/data_object/frameworks/jskitsimpl/src/adaptor/js_watcher.cpp index e32d3a81..ee612ca0 100644 --- a/data_object/frameworks/jskitsimpl/src/adaptor/js_watcher.cpp +++ b/data_object/frameworks/jskitsimpl/src/adaptor/js_watcher.cpp @@ -17,6 +17,7 @@ #include +#include "anonymous.h" #include "js_common.h" #include "js_util.h" #include "logger.h" @@ -143,10 +144,10 @@ void JSWatcher::ProcessStatus(napi_env env, std::list &args) status = JSUtil::SetValue(env, statusArgs->status_, param[2]); NOT_MATCH_GOTO_ERROR(status == napi_ok); LOG_INFO("start %{public}s, %{public}s, %{public}s", statusArgs->sessionId_.c_str(), - statusArgs->networkId_.c_str(), statusArgs->status_.c_str()); + Anonymous::Change(statusArgs->networkId_).c_str(), statusArgs->status_.c_str()); status = napi_call_function(env, global, callback, ARGV_SIZE, param, &result); LOG_INFO("end %{public}s, %{public}s, %{public}s", statusArgs->sessionId_.c_str(), - statusArgs->networkId_.c_str(), statusArgs->status_.c_str()); + Anonymous::Change(statusArgs->networkId_).c_str(), statusArgs->status_.c_str()); NOT_MATCH_GOTO_ERROR(status == napi_ok); } ERROR: @@ -162,10 +163,10 @@ void JSWatcher::Emit( const char *type, const std::string &sessionId, const std::string &networkId, const std::string &status) { if (sessionId.empty() || networkId.empty()) { - LOG_ERROR("empty %{public}s %{public}s", sessionId.c_str(), networkId.c_str()); + LOG_ERROR("empty %{public}s %{public}s", sessionId.c_str(), Anonymous::Change(networkId).c_str()); return; } - LOG_ERROR("status change %{public}s %{public}s", sessionId.c_str(), networkId.c_str()); + LOG_INFO("status change %{public}s %{public}s", sessionId.c_str(), Anonymous::Change(networkId).c_str()); EventListener *listener = Find(type); if (listener == nullptr) { LOG_ERROR("error type %{public}s", type); diff --git a/data_object/frameworks/jskitsimpl/src/adaptor/notifier_impl.cpp b/data_object/frameworks/jskitsimpl/src/adaptor/notifier_impl.cpp index d52a6500..9b7f4f4a 100644 --- a/data_object/frameworks/jskitsimpl/src/adaptor/notifier_impl.cpp +++ b/data_object/frameworks/jskitsimpl/src/adaptor/notifier_impl.cpp @@ -15,6 +15,7 @@ #include "notifier_impl.h" +#include "anonymous.h" #include "logger.h" #include "objectstore_errors.h" @@ -53,17 +54,17 @@ void NotifierImpl::DelWatcher(std::string &sessionId) void NotifierImpl::OnChanged( const std::string &sessionId, const std::string &networkId, const std::string &onlineStatus) { - LOG_INFO( - "status changed %{public}s %{public}s %{public}s", sessionId.c_str(), networkId.c_str(), onlineStatus.c_str()); + LOG_INFO("status changed %{public}s %{public}s %{public}s", sessionId.c_str(), Anonymous::Change(networkId).c_str(), + onlineStatus.c_str()); std::lock_guard lock(mutex_); if (watchers_.count(sessionId) != 0) { - LOG_INFO( - "start emit %{public}s %{public}s %{public}s", sessionId.c_str(), networkId.c_str(), onlineStatus.c_str()); + LOG_INFO("start emit %{public}s %{public}s %{public}s", sessionId.c_str(), Anonymous::Change(networkId).c_str(), + onlineStatus.c_str()); std::shared_ptr lockedWatcher = watchers_.at(sessionId).lock(); if (lockedWatcher) { lockedWatcher->Emit("status", sessionId, networkId, onlineStatus); - LOG_INFO("end emit %{public}s %{public}s %{public}s", sessionId.c_str(), networkId.c_str(), - onlineStatus.c_str()); + LOG_INFO("end emit %{public}s %{public}s %{public}s", sessionId.c_str(), + Anonymous::Change(networkId).c_str(), onlineStatus.c_str()); } else { LOG_ERROR("watcher expired"); } diff --git a/data_object/interfaces/innerkits/BUILD.gn b/data_object/interfaces/innerkits/BUILD.gn index c6b0a712..f5b8ab1b 100644 --- a/data_object/interfaces/innerkits/BUILD.gn +++ b/data_object/interfaces/innerkits/BUILD.gn @@ -23,7 +23,6 @@ config("objectstore_config") { "../../frameworks/innerkitsimpl/include/communicator", "../../frameworks/innerkitsimpl/include", "../../interfaces/innerkits", - "${kvstore_path}/common", "${relational_store_path}/interfaces/inner_api/common_type/include", ] @@ -57,26 +56,28 @@ object_source_config = [ "../../frameworks/innerkitsimpl/src/object_service_proxy.cpp", "../../frameworks/innerkitsimpl/src/object_types_util.cpp", ] -object_deps_config = [ - "//third_party/bounds_checking_function:libsec_shared", - "//third_party/libuv:uv", -] +object_deps_config = [] object_external_deps_config = [ + "bounds_checking_function:libsec_shared", "c_utils:utils", "device_manager:devicemanagersdk", "dmsfwk:distributed_sdk", "dsoftbus:softbus_client", + "hisysevent:libhisysevent", "hitrace:hitrace_meter", "hitrace:libhitracechain", "hilog:libhilog", "ipc:ipc_core", "kv_store:distributeddata_inner", "kv_store:distributeddb", + "libuv:uv", "samgr:samgr_proxy", ] ohos_shared_library("distributeddataobject_impl") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false @@ -96,6 +97,8 @@ ohos_shared_library("distributeddataobject_impl") { ohos_static_library("distributeddataobject_static") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false diff --git a/data_object/interfaces/jskits/BUILD.gn b/data_object/interfaces/jskits/BUILD.gn index fc716832..64fdcd18 100644 --- a/data_object/interfaces/jskits/BUILD.gn +++ b/data_object/interfaces/jskits/BUILD.gn @@ -14,7 +14,6 @@ import("//arkcompiler/ets_frontend/es2panda/es2abc_config.gni") import("//build/ohos.gni") import("//build/ohos/ace/ace.gni") -import("//foundation/arkui/ace_engine/ace_config.gni") import("//foundation/distributeddatamgr/data_object/data_object.gni") group("build_module") { deps = [ ":distributeddataobject" ] @@ -43,7 +42,6 @@ config("objectstore_config") { "../../frameworks/innerkitsimpl/include", "../../frameworks/innerkitsimpl/include/communicator", "../../interfaces/innerkits", - "${kvstore_path}/common", "${relational_store_path}/interfaces/inner_api/common_type/include", ] } @@ -77,6 +75,8 @@ gen_js_obj("distributed_data_object_abc") { ohos_shared_library("distributeddataobject") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false @@ -102,17 +102,19 @@ ohos_shared_library("distributeddataobject") { ":distributed_data_object_abc", ":distributed_data_object_js", "//foundation/distributeddatamgr/data_object/interfaces/innerkits:distributeddataobject_impl", - "//third_party/bounds_checking_function:libsec_shared", - "//third_party/libuv:uv", ] external_deps = [ "ability_runtime:abilitykit_native", "ability_runtime:app_context", + "ability_runtime:extensionkit_native", "ability_runtime:napi_base_context", "access_token:libaccesstoken_sdk", + "bounds_checking_function:libsec_shared", "common_event_service:cesfwk_innerkits", "hilog:libhilog", + "kv_store:distributeddata_inner", "kv_store:distributeddb", + "libuv:uv", "napi:ace_napi", ] diff --git a/data_object/interfaces/jskits/distributed_data_object.js b/data_object/interfaces/jskits/distributed_data_object.js index c9a3d533..a7656331 100644 --- a/data_object/interfaces/jskits/distributed_data_object.js +++ b/data_object/interfaces/jskits/distributed_data_object.js @@ -174,20 +174,42 @@ function isAsset(obj) { if (Object.keys(obj).length !== length) { return false; } - if (Object.prototype.hasOwnProperty.call(obj, ASSET_KEYS[STATUS_INDEX]) && typeof obj[ASSET_KEYS[STATUS_INDEX]] !== 'number') { + if (Object.prototype.hasOwnProperty.call(obj, ASSET_KEYS[STATUS_INDEX]) && + typeof obj[ASSET_KEYS[STATUS_INDEX]] !== 'number' && typeof obj[ASSET_KEYS[STATUS_INDEX]] !== 'undefined') { return false; } for (const key of ASSET_KEYS.slice(1)) { - if (!Object.prototype.hasOwnProperty.call(obj, key) || typeof obj[key] !== 'string') { + if (!Object.prototype.hasOwnProperty.call(obj, key) || + (typeof obj[key] !== 'string' && typeof obj[key] !== 'undefined')) { return false; } } return true; } -function getAssetValue(object, key, obj) { - Object.keys(obj).forEach(subKey => { - Object.defineProperty(obj, subKey, { +function defineAsset(object, key, data) { + Object.defineProperty(object, key, { + enumerable: true, + configurable: true, + get: function () { + return getAssetValue(object, key); + }, + set: function (newValue) { + setAssetValue(object, key, newValue); + } + }); + let asset = object[key]; + Object.keys(data).forEach(subKey => { + if (data[subKey] !== undefined) { + asset[subKey] = data[subKey]; + } + }); +} + +function getAssetValue(object, key) { + let asset = {}; + ASSET_KEYS.forEach(subKey => { + Object.defineProperty(asset, subKey, { enumerable: true, configurable: true, get: function () { @@ -198,7 +220,7 @@ function getAssetValue(object, key, obj) { } }); }); - return obj; + return asset; } function setAssetValue(object, key, newValue) { @@ -208,7 +230,7 @@ function setAssetValue(object, key, newValue) { message: 'cannot set ' + key + ' by non Asset type data' }; } - Object.values(ASSET_KEYS).forEach(subKey => { + Object.values(newValue).forEach(subKey => { setObjectValue(object, key + ASSET_KEY_SEPARATOR + subKey, newValue[subKey]); }); } @@ -234,16 +256,7 @@ function joinSession(version, obj, objectId, sessionId, context) { Object.keys(obj).forEach(key => { console.info('start define ' + key); 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); - } - }); + defineAsset(object, key, obj[key]); } else { Object.defineProperty(object, key, { enumerable: true, @@ -255,9 +268,9 @@ function joinSession(version, obj, objectId, sessionId, context) { setObjectValue(object, key, newValue); } }); - } - if (obj[key] !== undefined) { - object[key] = obj[key]; + if (obj[key] !== undefined) { + object[key] = obj[key]; + } } }); diff --git a/data_share/OAT.xml b/data_share/OAT.xml new file mode 100644 index 00000000..0e4aff54 --- /dev/null +++ b/data_share/OAT.xml @@ -0,0 +1,67 @@ + + + + + + LICENSE + + + + + + + + + + + + diff --git a/data_share/bundle.json b/data_share/bundle.json index d87ea9bc..701fc5e7 100644 --- a/data_share/bundle.json +++ b/data_share/bundle.json @@ -60,13 +60,13 @@ "hitrace", "hilog", "ipc", + "kv_store", + "libuv", "napi", "relational_store", "samgr" ], - "third_party": [ - "libuv" - ] + "third_party": [] }, "build": { "group_type": { diff --git a/data_share/datashare.gni b/data_share/datashare.gni index a3929b9e..c8f388e7 100644 --- a/data_share/datashare.gni +++ b/data_share/datashare.gni @@ -11,16 +11,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -ability_runtime_path = "//foundation/ability/ability_runtime" - -ability_runtime_inner_api_path = "${ability_runtime_path}/interfaces/inner_api" - -ability_runtime_kits_path = "${ability_runtime_path}/frameworks/kits" - -ability_runtime_services_path = "${ability_runtime_path}/services" - -ability_runtime_napi_path = "${ability_runtime_path}/frameworks/js/napi" - datashare_base_path = "//foundation/distributeddatamgr/data_share" datashare_common_native_path = "${datashare_base_path}/frameworks/native/common" @@ -44,10 +34,6 @@ datashare_native_proxy_path = "${datashare_base_path}/frameworks/native/proxy" foundation_path = "//foundation" -kvstore_base_path = "//foundation/distributeddatamgr/kv_store" - -kvstore_common_path = "${kvstore_base_path}/frameworks/common" - access_token_path = "//base/security/access_token" base_hiviewdfx_hilog_path = "//base/hiviewdfx/hilog" diff --git a/data_share/frameworks/js/napi/common/src/datashare_error_impl.cpp b/data_share/frameworks/js/napi/common/src/datashare_error_impl.cpp index f91c8f75..93a46c73 100644 --- a/data_share/frameworks/js/napi/common/src/datashare_error_impl.cpp +++ b/data_share/frameworks/js/napi/common/src/datashare_error_impl.cpp @@ -69,7 +69,7 @@ std::string BusinessError::GetMessage() const std::string UriNotExistError::GetMessage() const { - return "The uri is not exist."; + return "The URI is not exist."; } int UriNotExistError::GetCode() const diff --git a/data_share/frameworks/js/napi/common/src/datashare_predicates_proxy.cpp b/data_share/frameworks/js/napi/common/src/datashare_predicates_proxy.cpp index fbe0820a..ef9ccf25 100644 --- a/data_share/frameworks/js/napi/common/src/datashare_predicates_proxy.cpp +++ b/data_share/frameworks/js/napi/common/src/datashare_predicates_proxy.cpp @@ -70,6 +70,9 @@ napi_value DataSharePredicatesProxy::GetConstructor(napi_env env) void DataSharePredicatesProxy::Init(napi_env env, napi_value exports) { + // In asan version, the thread underline maybe reused and thread-local may not be cleared, this will + // cause use-after-free. + constructor_ = nullptr; napi_value cons = GetConstructor(env); NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, exports, "DataSharePredicates", cons)); } diff --git a/data_share/frameworks/js/napi/dataShare/BUILD.gn b/data_share/frameworks/js/napi/dataShare/BUILD.gn index 5e8d8fc2..70a6fb3f 100644 --- a/data_share/frameworks/js/napi/dataShare/BUILD.gn +++ b/data_share/frameworks/js/napi/dataShare/BUILD.gn @@ -17,6 +17,8 @@ import("//foundation/distributeddatamgr/data_share/datashare.gni") ohos_shared_library("datashare_jscommon") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false @@ -24,7 +26,6 @@ ohos_shared_library("datashare_jscommon") { include_dirs = [ "${datashare_common_native_path}/include", "${datashare_common_napi_path}/include", - "${kvstore_common_path}", ] sources = [ @@ -46,6 +47,7 @@ ohos_shared_library("datashare_jscommon") { "hitrace:libhitracechain", "ipc:ipc_napi", "ipc:ipc_single", + "kv_store:distributeddata_inner", "napi:ace_napi", ] @@ -56,6 +58,8 @@ ohos_shared_library("datashare_jscommon") { ohos_shared_library("datashare") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false @@ -84,7 +88,6 @@ ohos_shared_library("datashare") { ":datashare_jscommon", "${datashare_innerapi_path}:datashare_consumer", "${datashare_innerapi_path}/common:datashare_common", - "//third_party/libuv:uv", ] external_deps = [ @@ -93,6 +96,7 @@ ohos_shared_library("datashare") { "ability_base:zuri", "ability_runtime:abilitykit_native", "ability_runtime:dataobs_manager", + "ability_runtime:extensionkit_native", "ability_runtime:napi_base_context", "ability_runtime:napi_common", "c_utils:utils", @@ -101,6 +105,8 @@ ohos_shared_library("datashare") { "hitrace:hitrace_meter", "hitrace:libhitracechain", "ipc:ipc_single", + "kv_store:distributeddata_inner", + "libuv:uv", "napi:ace_napi", ] @@ -113,6 +119,8 @@ ohos_shared_library("datashare") { ohos_shared_library("datasharepredicates") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false @@ -134,6 +142,7 @@ ohos_shared_library("datasharepredicates") { "c_utils:utils", "hilog:libhilog", "ipc:ipc_single", + "kv_store:distributeddata_inner", "napi:ace_napi", ] diff --git a/data_share/frameworks/js/napi/dataShare/src/async_call.cpp b/data_share/frameworks/js/napi/dataShare/src/async_call.cpp index f9f24a83..a7e43680 100644 --- a/data_share/frameworks/js/napi/dataShare/src/async_call.cpp +++ b/data_share/frameworks/js/napi/dataShare/src/async_call.cpp @@ -28,10 +28,14 @@ AsyncCall::AsyncCall(napi_env env, napi_callback_info info, std::shared_ptrcallback); - argc = argc - 1; + if (argc > 0) { + napi_typeof(env, argv[argc - 1], &valueType); + if (valueType == napi_function) { + napi_create_reference(env, argv[argc - 1], 1, &context_->callback); + argc = argc - 1; + } + } else { + LOG_DEBUG("get argc value less than zero"); } napi_status status = (*context)(env, argc, argv, self); NAPI_ASSERT_ERRCODE(env, status == napi_ok, context->error); diff --git a/data_share/frameworks/js/napi/datashare_ext_ability/BUILD.gn b/data_share/frameworks/js/napi/datashare_ext_ability/BUILD.gn index 626766d9..e7e8367d 100644 --- a/data_share/frameworks/js/napi/datashare_ext_ability/BUILD.gn +++ b/data_share/frameworks/js/napi/datashare_ext_ability/BUILD.gn @@ -37,6 +37,8 @@ gen_js_obj("datashare_ext_ability_abc") { ohos_shared_library("datashareextensionability_napi") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false diff --git a/data_share/frameworks/js/napi/datashare_ext_ability_context/BUILD.gn b/data_share/frameworks/js/napi/datashare_ext_ability_context/BUILD.gn index 98b047c6..cce58b43 100644 --- a/data_share/frameworks/js/napi/datashare_ext_ability_context/BUILD.gn +++ b/data_share/frameworks/js/napi/datashare_ext_ability_context/BUILD.gn @@ -38,6 +38,8 @@ gen_js_obj("datashare_ext_ability_context_abc") { ohos_shared_library("datashareextensionabilitycontext_napi") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false diff --git a/data_share/frameworks/native/common/include/callbacks_manager.h b/data_share/frameworks/native/common/include/callbacks_manager.h index 9a62e2ce..052b1969 100644 --- a/data_share/frameworks/native/common/include/callbacks_manager.h +++ b/data_share/frameworks/native/common/include/callbacks_manager.h @@ -20,6 +20,7 @@ #include #include "datashare_errno.h" +#include "datashare_log.h" #include "datashare_template.h" namespace OHOS::DataShare { @@ -57,8 +58,8 @@ public: std::vector> GetEnabledObservers(const Key &); - int GetEnabledSubscriberSize(); - int GetEnabledSubscriberSize(const Key &key); + int GetAllSubscriberSize(); + int GetAllSubscriberSize(const Key &key); std::vector GetKeys(); void SetObserversNotifiedOnEnabled(const Key &key); @@ -314,32 +315,25 @@ std::vector CallbacksManager::DisableObservers(c } template -int CallbacksManager::GetEnabledSubscriberSize() +int CallbacksManager::GetAllSubscriberSize() { int count = 0; std::lock_guard lck(mutex_); for (auto &[key, value] : callbacks_) { - count += GetEnabledSubscriberSize(key); + count += GetAllSubscriberSize(key); } return count; } template -int CallbacksManager::GetEnabledSubscriberSize(const Key &key) +int CallbacksManager::GetAllSubscriberSize(const Key &key) { std::lock_guard lck(mutex_); - int count = 0; auto it = callbacks_.find(key); if (it == callbacks_.end()) { - return count; - } - std::vector &callbacks = it->second; - for (const auto &callback : callbacks) { - if (callback.enabled_) { - count++; - } + return 0; } - return count; + return it->second.size(); } template @@ -351,11 +345,16 @@ void CallbacksManager::SetObserversNotifiedOnEnabled(const Key &k return; } std::vector &callbacks = it->second; + uint32_t num = 0; for (auto &observerNode : callbacks) { if (!observerNode.enabled_) { + num++; observerNode.isNotifyOnEnabled_ = true; } } + if (num > 0) { + LOG_INFO("total %{public}zu, not refreshed %{public}u", callbacks.size(), num); + } } } // namespace OHOS::DataShare #endif // DATA_SHARE_CALLBACKS_MANAGER_H diff --git a/data_share/frameworks/native/common/include/datashare_radar_reporter.h b/data_share/frameworks/native/common/include/datashare_radar_reporter.h new file mode 100644 index 00000000..6860f54c --- /dev/null +++ b/data_share/frameworks/native/common/include/datashare_radar_reporter.h @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DATASHARE_RADAR_REPORTER_H +#define DATASHARE_RADAR_REPORTER_H + +#include "hisysevent.h" + +namespace OHOS { +namespace DataShare { +namespace RadarReporter { +using namespace OHOS::HiviewDFX; +static constexpr int DISTRIBUTEDDATA_ID = 0xd; +static constexpr int DATA_SHARE_ID = 5; +enum BizScene { + CREATE_DATASHARE_HELPER = 1, + SILENT_ACCESS = 2, + OBSERVER_MANAGER = 3, + NOTIFY_OBSERVER_DATA_CHANGE = 4, + TEMPLATE_DATA_MANAGER = 5, + TEMPLATE_DATA_CHANGE = 6, +}; + +enum CreateDataShareHelperStage { + CREATE_HELPER = 1, + DISTRIBUTEDDATA_START = 2, + CONNECT_EXT = 3, + DIS_CONNECT_EXT = 4, +}; + +enum SilentAccessStage { + EXT_REQUEST = 1, + GET_BMS = 2, + PROXY_GET_SUPPLIER = 3, + PROXY_PERMISSION = 4, + PROXY_MATEDATA_EXISTS = 5, + PROXY_CONNECT_EXT = 6, + PROXY_CALL_RDB = 7, +}; + +enum ObserverManagerStage { + REGISTER_OBSERVER = 1, + UNREGISTER_OBSERVER = 2, +}; + +enum NotifyObserverDataChangeStage { + NOTIFY_DATA_CHANGE = 1, +}; + +enum TemplateDataManagerStage { + SUBSCRIBE_PUBLISHED_DATA = 1, + SUBSCRIBE_RDB_DATA = 2, + UNSUBSCRIBE_PUBLISHED_DATA = 3, + UNSUBSCRIBE_RDB_DATA = 4, + ADD_TEMPLATE = 5, + DELETE_TEMPLATE = 6, +}; + +enum TemplateDataChangeStage { + PUBLISHED_DATA_CHANGE = 1, + RDB_DATA_CHANGE = 2, +}; + +enum StageRes { + IDLE = 0, + SUCCESS = 1, + FAILED = 2, + CANCELLED = 3, +}; + +enum BizState { + START = 1, + FINISHED = 2, +}; + +enum ErrorCode { + CONNECT_EXTENSION_ERROR = (DISTRIBUTEDDATA_ID << 21) | (DATA_SHARE_ID << 16), + CREATE_HELPER_ERROR, + CREATE_SHARE_BLOCK_ERROR, + SHARE_BLOCK_FULL, + DISTRIBUTEDDATA_NOT_START, + EXT_CONNECT_TIMEOUT_ERROR, + EXT_DIS_CONNECT_ERROR, + GET_BMS_FAILED, + SUPPLIER_ERROR, + URI_ERROR, + PERMISSION_DENIED_ERROR, + GET_RDB_STORE_ERROR, + META_DATA_NOT_EXISTS, + EMPTY_OBSERVER_ERROR, + NOTIFY_ERROR, + DATA_OBS_EMPTY_ERROR, + SILENT_PROXY_DISABLE, + ADD_TEMPLATE_ERROR, + NOT_SUBCRIBE_ERROR, + CREATE_DELEGATE_ERROR, + INSERT_RDB_ERROR, + QUERY_RDB_ERROR, + DELETE_RDB_ERROR, + UPDATE_RDB_ERROR, + GET_BUNDLE_INFP_FAILED, + EMPTY_PARAM_ERROR, + INVALID_PARAM_ERROR, + DATA_SHARE_DIED_ERROR, +}; + +static constexpr char DOMAIN[] = "DISTDATAMGR"; +constexpr const char* EVENT_NAME = "DISTRIBUTED_DATA_SHARE_BEHAVIOR"; +constexpr const char* ORG_PKG = "distributeddata"; +constexpr const char* BIZ_STATE = "BIZ_STATE"; +constexpr const char* ERROR_CODE = "ERROR_CODE"; +constexpr const char* LOCAL_SESS_NAME = "LOCAL_SESS_NAME"; +constexpr const char* PEER_SESS_NAME = "PEER_SESS_NAME"; + +static constexpr HiviewDFX::HiSysEvent::EventType TYPE = HiviewDFX::HiSysEvent::EventType::BEHAVIOR; + +#define RADAR_REPORT(funcName, bizScene, bizStage, stageRes, ...) \ +({ \ + HiSysEventWrite(RadarReporter::DOMAIN, RadarReporter::EVENT_NAME, RadarReporter::TYPE, \ + "ORG_PKG", RadarReporter::ORG_PKG, "FUNC", funcName, \ + "BIZ_SCENE", bizScene, "BIZ_STAGE", bizStage, "STAGE_RES", stageRes, \ + ##__VA_ARGS__); \ +}) + +class RadarReport final { +public: + RadarReport(int32_t bizScene, int32_t bizStage, const std::string funcName) + { + RADAR_REPORT(funcName, bizScene, bizStage, RadarReporter::SUCCESS, + RadarReporter::BIZ_STATE, RadarReporter::START); + bizScene_ = bizScene; + bizStage_ = bizStage; + funcName_ = funcName; + } + + ~RadarReport() + { + if (errorCode_ != 0) { + RADAR_REPORT(funcName_, bizScene_, bizStage_, RadarReporter::FAILED, RadarReporter::BIZ_STATE, + RadarReporter::FINISHED, RadarReporter::ERROR_CODE, errorCode_); + } else { + RADAR_REPORT(funcName_, bizScene_, bizStage_, RadarReporter::SUCCESS, + RadarReporter::BIZ_STATE, RadarReporter::FINISHED); + } + } + + void SetError(int32_t errorCode) + { + errorCode_ = errorCode; + } +private: + int32_t bizScene_; + int32_t bizStage_; + int32_t errorCode_ = 0; + std::string funcName_; +}; +} // namespace RadarReporter +} // namespace DataShare +} // namespace OHOS +#endif // DATASHARE_RADAR_REPORTER_H \ No newline at end of file diff --git a/data_share/frameworks/native/common/include/datashare_string_utils.h b/data_share/frameworks/native/common/include/datashare_string_utils.h index 47519a1c..be6f7f9e 100644 --- a/data_share/frameworks/native/common/include/datashare_string_utils.h +++ b/data_share/frameworks/native/common/include/datashare_string_utils.h @@ -28,6 +28,8 @@ public: static void RemoveFromQuery(std::string &uri); + static std::string Change(const std::string &name); + private: DataShareStringUtils(); ~DataShareStringUtils(); diff --git a/data_share/frameworks/native/common/include/distributeddata_data_share_ipc_interface_code.h b/data_share/frameworks/native/common/include/distributeddata_data_share_ipc_interface_code.h index 5d91f344..b91a91f9 100644 --- a/data_share/frameworks/native/common/include/distributeddata_data_share_ipc_interface_code.h +++ b/data_share/frameworks/native/common/include/distributeddata_data_share_ipc_interface_code.h @@ -90,7 +90,7 @@ enum class DataShareServiceInterfaceCode { DATA_SHARE_SERVICE_CMD_NOTIFY, DATA_SHARE_SERVICE_CMD_NOTIFY_OBSERVERS, DATA_SHARE_SERVICE_CMD_SET_SILENT_SWITCH, - DATA_SHARE_SERVICE_CMD_IS_SILENT_PROXY_ENABLE, + DATA_SHARE_SERVICE_CMD_GET_SILENT_PROXY_STATUS, DATA_SHARE_SERVICE_CMD_REGISTER_OBSERVER, DATA_SHARE_SERVICE_CMD_UNREGISTER_OBSERVER, DATA_SHARE_SERVICE_CMD_MAX diff --git a/data_share/frameworks/native/common/include/idata_share_service.h b/data_share/frameworks/native/common/include/idata_share_service.h index 51818b97..a09d5ac9 100644 --- a/data_share/frameworks/native/common/include/idata_share_service.h +++ b/data_share/frameworks/native/common/include/idata_share_service.h @@ -84,7 +84,7 @@ public: virtual int SetSilentSwitch(const Uri &uri, bool enable) = 0; - virtual bool IsSilentProxyEnable(const std::string &uri) = 0; + virtual int GetSilentProxyStatus(const std::string &uri) = 0; virtual int RegisterObserver(const Uri &uri, const sptr &dataObserver) = 0; diff --git a/data_share/frameworks/native/common/src/datashare_string_utils.cpp b/data_share/frameworks/native/common/src/datashare_string_utils.cpp index 98aab897..94d33047 100644 --- a/data_share/frameworks/native/common/src/datashare_string_utils.cpp +++ b/data_share/frameworks/native/common/src/datashare_string_utils.cpp @@ -18,6 +18,7 @@ namespace OHOS { namespace DataShare { constexpr int32_t END_SIZE = 10; +constexpr int32_t ANONYMOUS_SIZE = 12; constexpr const char *DEFAULT_ANONYMOUS = "******"; std::string DataShareStringUtils::Anonymous(const std::string &name) { @@ -37,6 +38,13 @@ void DataShareStringUtils::RemoveFromQuery(std::string &uri) uri.resize(pos); } +std::string DataShareStringUtils::Change(const std::string &name) +{ + if (name.length() <= ANONYMOUS_SIZE) { + return name; + } + return DEFAULT_ANONYMOUS + name.substr(ANONYMOUS_SIZE); +} DataShareStringUtils::DataShareStringUtils() {} DataShareStringUtils::~DataShareStringUtils() {} } // namespace DataShare diff --git a/data_share/frameworks/native/common/src/shared_block.cpp b/data_share/frameworks/native/common/src/shared_block.cpp index bdf19918..2264f2ad 100644 --- a/data_share/frameworks/native/common/src/shared_block.cpp +++ b/data_share/frameworks/native/common/src/shared_block.cpp @@ -38,6 +38,7 @@ SharedBlock::~SharedBlock() if (ashmem_ != nullptr) { ashmem_->UnmapAshmem(); ashmem_->CloseAshmem(); + ashmem_ = nullptr; LOG_DEBUG("SharedBlock: close ashmem"); } } diff --git a/data_share/frameworks/native/consumer/controller/provider/src/general_controller_provider_impl.cpp b/data_share/frameworks/native/consumer/controller/provider/src/general_controller_provider_impl.cpp index d3f15ca2..e7b1c812 100644 --- a/data_share/frameworks/native/consumer/controller/provider/src/general_controller_provider_impl.cpp +++ b/data_share/frameworks/native/consumer/controller/provider/src/general_controller_provider_impl.cpp @@ -16,6 +16,7 @@ #include "general_controller_provider_impl.h" #include "datashare_log.h" +#include "datashare_string_utils.h" namespace OHOS { namespace DataShare { @@ -95,7 +96,9 @@ void GeneralControllerProviderImpl::RegisterObserver(const Uri &uri, LOG_ERROR("proxy is nullptr"); return; } - proxy->RegisterObserver(uri, dataObserver); + bool ret = proxy->RegisterObserver(uri, dataObserver); + LOG_INFO("Register non-silent observer ret: %{public}d, uri: %{public}s", ret, + DataShareStringUtils::Anonymous(uri.ToString()).c_str()); } void GeneralControllerProviderImpl::UnregisterObserver(const Uri &uri, @@ -111,7 +114,9 @@ void GeneralControllerProviderImpl::UnregisterObserver(const Uri &uri, LOG_ERROR("proxy is nullptr"); return; } - proxy->UnregisterObserver(uri, dataObserver); + bool ret = proxy->UnregisterObserver(uri, dataObserver); + LOG_INFO("Unregister non-silent observer ret: %{public}d, uri: %{public}s", ret, + DataShareStringUtils::Anonymous(uri.ToString()).c_str()); } void GeneralControllerProviderImpl::NotifyChange(const Uri &uri) diff --git a/data_share/frameworks/native/consumer/controller/service/src/general_controller_service_impl.cpp b/data_share/frameworks/native/consumer/controller/service/src/general_controller_service_impl.cpp index bdf2e16e..4605e959 100644 --- a/data_share/frameworks/native/consumer/controller/service/src/general_controller_service_impl.cpp +++ b/data_share/frameworks/native/consumer/controller/service/src/general_controller_service_impl.cpp @@ -80,7 +80,7 @@ void GeneralControllerServiceImpl::RegisterObserver(const Uri &uri, return; } ErrCode ret = obsMgrClient->RegisterObserver(uri, dataObserver); - LOG_INFO("Register observer ret: %{public}d, uri: %{public}s", ret, + LOG_INFO("Register silent observer ret: %{public}d, uri: %{public}s", ret, DataShareStringUtils::Anonymous(uri.ToString()).c_str()); } @@ -93,7 +93,7 @@ void GeneralControllerServiceImpl::UnregisterObserver(const Uri &uri, return; } ErrCode ret = obsMgrClient->UnregisterObserver(uri, dataObserver); - LOG_INFO("Unregister observer ret: %{public}d, uri: %{public}s", ret, + LOG_INFO("Unregister silent observer ret: %{public}d, uri: %{public}s", ret, DataShareStringUtils::Anonymous(uri.ToString()).c_str()); } diff --git a/data_share/frameworks/native/consumer/include/datashare_connection.h b/data_share/frameworks/native/consumer/include/datashare_connection.h index 723ed0e3..7326345c 100644 --- a/data_share/frameworks/native/consumer/include/datashare_connection.h +++ b/data_share/frameworks/native/consumer/include/datashare_connection.h @@ -68,17 +68,21 @@ public: */ std::shared_ptr GetDataShareProxy(const Uri &uri, const sptr &token); + void SetConnectInvalid(); + private: struct ConnectCondition { std::condition_variable condition; std::mutex mutex; }; std::shared_ptr ConnectDataShareExtAbility(const Uri &uri, const sptr &token); + ErrCode Disconnect(); std::mutex mutex_{}; std::shared_ptr dataShareProxy_; ConnectCondition condition_; Uri uri_; sptr token_ = {}; + std::atomic isInvalid_ = false; }; } // namespace DataShare } // namespace OHOS diff --git a/data_share/frameworks/native/consumer/src/datashare_connection.cpp b/data_share/frameworks/native/consumer/src/datashare_connection.cpp index be1701b3..55d8efba 100644 --- a/data_share/frameworks/native/consumer/src/datashare_connection.cpp +++ b/data_share/frameworks/native/consumer/src/datashare_connection.cpp @@ -16,8 +16,11 @@ #include "datashare_connection.h" #include "ams_mgr_proxy.h" -#include "datashare_proxy.h" +#include "datashare_errno.h" #include "datashare_log.h" +#include "datashare_proxy.h" +#include "datashare_radar_reporter.h" +#include "datashare_string_utils.h" namespace OHOS { namespace DataShare { @@ -35,17 +38,26 @@ constexpr int WAIT_TIME = 2; void DataShareConnection::OnAbilityConnectDone( const AppExecFwk::ElementName &element, const sptr &remoteObject, int resultCode) { - LOG_INFO("on connect done, req uri:%{public}s, rev uri:%{public}s, ret=%{public}d", uri_.ToString().c_str(), - element.GetURI().c_str(), resultCode); + LOG_INFO("on connect done, req uri:%{public}s, rev uri:%{public}s, ret=%{public}d", + DataShareStringUtils::Change(uri_.ToString()).c_str(), + DataShareStringUtils::Change(element.GetURI()).c_str(), resultCode); if (remoteObject == nullptr) { LOG_ERROR("remote is nullptr"); condition_.condition.notify_all(); return; } - std::lock_guard lock(mutex_); - sptr proxy = new (std::nothrow) DataShareProxy(remoteObject); - dataShareProxy_ = std::shared_ptr(proxy.GetRefPtr(), [holder = proxy](const auto *) {}); - condition_.condition.notify_all(); + { + std::lock_guard lock(mutex_); + sptr proxy = new (std::nothrow) DataShareProxy(remoteObject); + dataShareProxy_ = std::shared_ptr(proxy.GetRefPtr(), [holder = proxy](const auto *) {}); + condition_.condition.notify_all(); + } + if (isInvalid_.load()) { + LOG_ERROR("connect is invalid, req uri:%{public}s, rev uri:%{public}s, ret=%{public}d", + DataShareStringUtils::Change(uri_.ToString()).c_str(), + DataShareStringUtils::Change(element.GetURI()).c_str(), resultCode); + Disconnect(); + } } /** @@ -59,8 +71,9 @@ void DataShareConnection::OnAbilityConnectDone( */ void DataShareConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int resultCode) { - LOG_INFO("on disconnect done, req uri:%{public}s, rev uri:%{public}s, ret=%{public}d", uri_.ToString().c_str(), - element.GetURI().c_str(), resultCode); + LOG_INFO("on disconnect done, req uri:%{public}s, rev uri:%{public}s, ret=%{public}d", + DataShareStringUtils::Change(uri_.ToString()).c_str(), + DataShareStringUtils::Change(element.GetURI()).c_str(), resultCode); std::string uri; { std::lock_guard lock(mutex_); @@ -72,11 +85,12 @@ void DataShareConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName } AmsMgrProxy* instance = AmsMgrProxy::GetInstance(); if (instance == nullptr) { - LOG_ERROR("get proxy failed uri:%{public}s", uri.c_str()); + LOG_ERROR("get proxy failed uri:%{public}s", DataShareStringUtils::Change(uri_.ToString()).c_str()); return; } ErrCode ret = instance->Connect(uri, this, token_); - LOG_INFO("reconnect ability, uri:%{public}s, ret = %{public}d", uri.c_str(), ret); + LOG_INFO("reconnect ability, uri:%{public}s, ret = %{public}d", + DataShareStringUtils::Change(uri_.ToString()).c_str(), ret); } /** @@ -96,20 +110,29 @@ std::shared_ptr DataShareConnection::ConnectDataShareExtAbility( AmsMgrProxy* instance = AmsMgrProxy::GetInstance(); if (instance == nullptr) { - LOG_ERROR("get proxy failed uri:%{public}s", reqUri.c_str()); + LOG_ERROR("get proxy failed uri:%{public}s", DataShareStringUtils::Change(reqUri).c_str()); return nullptr; } ErrCode ret = instance->Connect(reqUri, this, token); - LOG_INFO("connect ability, uri = %{public}s. ret = %{public}d", reqUri.c_str(), ret); + LOG_INFO("connect ability, uri = %{public}s. ret = %{public}d", DataShareStringUtils::Change(reqUri).c_str(), ret); if (ret != ERR_OK) { return nullptr; } std::unique_lock condLock(condition_.mutex); if (condition_.condition.wait_for(condLock, std::chrono::seconds(WAIT_TIME), [this] { return dataShareProxy_ != nullptr; })) { - LOG_DEBUG("connect ability ended successfully uri:%{public}s", reqUri.c_str()); + LOG_DEBUG("connect ability ended successfully uri:%{public}s", DataShareStringUtils::Change(reqUri).c_str()); + RADAR_REPORT(__FUNCTION__, RadarReporter::CREATE_DATASHARE_HELPER, + RadarReporter::CONNECT_EXT, RadarReporter::SUCCESS, + RadarReporter::LOCAL_SESS_NAME, Str16ToStr8(token->GetObjectDescriptor()), + RadarReporter::PEER_SESS_NAME, reqUri); } else { - LOG_WARN("connect timeout uri:%{public}s", reqUri.c_str()); + LOG_WARN("connect timeout uri:%{public}s", DataShareStringUtils::Change(reqUri).c_str()); + RADAR_REPORT(__FUNCTION__, RadarReporter::CREATE_DATASHARE_HELPER, + RadarReporter::CONNECT_EXT, RadarReporter::FAILED, + RadarReporter::ERROR_CODE, RadarReporter::EXT_CONNECT_TIMEOUT_ERROR, + RadarReporter::LOCAL_SESS_NAME, Str16ToStr8(token->GetObjectDescriptor()), + RadarReporter::PEER_SESS_NAME, reqUri); } return dataShareProxy_; } @@ -129,14 +152,20 @@ void DataShareConnection::DisconnectDataShareExtAbility() } } - AmsMgrProxy* instance = AmsMgrProxy::GetInstance(); - if (instance == nullptr) { - LOG_ERROR("get proxy failed uri:%{public}s", uri.c_str()); + ErrCode ret = Disconnect(); + LOG_INFO("disconnect uri:%{public}s, ret = %{public}d", DataShareStringUtils::Change(uri).c_str(), ret); + if (ret == E_OK) { + RADAR_REPORT(__FUNCTION__, RadarReporter::CREATE_DATASHARE_HELPER, + RadarReporter::DIS_CONNECT_EXT, RadarReporter::SUCCESS, + RadarReporter::LOCAL_SESS_NAME, Str16ToStr8(token_->GetObjectDescriptor()), + RadarReporter::PEER_SESS_NAME, uri); return; } - - ErrCode ret = instance->DisConnect(this); - LOG_INFO("disconnect uri:%{public}s, ret = %{public}d", uri.c_str(), ret); + RADAR_REPORT(__FUNCTION__, RadarReporter::CREATE_DATASHARE_HELPER, + RadarReporter::DIS_CONNECT_EXT, RadarReporter::FAILED, + RadarReporter::ERROR_CODE, RadarReporter::EXT_DIS_CONNECT_ERROR, + RadarReporter::LOCAL_SESS_NAME, Str16ToStr8(token_->GetObjectDescriptor()), + RadarReporter::PEER_SESS_NAME, uri); } DataShareConnection::~DataShareConnection() @@ -148,5 +177,19 @@ std::shared_ptr DataShareConnection::GetDataShareProxy(const Uri { return ConnectDataShareExtAbility(uri, token); } + +void DataShareConnection::SetConnectInvalid() +{ + isInvalid_.store(true); +} + +ErrCode DataShareConnection::Disconnect() +{ + AmsMgrProxy* instance = AmsMgrProxy::GetInstance(); + if (instance == nullptr) { + return -1; + } + return instance->DisConnect(this); +} } // namespace DataShare } // namespace OHOS \ No newline at end of file diff --git a/data_share/frameworks/native/consumer/src/datashare_helper.cpp b/data_share/frameworks/native/consumer/src/datashare_helper.cpp index cd143836..1fed4972 100644 --- a/data_share/frameworks/native/consumer/src/datashare_helper.cpp +++ b/data_share/frameworks/native/consumer/src/datashare_helper.cpp @@ -22,7 +22,9 @@ #include "data_ability_observer_interface.h" #include "data_ability_observer_stub.h" #include "dataobs_mgr_client.h" +#include "datashare_errno.h" #include "datashare_log.h" +#include "datashare_radar_reporter.h" #include "datashare_string_utils.h" namespace OHOS { @@ -78,66 +80,116 @@ std::shared_ptr DataShareHelper::Creator( const sptr &token, const std::string &strUri, const std::string &extUri) { DISTRIBUTED_DATA_HITRACE(std::string(LOG_TAG) + "::" + std::string(__FUNCTION__)); + RadarReporter::RadarReport report(RadarReporter::CREATE_DATASHARE_HELPER, + RadarReporter::CREATE_HELPER, __FUNCTION__); if (token == nullptr) { + report.SetError(RadarReporter::INVALID_PARAM_ERROR); LOG_ERROR("token == nullptr"); return nullptr; } std::string replacedUriStr = TransferUriPrefix(FILE_PREFIX, DATA_SHARE_PREFIX, strUri); Uri uri(replacedUriStr); - + std::shared_ptr helper = nullptr; if (uri.GetQuery().find("Proxy=true") != std::string::npos) { auto result = CreateServiceHelper(); - if (result != nullptr && IsSilentProxyEnable(strUri)) { + if (result != nullptr && GetSilentProxyStatus(strUri) == E_OK) { return result; } if (extUri.empty()) { + report.SetError(RadarReporter::INVALID_PARAM_ERROR); return nullptr; } Uri ext(extUri); - return CreateExtHelper(ext, token); + helper = CreateExtHelper(ext, token); + } else { + helper = CreateExtHelper(uri, token); + } + if (helper == nullptr) { + report.SetError(RadarReporter::CREATE_HELPER_ERROR); } - return CreateExtHelper(uri, token); + return helper; } std::shared_ptr DataShareHelper::Creator(const string &strUri, const CreateOptions &options, const std::string &bundleName) { + RadarReporter::RadarReport report(RadarReporter::CREATE_DATASHARE_HELPER, + RadarReporter::CREATE_HELPER, __FUNCTION__); DISTRIBUTED_DATA_HITRACE(std::string(LOG_TAG) + "::" + std::string(__FUNCTION__)); Uri uri(strUri); if (!options.isProxy_ && options.token_ == nullptr) { LOG_ERROR("token is nullptr"); + report.SetError(RadarReporter::INVALID_PARAM_ERROR); return nullptr; } - if (options.isProxy_) { - return CreateServiceHelper(bundleName); + auto helper = options.isProxy_ ? CreateServiceHelper(bundleName) : CreateExtHelper(uri, options.token_); + if (helper == nullptr) { + report.SetError(RadarReporter::CREATE_HELPER_ERROR); + } + return helper; +} + +std::pair> DataShareHelper::Create(const sptr &token, + const std::string &strUri, const std::string &extUri) +{ + RadarReporter::RadarReport report(RadarReporter::CREATE_DATASHARE_HELPER, + RadarReporter::CREATE_HELPER, __FUNCTION__); + DISTRIBUTED_DATA_HITRACE(std::string(LOG_TAG) + "::" + std::string(__FUNCTION__)); + if (token == nullptr) { + LOG_ERROR("Create helper failed, err: %{public}d", E_TOKEN_EMPTY); + report.SetError(RadarReporter::INVALID_PARAM_ERROR); + return std::make_pair(E_TOKEN_EMPTY, nullptr); + } + Uri uri(strUri); + if (IsProxy(uri)) { + auto [ret, helper] = CreateProxyHelper(strUri); + if (helper != nullptr) { + return std::make_pair(E_OK, helper); + } + if (ret == E_BMS_NOT_READY) { + report.SetError(RadarReporter::GET_BMS_FAILED); + LOG_ERROR("BMS not ready, err: %{public}d", E_BMS_NOT_READY); + return std::make_pair(E_DATA_SHARE_NOT_READY, nullptr); + } + if (extUri.empty()) { + report.SetError(RadarReporter::INVALID_PARAM_ERROR); + LOG_ERROR("Ext uri empty, err: %{public}d", E_EXT_URI_INVALID); + return std::make_pair(E_EXT_URI_INVALID, nullptr); + } + uri = Uri(extUri); + } + auto helper = CreateExtHelper(uri, token); + if (helper != nullptr) { + return std::make_pair(E_OK, helper); } - return CreateExtHelper(uri, options.token_); + report.SetError(RadarReporter::CREATE_HELPER_ERROR); + return std::make_pair(E_ERROR, nullptr); } std::shared_ptr DataShareHelper::CreateServiceHelper(const std::string &bundleName) { auto manager = DataShareManagerImpl::GetInstance(); if (manager == nullptr) { - LOG_ERROR("manager_ is nullptr"); + LOG_ERROR("Manager is nullptr"); return nullptr; } manager->SetBundleName(bundleName); if (DataShareManagerImpl::GetServiceProxy() == nullptr) { - LOG_ERROR("service proxy is nullptr."); + LOG_ERROR("Service proxy is nullptr."); return nullptr; } return std::make_shared(); } -bool DataShareHelper::IsSilentProxyEnable(const std::string &uri) +int DataShareHelper::GetSilentProxyStatus(const std::string &uri) { auto proxy = DataShareManagerImpl::GetServiceProxy(); if (proxy == nullptr) { LOG_ERROR("Service proxy is nullptr."); - return false; + return E_ERROR; } - return proxy->IsSilentProxyEnable(uri); + return proxy->GetSilentProxyStatus(uri); } std::shared_ptr DataShareHelper::CreateExtHelper(Uri &uri, const sptr &token) @@ -149,6 +201,7 @@ std::shared_ptr DataShareHelper::CreateExtHelper(Uri &uri, cons } auto dataShareConnection = std::shared_ptr(connection.GetRefPtr(), [holder = connection](const auto *) { + holder->SetConnectInvalid(); holder->DisconnectDataShareExtAbility(); }); if (dataShareConnection->GetDataShareProxy(uri, token) == nullptr) { @@ -325,5 +378,17 @@ int DataShareHelper::SetSilentSwitch(Uri &uri, bool enable) } return proxy->SetSilentSwitch(uri, enable); } + +bool DataShareHelper::IsProxy(Uri &uri) +{ + return (uri.GetQuery().find("Proxy=true") != std::string::npos || uri.GetScheme() == "datashareproxy"); +} + +std::pair> DataShareHelper::CreateProxyHelper(const std::string &strUri) +{ + int ret = GetSilentProxyStatus(strUri); + auto helper = ret == E_OK ? CreateServiceHelper() : nullptr; + return std::make_pair(ret, helper); +} } // namespace DataShare } // namespace OHOS \ No newline at end of file diff --git a/data_share/frameworks/native/consumer/src/datashare_helper_impl.cpp b/data_share/frameworks/native/consumer/src/datashare_helper_impl.cpp index 052938b4..f92398d1 100644 --- a/data_share/frameworks/native/consumer/src/datashare_helper_impl.cpp +++ b/data_share/frameworks/native/consumer/src/datashare_helper_impl.cpp @@ -21,6 +21,7 @@ #include "data_ability_observer_interface.h" #include "dataobs_mgr_client.h" #include "datashare_log.h" +#include "datashare_radar_reporter.h" #include "datashare_result_set.h" #include "general_controller_provider_impl.h" @@ -195,13 +196,17 @@ int DataShareHelperImpl::ExecuteBatch(const std::vector &sta void DataShareHelperImpl::RegisterObserver(const Uri &uri, const sptr &dataObserver) { + RadarReporter::RadarReport report(RadarReporter::OBSERVER_MANAGER, + RadarReporter::REGISTER_OBSERVER, __FUNCTION__); if (dataObserver == nullptr) { LOG_ERROR("dataObserver is nullptr"); + report.SetError(RadarReporter::EMPTY_OBSERVER_ERROR); return; } auto generalCtl = generalCtl_; if (generalCtl == nullptr) { LOG_ERROR("generalCtl is nullptr"); + report.SetError(RadarReporter::DATA_SHARE_DIED_ERROR); return; } return generalCtl->RegisterObserver(uri, dataObserver); @@ -209,13 +214,17 @@ void DataShareHelperImpl::RegisterObserver(const Uri &uri, const sptr &dataObserver) { + RadarReporter::RadarReport report(RadarReporter::OBSERVER_MANAGER, + RadarReporter::UNREGISTER_OBSERVER, __FUNCTION__); if (dataObserver == nullptr) { LOG_ERROR("dataObserver is nullptr"); + report.SetError(RadarReporter::EMPTY_OBSERVER_ERROR); return; } auto generalCtl = generalCtl_; if (generalCtl == nullptr) { LOG_ERROR("generalCtl is nullptr"); + report.SetError(RadarReporter::DATA_SHARE_DIED_ERROR); return; } return generalCtl->UnregisterObserver(uri, dataObserver); @@ -256,9 +265,12 @@ Uri DataShareHelperImpl::DenormalizeUri(Uri &uri) int DataShareHelperImpl::AddQueryTemplate(const std::string &uri, int64_t subscriberId, Template &tpl) { + RadarReporter::RadarReport report(RadarReporter::TEMPLATE_DATA_MANAGER, + RadarReporter::ADD_TEMPLATE, __FUNCTION__); auto persistentDataCtl = persistentDataCtl_; if (persistentDataCtl == nullptr) { LOG_ERROR("persistentDataCtl is nullptr"); + report.SetError(RadarReporter::DATA_SHARE_DIED_ERROR); return INVALID_VALUE; } return persistentDataCtl->AddQueryTemplate(uri, subscriberId, tpl); @@ -266,9 +278,12 @@ int DataShareHelperImpl::AddQueryTemplate(const std::string &uri, int64_t subscr int DataShareHelperImpl::DelQueryTemplate(const std::string &uri, int64_t subscriberId) { + RadarReporter::RadarReport report(RadarReporter::TEMPLATE_DATA_MANAGER, + RadarReporter::DELETE_TEMPLATE, __FUNCTION__); auto persistentDataCtl = persistentDataCtl_; if (persistentDataCtl == nullptr) { LOG_ERROR("persistentDataCtl is nullptr"); + report.SetError(RadarReporter::DATA_SHARE_DIED_ERROR); return INVALID_VALUE; } return persistentDataCtl->DelQueryTemplate(uri, subscriberId); @@ -300,9 +315,12 @@ std::vector DataShareHelperImpl::SubscribeRdbData(const std::ve const TemplateId &templateId, const std::function &callback) { LOG_DEBUG("Start SubscribeRdbData"); + RadarReporter::RadarReport report(RadarReporter::TEMPLATE_DATA_MANAGER, + RadarReporter::SUBSCRIBE_RDB_DATA, __FUNCTION__); auto persistentDataCtl = persistentDataCtl_; if (persistentDataCtl == nullptr) { LOG_ERROR("persistentDataCtl is nullptr"); + report.SetError(RadarReporter::DATA_SHARE_DIED_ERROR); return std::vector(); } return persistentDataCtl->SubscribeRdbData(this, uris, templateId, callback); @@ -312,9 +330,12 @@ std::vector DataShareHelperImpl::UnsubscribeRdbData(const std:: const TemplateId &templateId) { LOG_DEBUG("Start UnsubscribeRdbData"); + RadarReporter::RadarReport report(RadarReporter::TEMPLATE_DATA_MANAGER, + RadarReporter::UNSUBSCRIBE_RDB_DATA, __FUNCTION__); auto persistentDataCtl = persistentDataCtl_; if (persistentDataCtl == nullptr) { LOG_ERROR("persistentDataCtl is nullptr"); + report.SetError(RadarReporter::DATA_SHARE_DIED_ERROR); return std::vector(); } return persistentDataCtl->UnSubscribeRdbData(this, uris, templateId); @@ -348,9 +369,12 @@ std::vector DataShareHelperImpl::SubscribePublishedData(const s int64_t subscriberId, const std::function &callback) { LOG_DEBUG("Start SubscribePublishedData"); + RadarReporter::RadarReport report(RadarReporter::TEMPLATE_DATA_MANAGER, + RadarReporter::SUBSCRIBE_PUBLISHED_DATA, __FUNCTION__); auto publishedDataCtl = publishedDataCtl_; if (publishedDataCtl == nullptr) { LOG_ERROR("publishedDataCtl is nullptr"); + report.SetError(RadarReporter::DATA_SHARE_DIED_ERROR); return std::vector(); } return publishedDataCtl->SubscribePublishedData(this, uris, subscriberId, callback); @@ -360,9 +384,12 @@ std::vector DataShareHelperImpl::UnsubscribePublishedData(const int64_t subscriberId) { LOG_DEBUG("Start UnSubscribePublishedData"); + RadarReporter::RadarReport report(RadarReporter::TEMPLATE_DATA_MANAGER, + RadarReporter::UNSUBSCRIBE_PUBLISHED_DATA, __FUNCTION__); auto publishedDataCtl = publishedDataCtl_; if (publishedDataCtl == nullptr) { LOG_ERROR("publishedDataCtl is nullptr"); + report.SetError(RadarReporter::DATA_SHARE_DIED_ERROR); return std::vector(); } return publishedDataCtl->UnSubscribePublishedData(this, uris, subscriberId); diff --git a/data_share/frameworks/native/permission/src/data_share_permission.cpp b/data_share/frameworks/native/permission/src/data_share_permission.cpp index 8edea2d0..b0862a22 100644 --- a/data_share/frameworks/native/permission/src/data_share_permission.cpp +++ b/data_share/frameworks/native/permission/src/data_share_permission.cpp @@ -29,8 +29,7 @@ using namespace AppExecFwk; int DataSharePermission::VerifyPermission(Security::AccessToken::AccessTokenID tokenID, const Uri &uri, bool isRead) { if (uri.ToString().empty()) { - LOG_ERROR("Uri empty, tokenId:0x%{public}x, uri:%{public}s", tokenID, - DataShareStringUtils::Anonymous(uri.ToString()).c_str()); + LOG_ERROR("Uri empty, tokenId:0x%{public}x", tokenID); return ERR_INVALID_VALUE; } DataShareCalledConfig calledConfig(uri.ToString()); diff --git a/data_share/frameworks/native/provider/include/datashare_stub.h b/data_share/frameworks/native/provider/include/datashare_stub.h index 44e195f7..b4d71b43 100644 --- a/data_share/frameworks/native/provider/include/datashare_stub.h +++ b/data_share/frameworks/native/provider/include/datashare_stub.h @@ -56,6 +56,7 @@ private: using RequestFuncType = int (DataShareStub::*)(MessageParcel &data, MessageParcel &reply); std::map stubFuncMap_; static constexpr int VALUEBUCKET_MAX_COUNT = 3000; + static constexpr std::chrono::milliseconds TIME_THRESHOLD = std::chrono::milliseconds(500); }; } // namespace DataShare } // namespace OHOS diff --git a/data_share/frameworks/native/provider/src/datashare_stub.cpp b/data_share/frameworks/native/provider/src/datashare_stub.cpp index b8cd3297..50c48eaa 100644 --- a/data_share/frameworks/native/provider/src/datashare_stub.cpp +++ b/data_share/frameworks/native/provider/src/datashare_stub.cpp @@ -15,9 +15,12 @@ #include "datashare_stub.h" +#include + #include "data_ability_observer_interface.h" #include "datashare_itypes_utils.h" #include "datashare_log.h" +#include "ipc_skeleton.h" #include "ipc_types.h" #include "ishared_result_set.h" #include "datashare_operation_statement.h" @@ -72,7 +75,17 @@ int DataShareStub::OnRemoteRequest(uint32_t code, MessageParcel& data, MessagePa const auto &itFunc = stubFuncMap_.find(code); if (itFunc != stubFuncMap_.end()) { - return (this->*(itFunc->second))(data, reply); + auto start = std::chrono::steady_clock::now(); + auto ret = (this->*(itFunc->second))(data, reply); + auto finish = std::chrono::steady_clock::now(); + auto duration = std::chrono::duration_cast(finish - start); + if (duration >= TIME_THRESHOLD) { + auto callingPid = IPCSkeleton::GetCallingPid(); + int64_t milliseconds = duration.count(); + LOG_ERROR("extension time over, code:%{public}u callingPid:%{public}d, cost:%{public}" PRIi64 "ms", + code, callingPid, milliseconds); + } + return ret; } LOG_DEBUG("remote request unhandled: %{public}d", code); diff --git a/data_share/frameworks/native/provider/src/datashare_uv_queue.cpp b/data_share/frameworks/native/provider/src/datashare_uv_queue.cpp index 2b466d00..ada7b561 100644 --- a/data_share/frameworks/native/provider/src/datashare_uv_queue.cpp +++ b/data_share/frameworks/native/provider/src/datashare_uv_queue.cpp @@ -32,7 +32,7 @@ DataShareUvQueue::DataShareUvQueue(napi_env env) void DataShareUvQueue::LambdaForWork(uv_work_t *work, int uvstatus) { - if (work == nullptr || work->data == nullptr) { + if (UV_ECANCELED == uvstatus || work == nullptr || work->data == nullptr) { LOG_ERROR("invalid work or work->data."); return; } @@ -81,7 +81,7 @@ void DataShareUvQueue::SyncCall(NapiVoidFunc func, NapiBoolFunc retFunc) system_clock::now().time_since_epoch()).count()); LOG_INFO("function ended successfully. times %{public}" PRIu64 ".", time); } - if (!uvEntry->done && !uv_cancel((uv_req_t*)&work)) { + if (!uvEntry->done && uv_cancel((uv_req_t*)work) != napi_ok) { LOG_ERROR("uv_cancel failed."); uvEntry->purge = true; noNeedPurge = true; diff --git a/data_share/frameworks/native/proxy/include/data_share_manager_impl.h b/data_share/frameworks/native/proxy/include/data_share_manager_impl.h index 8b22e8f7..dcb38fe9 100644 --- a/data_share/frameworks/native/proxy/include/data_share_manager_impl.h +++ b/data_share/frameworks/native/proxy/include/data_share_manager_impl.h @@ -85,6 +85,7 @@ public: void RemoveRegisterCallback(GeneralControllerServiceImpl* ptr); void OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId); + private: DataShareManagerImpl(); diff --git a/data_share/frameworks/native/proxy/include/data_share_service_proxy.h b/data_share/frameworks/native/proxy/include/data_share_service_proxy.h index 06cce528..5b7658ca 100644 --- a/data_share/frameworks/native/proxy/include/data_share_service_proxy.h +++ b/data_share/frameworks/native/proxy/include/data_share_service_proxy.h @@ -71,7 +71,7 @@ public: int SetSilentSwitch(const Uri &uri, bool enable) override; - bool IsSilentProxyEnable(const std::string &uri) override; + int GetSilentProxyStatus(const std::string &uri) override; int RegisterObserver(const Uri &uri, const sptr &dataObserver) override; diff --git a/data_share/frameworks/native/proxy/src/ams_mgr_proxy.cpp b/data_share/frameworks/native/proxy/src/ams_mgr_proxy.cpp index 1f338ab2..73bdba45 100644 --- a/data_share/frameworks/native/proxy/src/ams_mgr_proxy.cpp +++ b/data_share/frameworks/native/proxy/src/ams_mgr_proxy.cpp @@ -15,6 +15,7 @@ #include "ams_mgr_proxy.h" #include "datashare_log.h" +#include "datashare_string_utils.h" #include "extension_ability_info.h" #include "if_system_ability_manager.h" #include "iservice_registry.h" @@ -66,7 +67,7 @@ __attribute__ ((no_sanitize("cfi"))) int AmsMgrProxy::Connect( want.SetUri(uri); std::lock_guard lock(mutex_); if (ConnectSA()) { - LOG_INFO("connect start, uri = %{public}s", uri.c_str()); + LOG_INFO("connect start, uri = %{public}s", DataShareStringUtils::Change(uri).c_str()); return proxy_->ConnectAbilityCommon(want, connect, callerToken, AppExecFwk::ExtensionAbilityType::DATASHARE); } return -1; diff --git a/data_share/frameworks/native/proxy/src/data_share_manager_impl.cpp b/data_share/frameworks/native/proxy/src/data_share_manager_impl.cpp index 994df0eb..8395eb12 100644 --- a/data_share/frameworks/native/proxy/src/data_share_manager_impl.cpp +++ b/data_share/frameworks/native/proxy/src/data_share_manager_impl.cpp @@ -18,6 +18,7 @@ #include #include "datashare_log.h" +#include "datashare_radar_reporter.h" #include "ikvstore_data_service.h" #include "ipc_skeleton.h" #include "iservice_registry.h" @@ -55,7 +56,6 @@ DataShareManagerImpl* DataShareManagerImpl::GetInstance() return manager_; } - sptr DataShareManagerImpl::GetDistributedDataManager() { auto manager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); @@ -97,6 +97,9 @@ sptr DataShareManagerImpl::GetDataShareServiceProxy() } if (dataMgrService_ == nullptr) { LOG_ERROR("Get distributed data manager failed!"); + RADAR_REPORT(__FUNCTION__, RadarReporter::CREATE_DATASHARE_HELPER, + RadarReporter::DISTRIBUTEDDATA_START, RadarReporter::FAILED, + RadarReporter::ERROR_CODE, RadarReporter::DISTRIBUTEDDATA_NOT_START); return nullptr; } auto remote = dataMgrService_->GetFeatureInterface("data_share"); @@ -234,4 +237,4 @@ void DataShareManagerImpl::OnAddSystemAbility(int32_t systemAbilityId, const std }); } } -} \ No newline at end of file +} diff --git a/data_share/frameworks/native/proxy/src/data_share_service_proxy.cpp b/data_share/frameworks/native/proxy/src/data_share_service_proxy.cpp index 916f1be1..bc14154c 100644 --- a/data_share/frameworks/native/proxy/src/data_share_service_proxy.cpp +++ b/data_share/frameworks/native/proxy/src/data_share_service_proxy.cpp @@ -15,6 +15,7 @@ #include "data_share_service_proxy.h" +#include #include "data_ability_observer_interface.h" #include "datashare_itypes_utils.h" #include "datashare_log.h" @@ -48,7 +49,8 @@ int32_t DataShareServiceProxy::Insert(const Uri &uri, const DataShareValuesBucke int32_t err = Remote()->SendRequest( static_cast(InterfaceCode::DATA_SHARE_SERVICE_CMD_INSERT), data, reply, option); if (err != NO_ERROR) { - LOG_ERROR("Insert fail to SendRequest. uri: %{public}s, err: %{public}d", uriStr.c_str(), err); + LOG_ERROR("Insert fail to sendRequest. uri: %{public}s, err: %{public}d", + DataShareStringUtils::Anonymous(uriStr).c_str(), err); return DATA_SHARE_ERROR; } return reply.ReadInt32(); @@ -73,7 +75,8 @@ int32_t DataShareServiceProxy::Update(const Uri &uri, int32_t err = Remote()->SendRequest( static_cast(InterfaceCode::DATA_SHARE_SERVICE_CMD_UPDATE), data, reply, option); if (err != NO_ERROR) { - LOG_ERROR("Update fail to SendRequest. uri: %{public}s, err: %{public}d", uriStr.c_str(), err); + LOG_ERROR("Update fail to sendRequest. uri: %{public}s, err: %{public}d", + DataShareStringUtils::Anonymous(uriStr).c_str(), err); return DATA_SHARE_ERROR; } return reply.ReadInt32(); @@ -97,7 +100,8 @@ int32_t DataShareServiceProxy::Delete(const Uri &uri, const DataSharePredicates int32_t err = Remote()->SendRequest( static_cast(InterfaceCode::DATA_SHARE_SERVICE_CMD_DELETE), data, reply, option); if (err != NO_ERROR) { - LOG_ERROR("Delete fail to SendRequest. uri: %{public}s, err: %{public}d", uriStr.c_str(), err); + LOG_ERROR("Delete fail to sendRequest. uri: %{public}s, err: %{public}d", + DataShareStringUtils::Anonymous(uriStr).c_str(), err); return DATA_SHARE_ERROR; } return reply.ReadInt32(); @@ -126,7 +130,8 @@ std::shared_ptr DataShareServiceProxy::Query(const Uri &uri, auto result = ISharedResultSet::ReadFromParcel(reply); businessError.SetCode(reply.ReadInt32()); if (err != NO_ERROR) { - LOG_ERROR("Query fail to SendRequest. uri: %{public}s, err: %{public}d", uriStr.c_str(), err); + LOG_ERROR("Query fail to sendRequest. uri: %{public}s, err: %{public}d", + DataShareStringUtils::Anonymous(uriStr).c_str(), err); return nullptr; } return result; @@ -149,7 +154,8 @@ int DataShareServiceProxy::AddQueryTemplate(const std::string &uri, int64_t subs int32_t err = Remote()->SendRequest( static_cast(InterfaceCode::DATA_SHARE_SERVICE_CMD_ADD_TEMPLATE), data, reply, option); if (err != NO_ERROR) { - LOG_ERROR("AddTemplate fail to SendRequest. uri: %{public}s, err: %{public}d", uri.c_str(), err); + LOG_ERROR("AddTemplate fail to sendRequest. uri: %{public}s, err: %{public}d", + DataShareStringUtils::Anonymous(uri).c_str(), err); return DATA_SHARE_ERROR; } return reply.ReadInt32(); @@ -172,7 +178,8 @@ int DataShareServiceProxy::DelQueryTemplate(const std::string &uri, int64_t subs int32_t err = Remote()->SendRequest( static_cast(InterfaceCode::DATA_SHARE_SERVICE_CMD_DEL_TEMPLATE), data, reply, option); if (err != NO_ERROR) { - LOG_ERROR("AddTemplate fail to SendRequest. uri: %{public}s, err: %{public}d", uri.c_str(), err); + LOG_ERROR("Delete template fail to sendRequest. uri: %{public}s, err: %{public}d", + DataShareStringUtils::Anonymous(uri).c_str(), err); return DATA_SHARE_ERROR; } return reply.ReadInt32(); @@ -196,7 +203,7 @@ std::vector DataShareServiceProxy::Publish(const Data &data, co int32_t err = Remote()->SendRequest( static_cast(InterfaceCode::DATA_SHARE_SERVICE_CMD_PUBLISH), parcel, reply, option); if (err != NO_ERROR) { - LOG_ERROR("Publish fail to SendRequest. err: %{public}d", err); + LOG_ERROR("Publish fail to sendRequest. err: %{public}d", err); return results; } @@ -222,7 +229,7 @@ Data DataShareServiceProxy::GetPublishedData(const std::string &bundleName, int int32_t err = Remote()->SendRequest( static_cast(InterfaceCode::DATA_SHARE_SERVICE_CMD_GET_DATA), data, reply, option); if (err != NO_ERROR) { - LOG_ERROR("AddTemplate fail to SendRequest, err: %{public}d", err); + LOG_ERROR("Get published data fail to sendRequest, err: %{public}d", err); return results; } ITypesUtil::Unmarshal(reply, results.datas_, resultCode); @@ -233,6 +240,10 @@ std::vector DataShareServiceProxy::SubscribeRdbData(const std:: const TemplateId &templateId, const sptr &observer) { std::vector results; + if (observer == nullptr) { + LOG_ERROR("Observer is nullptr, subscriberId: %{public}" PRId64, templateId.subscriberId_); + return results; + } MessageParcel data; if (!data.WriteInterfaceToken(IDataShareService::GetDescriptor())) { LOG_ERROR("Write descriptor failed!"); @@ -244,7 +255,7 @@ std::vector DataShareServiceProxy::SubscribeRdbData(const std:: return results; } if (!data.WriteRemoteObject(observer->AsObject())) { - LOG_ERROR("failed to WriteParcelable dataObserver "); + LOG_ERROR("Failed to write parcelable dataObserver "); return results; } @@ -253,7 +264,7 @@ std::vector DataShareServiceProxy::SubscribeRdbData(const std:: int32_t err = Remote()->SendRequest( static_cast(InterfaceCode::DATA_SHARE_SERVICE_CMD_SUBSCRIBE_RDB), data, reply, option); if (err != NO_ERROR) { - LOG_ERROR("SubscribeRdbData fail to SendRequest. err: %{public}d", err); + LOG_ERROR("SubscribeRdbData fail to sendRequest. err: %{public}d", err); return results; } ITypesUtil::Unmarshal(reply, results); @@ -280,7 +291,7 @@ std::vector DataShareServiceProxy::UnSubscribeRdbData( int32_t err = Remote()->SendRequest( static_cast(InterfaceCode::DATA_SHARE_SERVICE_CMD_UNSUBSCRIBE_RDB), data, reply, option); if (err != NO_ERROR) { - LOG_ERROR("fail to SendRequest. err: %{public}d", err); + LOG_ERROR("Fail to sendRequest. err: %{public}d", err); return results; } ITypesUtil::Unmarshal(reply, results); @@ -307,7 +318,7 @@ std::vector DataShareServiceProxy::EnableSubscribeRdbData( int32_t err = Remote()->SendRequest( static_cast(InterfaceCode::DATA_SHARE_SERVICE_CMD_ENABLE_SUBSCRIBE_RDB), data, reply, option); if (err != NO_ERROR) { - LOG_ERROR("fail to SendRequest. err: %{public}d", err); + LOG_ERROR("Fail to sendRequest. err: %{public}d", err); return results; } ITypesUtil::Unmarshal(reply, results); @@ -334,7 +345,7 @@ std::vector DataShareServiceProxy::DisableSubscribeRdbData( int32_t err = Remote()->SendRequest( static_cast(InterfaceCode::DATA_SHARE_SERVICE_CMD_DISABLE_SUBSCRIBE_RDB), data, reply, option); if (err != NO_ERROR) { - LOG_ERROR("AddTemplate fail to SendRequest. err: %{public}d", err); + LOG_ERROR("Disable subscribe RdbData fail to sendRequest. err: %{public}d", err); return results; } ITypesUtil::Unmarshal(reply, results); @@ -345,6 +356,10 @@ std::vector DataShareServiceProxy::SubscribePublishedData( const std::vector &uris, int64_t subscriberId, const sptr &observer) { std::vector results; + if (observer == nullptr) { + LOG_ERROR("Observer is nullptr, subscriberId: %{public}" PRId64, subscriberId); + return results; + } MessageParcel data; if (!data.WriteInterfaceToken(IDataShareService::GetDescriptor())) { LOG_ERROR("Write descriptor failed!"); @@ -355,7 +370,7 @@ std::vector DataShareServiceProxy::SubscribePublishedData( return results; } if (!data.WriteRemoteObject(observer->AsObject())) { - LOG_ERROR("failed to WriteRemoteObject dataObserver "); + LOG_ERROR("Failed to write remote object dataObserver "); return results; } @@ -364,7 +379,7 @@ std::vector DataShareServiceProxy::SubscribePublishedData( int32_t err = Remote()->SendRequest( static_cast(InterfaceCode::DATA_SHARE_SERVICE_CMD_SUBSCRIBE_PUBLISHED), data, reply, option); if (err != NO_ERROR) { - LOG_ERROR("AddTemplate fail to SendRequest. err: %{public}d", err); + LOG_ERROR("Subscribe published data fail to sendRequest. err: %{public}d", err); return results; } ITypesUtil::Unmarshal(reply, results); @@ -390,7 +405,7 @@ std::vector DataShareServiceProxy::UnSubscribePublishedData( int32_t err = Remote()->SendRequest( static_cast(InterfaceCode::DATA_SHARE_SERVICE_CMD_UNSUBSCRIBE_PUBLISHED), data, reply, option); if (err != NO_ERROR) { - LOG_ERROR("AddTemplate fail to SendRequest. err: %{public}d", err); + LOG_ERROR("UnSubscribe published data fail to sendRequest. err: %{public}d", err); return results; } ITypesUtil::Unmarshal(reply, results); @@ -416,7 +431,7 @@ std::vector DataShareServiceProxy::EnableSubscribePublishedData int32_t err = Remote()->SendRequest( static_cast(InterfaceCode::DATA_SHARE_SERVICE_CMD_ENABLE_SUBSCRIBE_PUBLISHED), data, reply, option); if (err != NO_ERROR) { - LOG_ERROR("AddTemplate fail to SendRequest. err: %{public}d", err); + LOG_ERROR("Enable subscribe published data fail to sendRequest. err: %{public}d", err); return results; } ITypesUtil::Unmarshal(reply, results); @@ -442,7 +457,7 @@ std::vector DataShareServiceProxy::DisableSubscribePublishedDat int32_t err = Remote()->SendRequest( static_cast(InterfaceCode::DATA_SHARE_SERVICE_CMD_DISABLE_SUBSCRIBE_PUBLISHED), data, reply, option); if (err != NO_ERROR) { - LOG_ERROR("AddTemplate fail to SendRequest. err: %{public}d", err); + LOG_ERROR("Disable subscribe published data fail to sendRequest. err: %{public}d", err); return results; } ITypesUtil::Unmarshal(reply, results); @@ -466,7 +481,7 @@ void DataShareServiceProxy::Notify(const std::string &uri) int32_t err = Remote()->SendRequest( static_cast(InterfaceCode::DATA_SHARE_SERVICE_CMD_NOTIFY_OBSERVERS), data, reply, option); if (err != NO_ERROR) { - LOG_ERROR("Notify fail to SendRequest. err: %{public}d", err); + LOG_ERROR("Notify fail to sendRequest. err: %{public}d", err); return; } } @@ -489,37 +504,35 @@ int DataShareServiceProxy::SetSilentSwitch(const Uri &uri, bool enable) int32_t err = Remote()->SendRequest( static_cast(InterfaceCode::DATA_SHARE_SERVICE_CMD_SET_SILENT_SWITCH), data, reply, option); if (err != NO_ERROR) { - LOG_ERROR("SetSilentSwitch fail to SendRequest. uri: %{public}s, err: %{public}d", uriStr.c_str(), err); + LOG_ERROR("SetSilentSwitch fail to sendRequest. uri: %{public}s, err: %{public}d", + DataShareStringUtils::Anonymous(uriStr).c_str(), err); return DATA_SHARE_ERROR; } return reply.ReadInt32(); } -bool DataShareServiceProxy::IsSilentProxyEnable(const std::string &uri) +int DataShareServiceProxy::GetSilentProxyStatus(const std::string &uri) { MessageParcel data; if (!data.WriteInterfaceToken(IDataShareService::GetDescriptor())) { LOG_ERROR("Write descriptor failed!"); - return false; + return DATA_SHARE_ERROR; } if (!ITypesUtil::Marshal(data, uri)) { LOG_ERROR("Write to message parcel failed!"); - return false; + return DATA_SHARE_ERROR; } MessageParcel reply; MessageOption option; int32_t err = Remote()->SendRequest( - static_cast(InterfaceCode::DATA_SHARE_SERVICE_CMD_IS_SILENT_PROXY_ENABLE), data, reply, option); + static_cast(InterfaceCode::DATA_SHARE_SERVICE_CMD_GET_SILENT_PROXY_STATUS), data, reply, option); if (err != NO_ERROR) { - LOG_ERROR("Is silent proxy enable fail to SendRequest. uri: %{public}s, err: %{public}d", uri.c_str(), err); - return false; - } - bool enable = false; - if (!ITypesUtil::Unmarshal(reply, enable)) { - LOG_ERROR("Is silent proxy Unmarshal failed."); + LOG_ERROR("Is silent proxy enable fail to sendRequest. uri: %{public}s, err: %{public}d", + DataShareStringUtils::Anonymous(uri).c_str(), err); + return DATA_SHARE_ERROR; } - return enable; + return reply.ReadInt32(); } int DataShareServiceProxy::RegisterObserver(const Uri &uri, const sptr &dataObserver) diff --git a/data_share/frameworks/native/proxy/src/published_data_subscriber_manager.cpp b/data_share/frameworks/native/proxy/src/published_data_subscriber_manager.cpp index 24314937..fe41f1d3 100644 --- a/data_share/frameworks/native/proxy/src/published_data_subscriber_manager.cpp +++ b/data_share/frameworks/native/proxy/src/published_data_subscriber_manager.cpp @@ -15,8 +15,11 @@ #include "published_data_subscriber_manager.h" +#include + #include "data_proxy_observer_stub.h" #include "datashare_log.h" +#include "datashare_string_utils.h" namespace OHOS { namespace DataShare { @@ -113,10 +116,6 @@ std::vector PublishedDataSubscriberManager::DelObservers(void * return; } auto unsubResult = proxy->UnSubscribePublishedData(lastDelUris, subscriberId); - if (BaseCallbacks::GetEnabledSubscriberSize() == 0) { - LOG_INFO("no valid subscriber, delete callback"); - serviceCallback_ = nullptr; - } opResult.insert(opResult.end(), unsubResult.begin(), unsubResult.end()); Destroy(); }); @@ -262,15 +261,21 @@ void PublishedDataSubscriberManager::EmitOnEnable(std::mapsecond.datas_) { PublishedObserverMapKey mapKey(data.key_, data.subscriberId_); for (auto &obs : obsVector) { if (obs.isNotifyOnEnabled_) { + num++; results[obs.observer_].datas_.emplace_back(data.key_, data.subscriberId_, data.GetData()); results[obs.observer_].ownerBundleName_ = it->second.ownerBundleName_; } } } + if (num > 0) { + LOG_INFO("%{public}u will refresh, total %{public}zu, uri %{public}s, subscribeId %{public}" PRId64, + num, obsVector.size(), DataShareStringUtils::Anonymous(key.uri_).c_str(), key.subscriberId_); + } } for (auto &[callback, node] : results) { callback->OnChange(node); @@ -290,7 +295,7 @@ bool PublishedDataSubscriberManager::Init() void PublishedDataSubscriberManager::Destroy() { - if (BaseCallbacks::GetEnabledSubscriberSize() == 0) { + if (BaseCallbacks::GetAllSubscriberSize() == 0) { if (serviceCallback_ != nullptr) { serviceCallback_->ClearCallback(); } diff --git a/data_share/frameworks/native/proxy/src/rdb_subscriber_manager.cpp b/data_share/frameworks/native/proxy/src/rdb_subscriber_manager.cpp index ab2fbba5..4c7ed30c 100644 --- a/data_share/frameworks/native/proxy/src/rdb_subscriber_manager.cpp +++ b/data_share/frameworks/native/proxy/src/rdb_subscriber_manager.cpp @@ -104,10 +104,6 @@ std::vector RdbSubscriberManager::DelObservers(void *subscriber return; } auto unsubResult = proxy->UnSubscribeRdbData(lastDelUris, templateId); - if (BaseCallbacks::GetEnabledSubscriberSize() == 0) { - LOG_INFO("no valid subscriber, delete callback"); - serviceCallback_ = nullptr; - } opResult.insert(opResult.end(), unsubResult.begin(), unsubResult.end()); Destroy(); }); @@ -272,7 +268,7 @@ bool RdbSubscriberManager::Init() void RdbSubscriberManager::Destroy() { - if (BaseCallbacks::GetEnabledSubscriberSize() == 0) { + if (BaseCallbacks::GetAllSubscriberSize() == 0) { if (serviceCallback_ != nullptr) { serviceCallback_->ClearCallback(); } diff --git a/data_share/interfaces/inner_api/BUILD.gn b/data_share/interfaces/inner_api/BUILD.gn index bbb2b9c0..fabe3a7c 100644 --- a/data_share/interfaces/inner_api/BUILD.gn +++ b/data_share/interfaces/inner_api/BUILD.gn @@ -13,7 +13,6 @@ import("//build/ohos.gni") import("//foundation/distributeddatamgr/data_share/datashare.gni") -import("//foundation/distributeddatamgr/relational_store/relational_store.gni") config("ability_config") { visibility = [ ":*" ] @@ -21,11 +20,9 @@ config("ability_config") { "common/include", "consumer/include", "provider/include", - "${ability_runtime_services_path}/common/include", "${datashare_native_consumer_path}/include", "${datashare_native_provider_path}/include", "${datashare_native_proxy_path}/include", - "${ability_runtime_napi_path}/inner/napi_common", ] cflags = [] @@ -47,8 +44,6 @@ config("datashare_public_config") { "${datashare_native_consumer_path}/include", "${datashare_native_provider_path}/include", "${datashare_native_proxy_path}/include", - "${kvstore_common_path}", - "${ability_runtime_inner_api_path}/dataobs_manager/include", ] } @@ -76,11 +71,11 @@ datashare_consumer_external_deps = [ "ability_base:want", "ability_base:zuri", "ability_runtime:app_context", - "ability_runtime:dataobs_manager", "ability_runtime:extension_manager", "c_utils:utils", "common_event_service:cesfwk_innerkits", "hilog:libhilog", + "hisysevent:libhisysevent", "hitrace:hitrace_meter", "hitrace:libhitracechain", "ipc:ipc_single", @@ -109,15 +104,13 @@ config("permission_public_config") { ohos_shared_library("datashare_consumer") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false } - include_dirs = [ - "${datashare_common_native_path}/include", - "${kvstore_base_path}/frameworks/common", - "${kvstore_base_path}/interfaces/innerkits/distributeddata/include", - ] + include_dirs = [ "${datashare_common_native_path}/include" ] sources = datashare_consumer_sources configs = [ ":ability_config" ] @@ -130,6 +123,12 @@ ohos_shared_library("datashare_consumer") { deps = [ "${datashare_innerapi_path}/common:datashare_common" ] external_deps = datashare_consumer_external_deps + external_deps += [ "ability_runtime:ability_connect_callback_stub" ] + + public_external_deps = [ + "ability_runtime:dataobs_manager", + "kv_store:distributeddata_inner", + ] subsystem_name = "distributeddatamgr" part_name = "data_share" @@ -138,6 +137,8 @@ ohos_shared_library("datashare_consumer") { ohos_shared_library("datashare_permission") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false @@ -177,14 +178,13 @@ ohos_shared_library("datashare_permission") { ohos_shared_library("datashare_provider") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false } - include_dirs = [ - "${datashare_common_napi_path}/include", - "${kvstore_common_path}", - ] + include_dirs = [ "${datashare_common_napi_path}/include" ] sources = [ "${datashare_common_native_path}/src/datashare_string_utils.cpp", @@ -208,21 +208,27 @@ ohos_shared_library("datashare_provider") { external_deps = [ "ability_base:want", "ability_base:zuri", + "ability_runtime:ability_connect_callback_stub", "ability_runtime:ability_context_native", "ability_runtime:abilitykit_native", "ability_runtime:app_context", - "ability_runtime:dataobs_manager", + "ability_runtime:extensionkit_native", + "ability_runtime:napi_common", "ability_runtime:runtime", "access_token:libaccesstoken_sdk", "c_utils:utils", "common_event_service:cesfwk_innerkits", "hilog:libhilog", + "hisysevent:libhisysevent", "ipc:ipc_napi", "ipc:ipc_single", + "kv_store:distributeddata_inner", "napi:ace_napi", "samgr:samgr_proxy", ] + public_external_deps = [ "ability_runtime:dataobs_manager" ] + subsystem_name = "distributeddatamgr" part_name = "data_share" } @@ -230,6 +236,8 @@ ohos_shared_library("datashare_provider") { ohos_shared_library("datashare_ext_ability_module") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false @@ -261,15 +269,13 @@ ohos_shared_library("datashare_ext_ability_module") { ohos_static_library("datashare_consumer_static") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false } - include_dirs = [ - "${datashare_common_native_path}/include", - "${kvstore_base_path}/frameworks/common", - "${kvstore_base_path}/interfaces/innerkits/distributeddata/include", - ] + include_dirs = [ "${datashare_common_native_path}/include" ] sources = datashare_consumer_sources configs = [ ":ability_config" ] @@ -278,6 +284,8 @@ ohos_static_library("datashare_consumer_static") { external_deps = datashare_consumer_external_deps + public_external_deps = [ "kv_store:distributeddata_inner" ] + subsystem_name = "distributeddatamgr" part_name = "data_share" } diff --git a/data_share/interfaces/inner_api/common/BUILD.gn b/data_share/interfaces/inner_api/common/BUILD.gn index ac3fc3de..dd28c64e 100644 --- a/data_share/interfaces/inner_api/common/BUILD.gn +++ b/data_share/interfaces/inner_api/common/BUILD.gn @@ -36,7 +36,6 @@ datashare_common_include_dirs = [ "${datashare_base_path}/interfaces/inner_api/consumer/include", "${datashare_base_path}/interfaces/inner_api/provider/include", "${datashare_native_proxy_path}/include", - "${kvstore_base_path}/frameworks/common", ] datashare_common_sources = [ @@ -61,11 +60,14 @@ datashare_common_external_deps = [ "hitrace:hitrace_meter", "hitrace:libhitracechain", "ipc:ipc_single", + "kv_store:distributeddata_inner", ] ohos_shared_library("datashare_common") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false @@ -95,6 +97,8 @@ ohos_shared_library("datashare_common") { ohos_static_library("datashare_common_static") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false diff --git a/data_share/interfaces/inner_api/common/include/datashare_errno.h b/data_share/interfaces/inner_api/common/include/datashare_errno.h index e2e8c7f0..3bdf68dc 100644 --- a/data_share/interfaces/inner_api/common/include/datashare_errno.h +++ b/data_share/interfaces/inner_api/common/include/datashare_errno.h @@ -89,6 +89,32 @@ constexpr int E_URI_NOT_EXIST = (E_BASE + 48); * @brief Cannot find the bundleName */ constexpr int E_BUNDLE_NAME_NOT_EXIST = (E_BASE + 49); + +/** +* @brief BMS not ready +*/ +constexpr int E_BMS_NOT_READY = (E_BASE + 50); + +/** +* @brief metaData not exists +*/ +constexpr int E_METADATA_NOT_EXISTS = (E_BASE + 51); +/** +* @brief silent proxy is disable +*/ +constexpr int E_SILENT_PROXY_DISABLE = (E_BASE + 52); +/** +* @brief token is empty +*/ +constexpr int E_TOKEN_EMPTY = (E_BASE + 53); +/** +* @brief ext uri is empty +*/ +constexpr int E_EXT_URI_INVALID = (E_BASE + 54); +/** +* @brief DataShare not ready +*/ +constexpr int E_DATA_SHARE_NOT_READY = (E_BASE + 55); } // namespace DataShare } // namespace OHOS diff --git a/data_share/interfaces/inner_api/consumer/include/datashare_helper.h b/data_share/interfaces/inner_api/consumer/include/datashare_helper.h index dca7ae45..7e7efc9a 100644 --- a/data_share/interfaces/inner_api/consumer/include/datashare_helper.h +++ b/data_share/interfaces/inner_api/consumer/include/datashare_helper.h @@ -73,6 +73,19 @@ public: static std::shared_ptr Creator(const std::string &strUri, const CreateOptions &options, const std::string &bundleName = ""); + /** + * @brief Creates a DataShareHelper instance, priority silent access, use non-silent access when silent is not + * available, at this time, it is necessary to apply for communication permission with the extension. + * + * @param token Indicates the System token. + * @param strUri Indicates the database table or disk file to operate for silent access. + * @param extUri Indicates the database table or disk file to operate for non silent access. + * + * @return Returns the created DataShareHelper instance with a specified Uri. + */ + static std::pair> Create(const sptr &token, + const std::string &strUri, const std::string &extUri); + /** * @brief Releases the client resource of the Data share. * You should call this method to releases client resource after the data operations are complete. @@ -403,12 +416,16 @@ public: private: static std::shared_ptr CreateServiceHelper(const std::string &bundleName = ""); - static bool IsSilentProxyEnable(const std::string &uri); + static int GetSilentProxyStatus(const std::string &uri); static std::shared_ptr CreateExtHelper(Uri &uri, const sptr &token); static std::string TransferUriPrefix(const std::string &originPrefix, const std::string &replacedPrefix, const std::string &originUriStr); + + static bool IsProxy(Uri &uri); + + static std::pair> CreateProxyHelper(const std::string &strUri); }; } // namespace DataShare } // namespace OHOS diff --git a/data_share/test/native/BUILD.gn b/data_share/test/native/BUILD.gn index ea8049ed..f2ac1cff 100644 --- a/data_share/test/native/BUILD.gn +++ b/data_share/test/native/BUILD.gn @@ -309,10 +309,6 @@ ohos_unittest("ControllerTest") { module_out_path = "data_share/native_datashare" include_dirs = [ - "${ability_runtime_inner_api_path}/ability_manager/include", - "${ability_runtime_inner_api_path}/app_manager/include/appmgr", - "${ability_runtime_inner_api_path}/dataobs_manager/include", - "${ability_runtime_path}/interfaces/kits/native/ability/native", "${access_token_path}/frameworks/common/include", "${base_hiviewdfx_hilog_path}/interfaces/native/innerkits/include", "${foundation_path}/aafwk/standard/interfaces/innerkits/uri/include", @@ -327,7 +323,6 @@ ohos_unittest("ControllerTest") { "${datashare_native_consumer_path}/include", "${datashare_innerapi_path}/common/include", "${datashare_native_proxy_path}/include", - "${ability_runtime_inner_api_path}/extension_manager/include/", ] sources = [ "./unittest/mediadatashare_test/src/controller_test.cpp" ] @@ -343,6 +338,7 @@ ohos_unittest("ControllerTest") { "ability_runtime:ability_manager", "ability_runtime:abilitykit_native", "ability_runtime:dataobs_manager", + "ability_runtime:extension_manager", "access_token:libaccesstoken_sdk", "access_token:libnativetoken", "access_token:libtoken_setproc", @@ -401,10 +397,7 @@ ohos_unittest("AbnormalBranchTest") { ohos_unittest("ValueProxyTest") { module_out_path = "data_share/native_datashare" - include_dirs = [ - "${datashare_base_path}/frameworks/native/common/include/", - "${kvstore_base_path}/frameworks/common", - ] + include_dirs = [ "${datashare_base_path}/frameworks/native/common/include/" ] sources = [ "./unittest/mediadatashare_test/src/valueproxy_test.cpp" ] @@ -414,5 +407,6 @@ ohos_unittest("ValueProxyTest") { "c_utils:utils", "hilog:libhilog", "ipc:ipc_single", + "kv_store:distributeddata_inner", ] } diff --git a/data_share/test/native/unittest/mediadatashare_test/src/errorcode_test.cpp b/data_share/test/native/unittest/mediadatashare_test/src/errorcode_test.cpp index e96994db..fa0fcb94 100644 --- a/data_share/test/native/unittest/mediadatashare_test/src/errorcode_test.cpp +++ b/data_share/test/native/unittest/mediadatashare_test/src/errorcode_test.cpp @@ -20,6 +20,7 @@ #include "datashare_log.h" #include "hap_token_info.h" #include "iservice_registry.h" +#include "rdb_errno.h" #include "system_ability_definition.h" #include "token_setproc.h" @@ -28,6 +29,12 @@ namespace DataShare { using namespace testing::ext; using namespace OHOS::Security::AccessToken; constexpr int STORAGE_MANAGER_MANAGER_ID = 5003; +//std::string DATA_SHARE_URI = "datashare:///com.acts.errorcodetest"; +//std::string SLIENT_ACCESS_URI = "datashare:///com.acts.errorcodetest/entry/DB00/TBL00?Proxy=true"; +//std::string TBL_STU_NAME = "name"; +//std::string TBL_STU_AGE = "age"; +//std::shared_ptr g_slientAccessHelper; +//std::shared_ptr dataShareHelper; class ErrorCodeTest : public testing::Test { public: @@ -161,8 +168,7 @@ HWTEST_F(ErrorCodeTest, ErrorCodeTest_QUERY_Test_001, TestSize.Level0) Uri uriErr(ERR_SLIENT_ACCESS_URI); DatashareBusinessError error; resultSet = helper->Query(uriErr, predicates, columns, &error); - int errDbNotExists = 14800045; - EXPECT_EQ(error.GetCode(), errDbNotExists); + EXPECT_EQ(error.GetCode(), NativeRdb::E_DB_NOT_EXIST); EXPECT_EQ(resultSet, nullptr); LOG_INFO("ErrorCodeTest_QUERY_Test_001::End"); } diff --git a/data_share/test/native/unittest/mediadatashare_test/src/slientaccess_test.cpp b/data_share/test/native/unittest/mediadatashare_test/src/slientaccess_test.cpp index 18bba4d5..a5ab5b7a 100644 --- a/data_share/test/native/unittest/mediadatashare_test/src/slientaccess_test.cpp +++ b/data_share/test/native/unittest/mediadatashare_test/src/slientaccess_test.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include "accesstoken_kit.h" #include "data_ability_observer_stub.h" @@ -31,6 +32,41 @@ using namespace testing::ext; using namespace OHOS::Security::AccessToken; constexpr int STORAGE_MANAGER_MANAGER_ID = 5003; static int USER_100 = 100; +template +class ConditionLock { +public: + explicit ConditionLock() {} + ~ConditionLock() {} +public: + void Notify() + { + std::lock_guard lock(mutex_); + isSet_ = true; + cv_.notify_one(); + } + + void Wait() + { + std::unique_lock lock(mutex_); + cv_.wait_for(lock, std::chrono::seconds(INTERVAL), [this]() { return isSet_; }); + cv_.notify_one(); + return; + } + + void Clear() + { + std::lock_guard lock(mutex_); + isSet_ = false; + cv_.notify_one(); + } + +private: + bool isSet_ = false; + T data_; + std::mutex mutex_; + std::condition_variable cv_; + static constexpr int64_t INTERVAL = 2; +}; class SlientAccessTest : public testing::Test { public: @@ -64,6 +100,7 @@ public: void OnChange() { name = "OnChangeName"; + data.Notify(); } std::string GetName() @@ -75,6 +112,12 @@ public: { this->name = name; } + + void Clear() + { + data.Clear(); + } + ConditionLock data; private: std::string name; }; @@ -254,7 +297,9 @@ HWTEST_F(SlientAccessTest, SlientAccess_Register_Test_001, TestSize.Level0) valuesBucket.Put(TBL_STU_AGE, age); int retVal = helper->Insert(uri, valuesBucket); EXPECT_EQ((retVal > 0), true); + dataObserver->data.Wait(); EXPECT_EQ(dataObserver->GetName(), "OnChangeName"); + dataObserver->Clear(); DataShare::DataSharePredicates deletePredicates; deletePredicates.EqualTo(TBL_STU_NAME, "lisi")->And()->EqualTo(TBL_STU_NAME, 25); diff --git a/datamgr_service/bundle.json b/datamgr_service/bundle.json index 3a89e666..c4a0ef43 100644 --- a/datamgr_service/bundle.json +++ b/datamgr_service/bundle.json @@ -64,6 +64,7 @@ "device_manager", "dfs_service", "dsoftbus", + "hicollie", "hilog", "hisysevent", "hitrace", @@ -71,6 +72,7 @@ "kv_store", "image_framework", "ipc", + "memmgr", "napi", "netmanager_base", "os_account", @@ -80,13 +82,13 @@ "samgr", "time_service", "udmf", - "app_file_service" + "app_file_service", + "file_api", + "openssl", + "json" ], "third_party": [ - "cJSON", - "jsoncpp", "libuv", - "openssl", "sqlite", "zlib" ] diff --git a/datamgr_service/datamgr_service.gni b/datamgr_service/datamgr_service.gni index 8a79ca9d..64b9838f 100644 --- a/datamgr_service/datamgr_service.gni +++ b/datamgr_service/datamgr_service.gni @@ -11,8 +11,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -distributedfilejs_path = "//foundation/distributeddatamgr/distributedfile" - kv_store_path = "//foundation/distributeddatamgr/kv_store" relational_store_path = "//foundation/distributeddatamgr/relational_store" diff --git a/datamgr_service/services/distributeddataservice/adapter/BUILD.gn b/datamgr_service/services/distributeddataservice/adapter/BUILD.gn index 44bef8b3..ae76a3ce 100644 --- a/datamgr_service/services/distributeddataservice/adapter/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/adapter/BUILD.gn @@ -68,7 +68,7 @@ ohos_shared_library("distributeddata_adapter") { "hitrace:hitrace_meter", "hitrace:libhitracechain", ] - + public_external_deps = [ "device_manager:devicemanagersdk" ] public_configs = [ ":distributeddata_adapter_public_config" ] subsystem_name = "distributeddatamgr" diff --git a/datamgr_service/services/distributeddataservice/adapter/account/BUILD.gn b/datamgr_service/services/distributeddataservice/adapter/account/BUILD.gn index ac7975c7..95465797 100644 --- a/datamgr_service/services/distributeddataservice/adapter/account/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/adapter/account/BUILD.gn @@ -19,6 +19,8 @@ ohos_static_library("distributeddata_account_static") { cfi = true cfi_cross_dso = true debug = false + boundary_sanitize = true + ubsan = true } sources = [ "src/account_delegate.cpp", @@ -35,7 +37,6 @@ ohos_static_library("distributeddata_account_static") { "${kv_store_common_path}", "${kv_store_path}/interfaces/innerkits/distributeddata/include", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/framework/include", - "${ipc_core_path}/include", ] cflags_cc = [ "-fvisibility=hidden" ] diff --git a/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.cpp b/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.cpp index 0b42cd23..7cf33587 100644 --- a/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.cpp @@ -56,6 +56,12 @@ bool AccountDelegateDefaultImpl::QueryForegroundUsers(std::vector &users) return true; } +bool AccountDelegateDefaultImpl::IsLoginAccount() +{ + ZLOGD("no account login."); + return false; +} + bool AccountDelegateDefaultImpl::IsVerified(int userId) { ZLOGD("no account part."); diff --git a/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.h b/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.h index 65033385..74298cb5 100644 --- a/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.h +++ b/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_default_impl.h @@ -26,6 +26,7 @@ public: int32_t GetUserByToken(uint32_t tokenId) const override; bool QueryUsers(std::vector &users) override; bool QueryForegroundUsers(std::vector &users) override; + bool IsLoginAccount() override; bool IsVerified(int userId) override; void SubscribeAccountEvent() override; void UnsubscribeAccountEvent() override; diff --git a/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.cpp b/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.cpp index 9656f8ff..edc5a7a9 100644 --- a/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.cpp @@ -70,7 +70,7 @@ int32_t AccountDelegateNormalImpl::GetUserByToken(uint32_t tokenId) const } return tokenInfo.userID; } - + bool AccountDelegateNormalImpl::QueryUsers(std::vector &users) { users = {0}; // default user @@ -89,6 +89,11 @@ bool AccountDelegateNormalImpl::QueryForegroundUsers(std::vector &users) return true; } +bool AccountDelegateNormalImpl::IsLoginAccount() +{ + return GetCurrentAccountId() != AccountSA::DEFAULT_OHOS_ACCOUNT_UID; +} + bool AccountDelegateNormalImpl::IsVerified(int userId) { auto [success, res] = userStatus_.Find(userId); @@ -105,17 +110,19 @@ bool AccountDelegateNormalImpl::IsVerified(int userId) void AccountDelegateNormalImpl::SubscribeAccountEvent() { ZLOGI("Subscribe account event listener start."); - MatchingSkills matchingSkills; - matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_REMOVED); - matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_SWITCHED); - matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_UNLOCKED); - CommonEventSubscribeInfo info(matchingSkills); - eventSubscriber_ = std::make_shared(info); - eventSubscriber_->SetEventCallback([this](AccountEventInfo& account) { - UpdateUserStatus(account); - account.harmonyAccountId = GetCurrentAccountId(); - NotifyAccountChanged(account); - }); + if (eventSubscriber_ == nullptr) { + MatchingSkills matchingSkills; + matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_REMOVED); + matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_SWITCHED); + matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_UNLOCKED); + CommonEventSubscribeInfo info(matchingSkills); + eventSubscriber_ = std::make_shared(info); + eventSubscriber_->SetEventCallback([this](AccountEventInfo& account) { + UpdateUserStatus(account); + account.harmonyAccountId = GetCurrentAccountId(); + NotifyAccountChanged(account); + }); + } executors_->Execute(GetTask(0)); } @@ -195,5 +202,21 @@ void AccountDelegateNormalImpl::BindExecutor(std::shared_ptr execu { executors_ = executors; } + +std::string AccountDelegateNormalImpl::GetUnencryptedAccountId(int32_t userId) const +{ + AccountSA::OhosAccountInfo info; + auto ret = AccountSA::OhosAccountKits::GetInstance().GetOhosAccountInfoByUserId(userId, info); + if (ret != ERR_OK) { + ZLOGE("GetUnencryptedAccountId failed: %{public}d", ret); + return ""; + } + return Sha256AccountId(info.GetRawUid()); +} + +bool AccountDelegateNormalImpl::QueryForegroundUserId(int &foregroundUserId) +{ + return AccountSA::OsAccountManager::GetForegroundOsAccountLocalId(foregroundUserId); +} } // namespace DistributedKv } // namespace OHOS \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.h b/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.h index 1b9e915a..758e25d4 100644 --- a/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.h +++ b/datamgr_service/services/distributeddataservice/adapter/account/src/account_delegate_normal_impl.h @@ -31,10 +31,13 @@ public: int32_t GetUserByToken(uint32_t tokenId) const override; bool QueryUsers(std::vector &users) override; bool QueryForegroundUsers(std::vector &users) override; + bool IsLoginAccount() override; bool IsVerified(int userId) override; void SubscribeAccountEvent() override; void UnsubscribeAccountEvent() override; void BindExecutor(std::shared_ptr executors) override; + std::string GetUnencryptedAccountId(int32_t userId = 0) const override; + bool QueryForegroundUserId(int &foregroundUserId) override; private: ~AccountDelegateNormalImpl(); diff --git a/datamgr_service/services/distributeddataservice/adapter/account/test/BUILD.gn b/datamgr_service/services/distributeddataservice/adapter/account/test/BUILD.gn index 26d316ca..1fb62f2e 100644 --- a/datamgr_service/services/distributeddataservice/adapter/account/test/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/adapter/account/test/BUILD.gn @@ -11,7 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. import("//build/test.gni") - +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") module_output_path = "datamgr_service/distributeddatafwk" ############################################################################### @@ -26,6 +26,11 @@ ohos_unittest("AccountDelegateTest") { "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/include/autils", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/include/utils", "//foundation/distributeddatamgr/kv_store/frameworks/common", + "${data_service_path}/adapter/account/src", + ] + cflags = [ + "-Dprivate=public", + "-Dprotected=public", ] deps = [ @@ -40,6 +45,9 @@ ohos_unittest("AccountDelegateTest") { "c_utils:utils", "hilog:libhilog", "ipc:ipc_core", + "kv_store:distributeddata_inner", + "kv_store:distributeddata_mgr", + "kv_store:distributeddb", "os_account:libaccountkits", "os_account:os_account_innerkits", ] diff --git a/datamgr_service/services/distributeddataservice/adapter/account/test/account_delegate_test.cpp b/datamgr_service/services/distributeddataservice/adapter/account/test/account_delegate_test.cpp index 82964195..21a0c5fc 100644 --- a/datamgr_service/services/distributeddataservice/adapter/account/test/account_delegate_test.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/account/test/account_delegate_test.cpp @@ -17,11 +17,12 @@ #include #include #include "account_delegate.h" +#include "account_delegate_impl.h" +#include "account_delegate_normal_impl.h" #include "ipc_skeleton.h" #include "ohos_account_kits.h" #include "os_account_manager.h" #include "log_print.h" - namespace { using namespace OHOS::DistributedKv; using namespace testing::ext; @@ -60,10 +61,12 @@ protected: static const std::string DEFAULT_OHOS_ACCOUNT_UID; static const uint32_t INVALID_TOKEN_ID; static const int32_t INVALID_USER; + static const int userId; }; const std::string AccountDelegateTest::DEFAULT_OHOS_ACCOUNT_UID = "ohosAnonymousUid"; const uint32_t AccountDelegateTest::INVALID_TOKEN_ID = -1; const int32_t AccountDelegateTest::INVALID_USER = -1; +const int AccountDelegateTest::userId = 100; /** * @tc.name: Subscribe001 @@ -103,6 +106,27 @@ HWTEST_F(AccountDelegateTest, Subscribe002, TestSize.Level0) EXPECT_EQ(status, Status::SUCCESS); } +/** +* @tc.name: Subscribe003 +* @tc.desc: subscribe user change, the observer is invalid +* @tc.type: FUNC +* @tc.author: nhj +*/ +HWTEST_F(AccountDelegateTest, Subscribe003, TestSize.Level0) +{ + auto account = AccountDelegate::GetInstance(); + EXPECT_NE(account, nullptr); + auto observer = std::make_shared(); + auto status = account->Subscribe(observer); + EXPECT_EQ(status, Status::INVALID_ARGUMENT); + observer->SetName("Subscribe003Observer"); + status = account->Subscribe(observer); + EXPECT_EQ(status, Status::SUCCESS); + observer->SetName("Subscribe002ObserverAfter"); + status = account->Subscribe(observer); + EXPECT_EQ(status, Status::SUCCESS); +} + /** * @tc.name: Unsubscribe001 * @tc.desc: unsubscribe user change, the observer is invalid @@ -195,6 +219,36 @@ HWTEST_F(AccountDelegateTest, QueryUsers, TestSize.Level0) EXPECT_GT(users.size(), 0); } +/** +* @tc.name: IsVerified +* @tc.desc: query users +* @tc.type: FUNC +* @tc.author: nhj +*/ +HWTEST_F(AccountDelegateTest, IsVerified, TestSize.Level0) +{ + auto user = AccountDelegate::GetInstance()->IsVerified(userId); + EXPECT_EQ(user, true); +} + +/** +* @tc.name: UnsubscribeAccountEvent +* @tc.desc: get current account Id +* @tc.type: FUNC +* @tc.author: nhj +*/ +HWTEST_F(AccountDelegateTest, UnsubscribeAccountEvent, TestSize.Level0) +{ + auto account = AccountDelegate::GetInstance(); + auto observer = std::make_shared(); + account->Subscribe(observer); + auto executor = std::make_shared(12, 5); + AccountDelegate::GetInstance()->UnsubscribeAccountEvent(); + AccountDelegate::GetInstance()->BindExecutor(executor); + auto status = account->Unsubscribe(observer); + EXPECT_EQ(status, Status::SUCCESS); +} + /** * @tc.name: QueryForegroundUsers * @tc.desc: query foreground users diff --git a/datamgr_service/services/distributeddataservice/adapter/broadcaster/BUILD.gn b/datamgr_service/services/distributeddataservice/adapter/broadcaster/BUILD.gn index e765d3d9..1f36633b 100644 --- a/datamgr_service/services/distributeddataservice/adapter/broadcaster/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/adapter/broadcaster/BUILD.gn @@ -19,6 +19,8 @@ ohos_static_library("distributeddata_broadcaster_static") { cfi = true cfi_cross_dso = true debug = false + boundary_sanitize = true + ubsan = true } sources = [ "src/broadcast_sender.cpp", diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/BUILD.gn b/datamgr_service/services/distributeddataservice/adapter/communicator/BUILD.gn index 873e9ae5..95897b4c 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/BUILD.gn @@ -18,6 +18,8 @@ ohos_static_library("distributeddata_communicator_static") { cfi = true cfi_cross_dso = true debug = false + boundary_sanitize = true + ubsan = true } sources = [ "src/app_pipe_handler.cpp", @@ -45,7 +47,6 @@ ohos_static_library("distributeddata_communicator_static") { "../include/log", "../include/autils", "../include/utils", - "${dsoftbus_core_path}", "${kv_store_common_path}", "${kv_store_distributeddb_path}/interfaces/include", "${kv_store_distributeddb_path}/include", 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 705bfb32..1f9db263 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 @@ -253,15 +253,9 @@ void DeviceManagerAdapter::Online(const DmDeviceInfo &info) ZLOGE("get device info fail"); return; } - syncTask_.Insert(dvInfo.uuid, dvInfo.uuid); - if (dvInfo.osType != OH_OS_TYPE) { - ZLOGI("[online] uuid:%{public}s, name:%{public}s, type:%{public}d is not oh device", - KvStoreUtils::ToBeAnonymous(dvInfo.uuid).c_str(), dvInfo.deviceName.c_str(), dvInfo.deviceType); - NotifyReadyEvent(dvInfo.uuid); - return; - } - ZLOGI("[online] uuid:%{public}s, name:%{public}s, type:%{public}d", - KvStoreUtils::ToBeAnonymous(dvInfo.uuid).c_str(), dvInfo.deviceName.c_str(), dvInfo.deviceType); + ZLOGI("[online] uuid:%{public}s, name:%{public}s, type:%{public}d, authForm:%{public}d, osType:%{public}d", + KvStoreUtils::ToBeAnonymous(dvInfo.uuid).c_str(), dvInfo.deviceName.c_str(), dvInfo.deviceType, + static_cast(dvInfo.authForm), dvInfo.osType); SaveDeviceInfo(dvInfo, DeviceChangeType::DEVICE_ONLINE); syncTask_.Insert(dvInfo.uuid, dvInfo.uuid); auto observers = GetObservers(); @@ -274,7 +268,7 @@ void DeviceManagerAdapter::Online(const DmDeviceInfo &info) item->OnDeviceChanged(dvInfo, DeviceChangeType::DEVICE_ONLINE); } } - for (const auto &item : observers) { // sync meta, get device security level + for (const auto &item : observers) { // judge water version, get device security level if (item == nullptr) { continue; } @@ -282,11 +276,6 @@ void DeviceManagerAdapter::Online(const DmDeviceInfo &info) item->OnDeviceChanged(dvInfo, DeviceChangeType::DEVICE_ONLINE); } } - - executors_->Schedule(std::chrono::milliseconds(SYNC_TIMEOUT), [this, dvInfo]() { - NotifyReadyEvent(dvInfo.uuid); - }); - for (const auto &item : observers) { // set compatible identify, sync service meta if (item == nullptr) { continue; @@ -331,8 +320,9 @@ void DeviceManagerAdapter::Offline(const DmDeviceInfo &info) return; } syncTask_.Erase(dvInfo.uuid); - ZLOGI("[offline] uuid:%{public}s, name:%{public}s, type:%{public}d", - KvStoreUtils::ToBeAnonymous(dvInfo.uuid).c_str(), dvInfo.deviceName.c_str(), dvInfo.deviceType); + ZLOGI("[offline] uuid:%{public}s, name:%{public}s, type:%{public}d, authForm:%{public}d, osType:%{public}d", + KvStoreUtils::ToBeAnonymous(dvInfo.uuid).c_str(), dvInfo.deviceName.c_str(), dvInfo.deviceType, + static_cast(dvInfo.authForm), dvInfo.osType); SaveDeviceInfo(dvInfo, DeviceChangeType::DEVICE_OFFLINE); auto task = [this, dvInfo]() { observers_.ForEachCopies([&dvInfo](const auto &key, auto &value) { @@ -363,11 +353,6 @@ void DeviceManagerAdapter::OnReady(const DmDeviceInfo &info) ZLOGE("get device info fail"); return; } - if (dvInfo.osType != OH_OS_TYPE) { - ZLOGW("[OnReady] uuid:%{public}s, name:%{public}s, type:%{public}d is not oh device", - KvStoreUtils::ToBeAnonymous(dvInfo.uuid).c_str(), dvInfo.deviceName.c_str(), dvInfo.deviceType); - return; - } readyDevices_.InsertOrAssign(dvInfo.uuid, std::make_pair(DeviceState::DEVICE_ONREADY, dvInfo)); ZLOGI("[OnReady] uuid:%{public}s, name:%{public}s, type:%{public}d", KvStoreUtils::ToBeAnonymous(dvInfo.uuid).c_str(), dvInfo.deviceName.c_str(), dvInfo.deviceType); @@ -395,7 +380,8 @@ bool DeviceManagerAdapter::GetDeviceInfo(const DmDeviceInfo &dmInfo, DeviceInfo return false; } if (uuid == CLOUD_DEVICE_UUID) { - dvInfo = { uuid, udid, networkId, std::string(dmInfo.deviceName), dmInfo.deviceTypeId, OH_OS_TYPE }; + dvInfo = { uuid, udid, networkId, std::string(dmInfo.deviceName), dmInfo.deviceTypeId, OH_OS_TYPE, + static_cast(dmInfo.authForm)}; return true; } DeviceExtraInfo deviceExtraInfo; @@ -403,7 +389,8 @@ bool DeviceManagerAdapter::GetDeviceInfo(const DmDeviceInfo &dmInfo, DeviceInfo ZLOGE("Unmarshall failed, deviceExtraInfo:%{public}s", dmInfo.extraData.c_str()); return false; } - dvInfo = { uuid, udid, networkId, std::string(dmInfo.deviceName), dmInfo.deviceTypeId, deviceExtraInfo.OS_TYPE }; + dvInfo = { uuid, udid, networkId, std::string(dmInfo.deviceName), dmInfo.deviceTypeId, deviceExtraInfo.OS_TYPE, + static_cast(dmInfo.authForm)}; return true; } @@ -463,11 +450,9 @@ std::vector DeviceManagerAdapter::GetRemoteDevices() ZLOGE("Unmarshall failed, deviceExtraInfo:%{public}s", dmInfo.extraData.c_str()); continue; } - if (deviceExtraInfo.OS_TYPE != OH_OS_TYPE) { - continue; - } DeviceInfo dvInfo = { std::move(uuid), std::move(udid), std::move(networkId), - std::string(dmInfo.deviceName), dmInfo.deviceTypeId, deviceExtraInfo.OS_TYPE }; + std::string(dmInfo.deviceName), dmInfo.deviceTypeId, deviceExtraInfo.OS_TYPE, + static_cast(dmInfo.authForm) }; dvInfos.emplace_back(std::move(dvInfo)); } return dvInfos; @@ -490,14 +475,24 @@ bool DeviceManagerAdapter::IsDeviceReady(const std::string& id) return (it.first && it.second.first == DeviceState::DEVICE_ONREADY); } -bool DeviceManagerAdapter::IsOHOsType(const std::string& id) +bool DeviceManagerAdapter::IsOHOSType(const std::string &id) { DeviceInfo dvInfo; if (!deviceInfos_.Get(id, dvInfo)) { InitDeviceInfo(); - return deviceInfos_.Get(id, dvInfo); + deviceInfos_.Get(id, dvInfo); } - return true; + return dvInfo.osType == OH_OS_TYPE; +} + +int32_t DeviceManagerAdapter::GetAuthType(const std::string &id) +{ + DeviceInfo dvInfo; + if (!deviceInfos_.Get(id, dvInfo)) { + InitDeviceInfo(); + deviceInfos_.Get(id, dvInfo); + } + return static_cast(dvInfo.authForm); } size_t DeviceManagerAdapter::GetOnlineSize() @@ -573,7 +568,7 @@ DeviceInfo DeviceManagerAdapter::GetLocalDeviceInfo() ZLOGI("[LocalDevice] uuid:%{public}s, name:%{public}s, type:%{public}d, osType:%{public}d", KvStoreUtils::ToBeAnonymous(uuid).c_str(), info.deviceName, info.deviceTypeId, deviceExtraInfo.OS_TYPE); return { std::move(uuid), std::move(udid), std::move(networkId), std::string(info.deviceName), info.deviceTypeId, - deviceExtraInfo.OS_TYPE }; + deviceExtraInfo.OS_TYPE, static_cast(info.authForm) }; } std::string DeviceManagerAdapter::GetUuidByNetworkId(const std::string &networkId) @@ -737,4 +732,19 @@ DeviceManagerAdapter::NetworkType DeviceManagerAdapter::RefreshNet() } return SetNet(Convert(*capabilities.bearerTypes_.begin())); } + +std::string DeviceManagerAdapter::GetEncryptedUuidByNetworkId(const std::string &networkId) +{ + if (networkId.empty()) { + ZLOGE("failed! networkId empty"); + return ""; + } + std::string encryptedUuid; + auto ret = DeviceManager::GetInstance().GetEncryptedUuidByNetworkId(PKG_NAME, networkId, encryptedUuid); + if (ret != DM_OK) { + ZLOGE("failed, result:%{public}d", ret); + return ""; + } + return encryptedUuid; +} } // namespace OHOS::DistributedData 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 ed7e12a0..e5237c4a 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 @@ -83,7 +83,7 @@ void OnDataLevelChanged(const char* networkId, const DataLevel dataLevel) } IDataLevelCb g_callback = { - .OnDataLevelChanged = OnDataLevelChanged, + .onDataLevelChanged = OnDataLevelChanged, }; } // namespace SoftBusAdapter::SoftBusAdapter() @@ -462,13 +462,6 @@ void AppDataListenerWrap::OnServerBytesReceived(int32_t socket, const void *data return; }; std::string peerDevUuid = DmAdapter::GetInstance().GetUuidByNetworkId(std::string(info.networkId)); - if (!DmAdapter::GetInstance().IsOHOsType(peerDevUuid)) { - ZLOGD("[OnBytesReceived] Not OH device socket:%{public}d, peer name:%{public}s, peer devId:%{public}s," - "data len:%{public}u", socket, info.name.c_str(), KvStoreUtils::ToBeAnonymous(peerDevUuid).c_str(), - dataLen); - return; - } - ZLOGD("[OnBytesReceived] socket:%{public}d, peer name:%{public}s, peer devId:%{public}s, data len:%{public}u", socket, info.name.c_str(), KvStoreUtils::ToBeAnonymous(peerDevUuid).c_str(), dataLen); 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 2c2f9e7f..f46d4e0d 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.cpp @@ -95,7 +95,7 @@ Status SoftBusClient::OpenConnect(const ISocketListener *listener) socketInfo.peerName = const_cast(peerName.c_str()); std::string networkId = DmAdapter::GetInstance().ToNetworkID(device_.deviceId); socketInfo.peerNetworkId = const_cast(networkId.c_str()); - std::string clientName = (pipe_.pipeId + "_client_" + socketInfo.peerNetworkId).substr(0, 64); + std::string clientName = pipe_.pipeId; socketInfo.name = const_cast(clientName.c_str()); std::string pkgName = "ohos.distributeddata"; socketInfo.pkgName = pkgName.data(); diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/test/BUILD.gn b/datamgr_service/services/distributeddataservice/adapter/communicator/test/BUILD.gn index f94d733b..c627bee8 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/test/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/test/BUILD.gn @@ -10,8 +10,10 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +import("//build/ohos.gni") +import("//build/ohos_var.gni") import("//build/test.gni") - +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") module_output_path = "datamgr_service/distributeddatafwk" ############################################################################### @@ -61,6 +63,10 @@ ohos_unittest("DeviceManagerAdapterTest") { "hilog:libhilog", "ipc:ipc_core", ] + cflags = [ + "-Dprivate=public", + "-Dprotected=public", + ] deps = [ "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/communicator:distributeddata_communicator_static", "//foundation/distributedhardware/device_manager/interfaces/inner_kits/native_cpp:devicemanagersdk", @@ -69,6 +75,38 @@ ohos_unittest("DeviceManagerAdapterTest") { defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] } +ohos_unittest("SoftbusAdapterStandardTest") { + module_out_path = module_output_path + + sources = [ "unittest/softbus_adapter_standard_test.cpp" ] + include_dirs = [ + "${kv_store_path}/frameworks/common", + "${data_service_path}/adapter/include/autils", + "${data_service_path}/adapter/include/communicator", + "${data_service_path}/adapter/include/dfx", + "${kv_store_path}/interfaces/innerkits/distributeddata/include", + "../src", + ] + external_deps = [ + "access_token:libaccesstoken_sdk", + "access_token:libnativetoken", + "access_token:libtoken_setproc", + "dsoftbus:softbus_client", + "hilog:libhilog", + "ipc:ipc_core", + ] + cflags = [ + "-Dprivate=public", + "-Dprotected=public", + ] + deps = [ + "${data_service_path}/adapter/communicator:distributeddata_communicator_static", + "${device_manager_path}/interfaces/inner_kits/native_cpp:devicemanagersdk", + "//third_party/googletest:gtest_main", + ] + defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] +} + ############################################################################### config("module_comm_config") { visibility = [ ":*" ] @@ -93,6 +131,7 @@ group("unittest") { deps += [ ":CommunicationProviderTest", ":DeviceManagerAdapterTest", + ":SoftbusAdapterStandardTest", ] } ############################################################################### diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/test/unittest/communication_provider_impl_test.cpp b/datamgr_service/services/distributeddataservice/adapter/communicator/test/unittest/communication_provider_impl_test.cpp index 0000371d..58c8e534 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/test/unittest/communication_provider_impl_test.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/test/unittest/communication_provider_impl_test.cpp @@ -140,3 +140,243 @@ HWTEST_F(CommunicationProviderImplTest, CommunicationProvider005, TestSize.Level delete dataListener17; sleep(1); // avoid thread dnet thread died, then will have pthread; } + +/** +* @tc.name: CommunicationProvider006 +* @tc.desc:the observer is nullptr +* @tc.type: FUNC +* @tc.author: nhj +*/ +HWTEST_F(CommunicationProviderImplTest, CommunicationProvider006, TestSize.Level1) +{ + ZLOGI("begin."); + PipeInfo appId; + appId.pipeId = "appId06"; + appId.userId = "groupId06"; + CommunicationProvider::GetInstance().StartWatchDataChange(nullptr, appId); + auto secRegister = CommunicationProvider::GetInstance().StartWatchDataChange(nullptr, appId); + EXPECT_EQ(Status::INVALID_ARGUMENT, secRegister); +} + +/** +* @tc.name: CommunicationProvider007 +* @tc.desc:the pipeInfo is nullptr +* @tc.type: FUNC +* @tc.author: nhj +*/ +HWTEST_F(CommunicationProviderImplTest, CommunicationProvider007, TestSize.Level1) +{ + ZLOGI("begin."); + auto secRegister = CommunicationProvider::GetInstance().StartWatchDataChange(nullptr, {}); + EXPECT_EQ(Status::INVALID_ARGUMENT, secRegister); +} + +/** +* @tc.name: CommunicationProvider008 +* @tc.desc:the observer is nullptr +* @tc.type: FUNC +* @tc.author: nhj +*/ +HWTEST_F(CommunicationProviderImplTest, CommunicationProvider008, TestSize.Level1) +{ + ZLOGI("begin."); + PipeInfo appId; + appId.pipeId = "appId06"; + appId.userId = "groupId06"; + CommunicationProvider::GetInstance().StopWatchDataChange(nullptr, appId); + auto secRegister = CommunicationProvider::GetInstance().StopWatchDataChange(nullptr, appId); + EXPECT_EQ(Status::INVALID_ARGUMENT, secRegister); +} + +/** +* @tc.name: CommunicationProvider009 +* @tc.desc: the pipeInfo is nullptr +* @tc.type: FUNC +* @tc.author: nhj +*/ +HWTEST_F(CommunicationProviderImplTest, CommunicationProvider009, TestSize.Level1) +{ + ZLOGI("begin."); + auto secRegister = CommunicationProvider::GetInstance().StopWatchDataChange(nullptr, {}); + EXPECT_EQ(Status::INVALID_ARGUMENT, secRegister); +} + +/** +* @tc.name: CommunicationProvider010 +* @tc.desc: Start pipe +* @tc.type: FUNC +* @tc.author: nhj +*/ +HWTEST_F(CommunicationProviderImplTest, CommunicationProvider010, TestSize.Level1) +{ + PipeInfo appId; + appId.pipeId = ""; + appId.userId = "groupId"; + auto status = CommunicationProvider::GetInstance().Start(appId); + EXPECT_EQ(Status::INVALID_ARGUMENT, status); +} + +/** +* @tc.name: CommunicationProvider011 +* @tc.desc: parse sent data +* @tc.type: FUNC +* @tc.author: nhj +*/ +HWTEST_F(CommunicationProviderImplTest, CommunicationProvider011, TestSize.Level1) +{ + const AppDataChangeListenerImpl *dataListener = new AppDataChangeListenerImpl(); + PipeInfo id; + id.pipeId = "appId"; + id.userId = "groupId"; + CommunicationProvider::GetInstance().StartWatchDataChange(dataListener, id); + CommunicationProvider::GetInstance().Start(id); + std::string content = ""; + const uint8_t *t = reinterpret_cast(content.c_str()); + DeviceId di = {"DeviceId"}; + DataInfo data = { const_cast(t), static_cast(content.length())}; + Status status = CommunicationProvider::GetInstance().SendData(id, di, data, 0); + EXPECT_EQ(status, Status::ERROR); + CommunicationProvider::GetInstance().StopWatchDataChange(dataListener, id); + CommunicationProvider::GetInstance().Stop(id); + delete dataListener; +} + +/** +* @tc.name: CommunicationProvider012 +* @tc.desc: parse sent data +* @tc.type: FUNC +* @tc.author: nhj +*/ +HWTEST_F(CommunicationProviderImplTest, CommunicationProvider012, TestSize.Level1) +{ + const AppDataChangeListenerImpl *dataListener = new AppDataChangeListenerImpl(); + PipeInfo id; + id.pipeId = "appId"; + id.userId = "groupId"; + CommunicationProvider::GetInstance().StartWatchDataChange(dataListener, id); + CommunicationProvider::GetInstance().Start(id); + std::string content = "hello"; + const uint8_t *t = reinterpret_cast(content.c_str()); + DeviceId di = {""}; + DataInfo data = { const_cast(t), static_cast(content.length())}; + Status status = CommunicationProvider::GetInstance().SendData(id, di, data, 0); + EXPECT_EQ(status, Status::ERROR); + CommunicationProvider::GetInstance().StopWatchDataChange(dataListener, id); + CommunicationProvider::GetInstance().Stop(id); + delete dataListener; +} + +/** +* @tc.name: CommunicationProvider013 +* @tc.desc: parse sent data +* @tc.type: FUNC +* @tc.author: nhj +*/ +HWTEST_F(CommunicationProviderImplTest, CommunicationProvider013, TestSize.Level1) +{ + const AppDataChangeListenerImpl *dataListener = new AppDataChangeListenerImpl(); + PipeInfo id; + id.pipeId = "appId"; + id.userId = "groupId"; + CommunicationProvider::GetInstance().StartWatchDataChange(dataListener, id); + CommunicationProvider::GetInstance().Start(id); + DeviceId di = {"DeviceId"}; + DataInfo data = {nullptr, 0}; + Status status = CommunicationProvider::GetInstance().SendData(id, di, data, 0); + EXPECT_EQ(status, Status::ERROR); + CommunicationProvider::GetInstance().StopWatchDataChange(dataListener, id); + CommunicationProvider::GetInstance().Stop(id); + delete dataListener; +} + +/** +* @tc.name: CommunicationProvider014 +* @tc.desc: parse sent data +* @tc.type: FUNC +* @tc.author: nhj +*/ +HWTEST_F(CommunicationProviderImplTest, CommunicationProvider014, TestSize.Level1) +{ + const AppDataChangeListenerImpl *dataListener = new AppDataChangeListenerImpl(); + PipeInfo id; + id.pipeId = ""; + id.userId = "groupId"; + CommunicationProvider::GetInstance().StartWatchDataChange(dataListener, id); + CommunicationProvider::GetInstance().Start(id); + std::string content = "hello"; + const uint8_t *t = reinterpret_cast(content.c_str()); + DeviceId di = {"DeviceId"}; + DataInfo data = { const_cast(t), static_cast(content.length())}; + Status status = CommunicationProvider::GetInstance().SendData(id, di, data, 0); + EXPECT_EQ(status, Status::ERROR); + CommunicationProvider::GetInstance().StopWatchDataChange(dataListener, id); + CommunicationProvider::GetInstance().Stop(id); + delete dataListener; +} + +/** +* @tc.name: CommunicationProvider015 +* @tc.desc: parse sent data +* @tc.type: FUNC +* @tc.author: nhj +*/ +HWTEST_F(CommunicationProviderImplTest, CommunicationProvider015, TestSize.Level1) +{ + const AppDataChangeListenerImpl *dataListener = new AppDataChangeListenerImpl(); + PipeInfo id; + id.pipeId = ""; + id.userId = "groupId"; + CommunicationProvider::GetInstance().StartWatchDataChange(dataListener, id); + CommunicationProvider::GetInstance().Start(id); + DeviceId di = {"DeviceId"}; + auto status = CommunicationProvider::GetInstance().IsSameStartedOnPeer(id, di); + EXPECT_EQ(status, false); + CommunicationProvider::GetInstance().StopWatchDataChange(dataListener, id); + CommunicationProvider::GetInstance().Stop(id); + delete dataListener; +} + +/** +* @tc.name: CommunicationProvider016 +* @tc.desc: IsSameStartedOnPeer +* @tc.type: FUNC +* @tc.author: nhj +*/ +HWTEST_F(CommunicationProviderImplTest, CommunicationProvider016, TestSize.Level1) +{ + const AppDataChangeListenerImpl *dataListener = new AppDataChangeListenerImpl(); + PipeInfo id; + id.pipeId = "pipeid"; + id.userId = "userId"; + CommunicationProvider::GetInstance().StartWatchDataChange(dataListener, id); + CommunicationProvider::GetInstance().Start(id); + DeviceId di = {""}; + auto status = CommunicationProvider::GetInstance().IsSameStartedOnPeer(id, di); + EXPECT_EQ(status, false); + CommunicationProvider::GetInstance().StopWatchDataChange(dataListener, id); + CommunicationProvider::GetInstance().Stop(id); + delete dataListener; +} + +/** +* @tc.name: CommunicationProvider017 +* @tc.desc: SetMessageTransFlag +* @tc.type: FUNC +* @tc.author: nhj +*/ +HWTEST_F(CommunicationProviderImplTest, CommunicationProvider017, TestSize.Level1) +{ + const AppDataChangeListenerImpl *dataListener = new AppDataChangeListenerImpl(); + PipeInfo id; + id.pipeId = "pipeid"; + id.userId = "userId"; + CommunicationProvider::GetInstance().StartWatchDataChange(dataListener, id); + CommunicationProvider::GetInstance().Start(id); + DeviceId di = {"DeviceId"}; + auto status = CommunicationProvider::GetInstance().IsSameStartedOnPeer(id, di); + EXPECT_EQ(status, false); + CommunicationProvider::GetInstance().SetMessageTransFlag(id, true); + CommunicationProvider::GetInstance().StopWatchDataChange(dataListener, id); + CommunicationProvider::GetInstance().Stop(id); + delete dataListener; +} \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/test/unittest/device_manager_adapter_test.cpp b/datamgr_service/services/distributeddataservice/adapter/communicator/test/unittest/device_manager_adapter_test.cpp index b3f03b75..d9005d26 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/test/unittest/device_manager_adapter_test.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/test/unittest/device_manager_adapter_test.cpp @@ -14,7 +14,6 @@ */ #include "device_manager_adapter.h" - #include "gtest/gtest.h" #include "accesstoken_kit.h" #include "executor_pool.h" @@ -25,7 +24,9 @@ namespace { using namespace testing::ext; using namespace OHOS::AppDistributedKv; using namespace OHOS::DistributedData; +using namespace OHOS::DistributedHardware; using namespace OHOS::Security::AccessToken; +using DmDeviceInfo = OHOS::DistributedHardware::DmDeviceInfo; class DeviceChangerListener final : public AppDeviceChangeListener { public: void OnDeviceChanged(const DeviceInfo &info, const DeviceChangeType &type) const override @@ -363,4 +364,58 @@ HWTEST_F(DeviceManagerAdapterTest, DeviceIdToNetworkIdLocal, TestSize.Level0) auto networkIdToNetworkId = DeviceManagerAdapter::GetInstance().ToNetworkID(dvInfo.networkId); EXPECT_EQ(networkIdToNetworkId, dvInfo.networkId); } + +/** +* @tc.name: StartWatchDeviceChange +* @tc.desc: start watch device change +* @tc.type: FUNC +* @tc.author: nhj + */ +HWTEST_F(DeviceManagerAdapterTest, StartWatchDeviceChange01, TestSize.Level0) +{ + std::shared_ptr observer = std::make_shared(); + auto status = DeviceManagerAdapter::GetInstance().StartWatchDeviceChange(observer.get(), {}); + EXPECT_EQ(status, Status::SUCCESS); +} + +/** +* @tc.name: GetDeviceInfo +* @tc.desc: get device info +* @tc.type: FUNC +* @tc.author: nhj + */ +HWTEST_F(DeviceManagerAdapterTest, GetDeviceInfo, TestSize.Level0) +{ + auto executors = std::make_shared(0, 0); + DeviceManagerAdapter::GetInstance().Init(executors); + auto dvInfo = DeviceManagerAdapter::GetInstance().GetDeviceInfo(EMPTY_DEVICE_ID); + EXPECT_TRUE(dvInfo.uuid.empty()); + EXPECT_TRUE(dvInfo.udid.empty()); + EXPECT_TRUE(dvInfo.networkId.empty()); +} + +/** +* @tc.name: GetDeviceInfo +* @tc.desc: get device info, the id is invalid +* @tc.type: FUNC +* @tc.author: nhj + */ +HWTEST_F(DeviceManagerAdapterTest, GetDeviceInfoInvalidId01, TestSize.Level0) +{ + auto dvInfo = DeviceManagerAdapter::GetInstance().GetDeviceInfo(EMPTY_DEVICE_ID); + EXPECT_TRUE(dvInfo.uuid.empty()); +} + +/** +* @tc.name: GetOnlineDevices +* @tc.desc: get Online device +* @tc.type: FUNC +* @tc.author: nhj + */ +HWTEST_F(DeviceManagerAdapterTest, GetOnlineDevices, TestSize.Level0) +{ + auto onInfos = DeviceManagerAdapter::GetInstance().GetOnlineDevices(); + EXPECT_TRUE(onInfos.empty()); +} + } // namespace \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/test/unittest/softbus_adapter_standard_test.cpp b/datamgr_service/services/distributeddataservice/adapter/communicator/test/unittest/softbus_adapter_standard_test.cpp new file mode 100644 index 00000000..d0c91821 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/test/unittest/softbus_adapter_standard_test.cpp @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define LOG_TAG "SoftbusAdapterStandardTest" + +#include "app_device_change_listener.h" +#include +#include "gtest/gtest.h" +#include +#include "log_print.h" +#define private public +#include "softbus_adapter.h" +#include "types.h" +#include +#include + +namespace OHOS::Test { +using namespace testing::ext; +using namespace OHOS::AppDistributedKv; +using DeviceInfo = OHOS::AppDistributedKv::DeviceInfo; +class AppDataChangeListenerImpl : public AppDataChangeListener { + struct ServerSocketInfo { + std::string name; /**< Peer socket name */ + std::string networkId; /**< Peer network ID */ + std::string pkgName; /**< Peer package name */ + }; + + void OnMessage(const OHOS::AppDistributedKv::DeviceInfo &info, const uint8_t *ptr, const int size, + const struct PipeInfo &id) const override; +}; + +void AppDataChangeListenerImpl::OnMessage(const OHOS::AppDistributedKv::DeviceInfo &info, + const uint8_t *ptr, const int size, const struct PipeInfo &id) const +{ + ZLOGI("data %{public}s %s", info.deviceName.c_str(), ptr); +} + +class SoftbusAdapterStandardTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} + void SetUp() {} + void TearDown() {} +protected: + static constexpr uint32_t DEFAULT_MTU_SIZE = 4096 * 1024u; + static constexpr uint32_t DEFAULT_TIMEOUT = 30 * 1000; +}; + +/** +* @tc.name: StartWatchDeviceChange +* @tc.desc: start watch data change +* @tc.type: FUNC +* @tc.require: +* @tc.author: nhj + */ +HWTEST_F(SoftbusAdapterStandardTest, StartWatchDeviceChange, TestSize.Level0) +{ + auto status = SoftBusAdapter::GetInstance()->StartWatchDataChange(nullptr, {}); + EXPECT_EQ(status, Status::INVALID_ARGUMENT); +} + +/** +* @tc.name: StartWatchDeviceChange +* @tc.desc: start watch data change +* @tc.type: FUNC +* @tc.require: +* @tc.author: nhj + */ +HWTEST_F(SoftbusAdapterStandardTest, StartWatchDeviceChange01, TestSize.Level0) +{ + PipeInfo appId; + appId.pipeId = "appId"; + appId.userId = "groupId"; + const AppDataChangeListenerImpl *dataListener = new AppDataChangeListenerImpl(); + auto status = SoftBusAdapter::GetInstance()->StartWatchDataChange(dataListener, appId); + EXPECT_EQ(status, Status::SUCCESS); +} + +/** +* @tc.name: StartWatchDeviceChange +* @tc.desc: start watch data change +* @tc.type: FUNC +* @tc.require: +* @tc.author: nhj + */ +HWTEST_F(SoftbusAdapterStandardTest, StartWatchDeviceChange02, TestSize.Level0) +{ + PipeInfo appId; + appId.pipeId = ""; + appId.userId = "groupId"; + const AppDataChangeListenerImpl *dataListener = new AppDataChangeListenerImpl(); + auto status = SoftBusAdapter::GetInstance()->StartWatchDataChange(dataListener, appId); + EXPECT_EQ(status, Status::SUCCESS); +} + +/** +* @tc.name: StopWatchDataChange +* @tc.desc: stop watch data change +* @tc.type: FUNC +* @tc.require: +* @tc.author: nhj + */ +HWTEST_F(SoftbusAdapterStandardTest, StopWatchDataChange, TestSize.Level0) +{ + PipeInfo appId; + appId.pipeId = "appId"; + appId.userId = "groupId"; + const AppDataChangeListenerImpl *dataListener = new AppDataChangeListenerImpl(); + auto status = SoftBusAdapter::GetInstance()->StopWatchDataChange(dataListener, appId); + EXPECT_EQ(status, Status::SUCCESS); +} + +/** +* @tc.name: StopWatchDataChange +* @tc.desc: stop watch data change +* @tc.type: FUNC +* @tc.require: +* @tc.author: nhj + */ +HWTEST_F(SoftbusAdapterStandardTest, StopWatchDataChange01, TestSize.Level0) +{ + PipeInfo appId; + appId.pipeId = ""; + appId.userId = "groupId"; + const AppDataChangeListenerImpl *dataListener = new AppDataChangeListenerImpl(); + auto status = SoftBusAdapter::GetInstance()->StopWatchDataChange(dataListener, appId); + EXPECT_EQ(status, Status::SUCCESS); +} + +/** +* @tc.name: SendData +* @tc.desc: parse sent data +* @tc.type: FUNC +* @tc.author: nhj +*/ +HWTEST_F(SoftbusAdapterStandardTest, SendData, TestSize.Level1) +{ + const AppDataChangeListenerImpl *dataListener = new AppDataChangeListenerImpl(); + PipeInfo id; + id.pipeId = "appId"; + id.userId = "groupId"; + auto secRegister = SoftBusAdapter::GetInstance()->StartWatchDataChange(dataListener, id); + EXPECT_EQ(Status::SUCCESS, secRegister); + std::string content = "Helloworlds"; + const uint8_t *t = reinterpret_cast(content.c_str()); + DeviceId di = {"DeviceId"}; + DataInfo data = { const_cast(t), static_cast(content.length())}; + Status status = SoftBusAdapter::GetInstance()->SendData(id, di, data, 11, { MessageType::DEFAULT }); + EXPECT_NE(status, Status::SUCCESS); + SoftBusAdapter::GetInstance()->StopWatchDataChange(dataListener, id); + delete dataListener; +} + +/** +* @tc.name: GetMtuSize +* @tc.desc: get size +* @tc.type: FUNC +* @tc.author: nhj +*/ +HWTEST_F(SoftbusAdapterStandardTest, GetMtuSize, TestSize.Level1) +{ + const AppDataChangeListenerImpl *dataListener = new AppDataChangeListenerImpl(); + PipeInfo id; + id.pipeId = "appId"; + id.userId = "groupId"; + SoftBusAdapter::GetInstance()->StartWatchDataChange(dataListener, id); + DeviceId di = {"DeviceId"}; + auto size = SoftBusAdapter::GetInstance()->GetMtuSize(di); + EXPECT_EQ(size, DEFAULT_MTU_SIZE); + SoftBusAdapter::GetInstance()->GetCloseSessionTask(); + SoftBusAdapter::GetInstance()->StopWatchDataChange(dataListener, id); + delete dataListener; +} + +/** +* @tc.name: GetTimeout +* @tc.desc: get timeout +* @tc.type: FUNC +* @tc.author: nhj +*/ +HWTEST_F(SoftbusAdapterStandardTest, GetTimeout, TestSize.Level1) +{ + const AppDataChangeListenerImpl *dataListener = new AppDataChangeListenerImpl(); + PipeInfo id; + id.pipeId = "appId01"; + id.userId = "groupId01"; + SoftBusAdapter::GetInstance()->StartWatchDataChange(dataListener, id); + DeviceId di = {"DeviceId"}; + auto time = SoftBusAdapter::GetInstance()->GetTimeout(di); + EXPECT_EQ(time, DEFAULT_TIMEOUT); + SoftBusAdapter::GetInstance()->StopWatchDataChange(dataListener, id); + delete dataListener; +} + +/** +* @tc.name: IsSameStartedOnPeer +* @tc.desc: get size +* @tc.type: FUNC +* @tc.author: nhj +*/ +HWTEST_F(SoftbusAdapterStandardTest, IsSameStartedOnPeer, TestSize.Level1) +{ + PipeInfo id; + id.pipeId = "appId01"; + id.userId = "groupId01"; + DeviceId di = {"DeviceId"}; + SoftBusAdapter::GetInstance()->SetMessageTransFlag(id, true); + auto status = SoftBusAdapter::GetInstance()->IsSameStartedOnPeer(id, di); + EXPECT_EQ(status, true); +} +} // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/adapter/dfx/BUILD.gn b/datamgr_service/services/distributeddataservice/adapter/dfx/BUILD.gn index 2e8eb566..3b7ee170 100644 --- a/datamgr_service/services/distributeddataservice/adapter/dfx/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/adapter/dfx/BUILD.gn @@ -19,6 +19,8 @@ ohos_static_library("distributeddata_dfx_static") { cfi = true cfi_cross_dso = true debug = false + boundary_sanitize = true + ubsan = true } sources = [ "src/behaviour/behaviour_reporter_impl.cpp", @@ -27,6 +29,7 @@ ohos_static_library("distributeddata_dfx_static") { "src/fault/runtime_fault_impl.cpp", "src/fault/service_fault_impl.cpp", "src/hiview_adapter.cpp", + "src/radar_reporter.cpp", "src/reporter.cpp", "src/statistic/api_performance_statistic_impl.cpp", "src/statistic/database_statistic_impl.cpp", @@ -41,21 +44,22 @@ ohos_static_library("distributeddata_dfx_static") { "../include/dfx", "../include/log", "../include/autils", + "../include/communicator", "${kv_store_common_path}", "${kv_store_path}/interfaces/inner_api/distributeddata/include", - "//third_party/openssl/include/", ] cflags_cc = [ "-fvisibility=hidden" ] - deps = [ "//third_party/openssl:libcrypto_shared" ] external_deps = [ "c_utils:utils", + "device_manager:devicemanagersdk", "hilog:libhilog", "hisysevent:libhisysevent", "hitrace:hitrace_meter", "hitrace:libhitracechain", "kv_store:distributeddata_inner", + "openssl:libcrypto_shared", ] subsystem_name = "distributeddatamgr" part_name = "datamgr_service" diff --git a/datamgr_service/services/distributeddataservice/adapter/dfx/src/hiview_adapter.cpp b/datamgr_service/services/distributeddataservice/adapter/dfx/src/hiview_adapter.cpp index 47aa3016..cb7f26c5 100644 --- a/datamgr_service/services/distributeddataservice/adapter/dfx/src/hiview_adapter.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/dfx/src/hiview_adapter.cpp @@ -24,6 +24,7 @@ namespace OHOS { namespace DistributedDataDfx { using namespace DistributedKv; namespace { +constexpr const char *DATAMGR_DOMAIN = "DISTDATAMGR"; // fault key constexpr const char *FAULT_TYPE = "FAULT_TYPE"; constexpr const char *MODULE_NAME = "MODULE_NAME"; @@ -71,7 +72,6 @@ const std::map EVENT_COVERT_TABLE = { { DfxCodeConstant::UDMF_DATA_BEHAVIOR, "UDMF_DATA_BEHAVIOR" }, }; } -using OHOS::HiviewDFX::HiSysEvent; std::mutex HiViewAdapter::visitMutex_; std::map> HiViewAdapter::visitStat_; @@ -90,13 +90,31 @@ std::mutex HiViewAdapter::runMutex_; void HiViewAdapter::ReportFault(int dfxCode, const FaultMsg &msg, std::shared_ptr executors) { ExecutorPool::Task task([dfxCode, msg]() { - HiSysEventWrite(HiSysEvent::Domain::DISTRIBUTED_DATAMGR, - CoverEventID(dfxCode), - HiSysEvent::EventType::FAULT, - FAULT_TYPE, static_cast(msg.faultType), - MODULE_NAME, msg.moduleName, - INTERFACE_NAME, msg.interfaceName, - ERROR_TYPE, static_cast(msg.errorType)); + struct HiSysEventParam params[] = { + { .name = { *FAULT_TYPE }, + .t = HISYSEVENT_INT32, + .v = { .i32 = static_cast(msg.faultType) }, + .arraySize = 0 }, + { .name = { *MODULE_NAME }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(msg.moduleName.c_str()) }, + .arraySize = 0 }, + { .name = { *INTERFACE_NAME }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(msg.interfaceName.c_str()) }, + .arraySize = 0 }, + { .name = { *ERROR_TYPE }, + .t = HISYSEVENT_INT32, + .v = { .i32 = static_cast(msg.errorType) }, + .arraySize = 0 }, + }; + OH_HiSysEvent_Write( + DATAMGR_DOMAIN, + CoverEventID(dfxCode).c_str(), + HISYSEVENT_FAULT, + params, + sizeof(params) / sizeof(params[0]) + ); }); executors->Execute(std::move(task)); } @@ -104,13 +122,31 @@ void HiViewAdapter::ReportFault(int dfxCode, const FaultMsg &msg, std::shared_pt void HiViewAdapter::ReportDBFault(int dfxCode, const DBFaultMsg &msg, std::shared_ptr executors) { ExecutorPool::Task task([dfxCode, msg]() { - HiSysEventWrite(HiSysEvent::Domain::DISTRIBUTED_DATAMGR, - CoverEventID(dfxCode), - HiSysEvent::EventType::FAULT, - APP_ID, msg.appId, - STORE_ID, msg.storeId, - MODULE_NAME, msg.moduleName, - ERROR_TYPE, static_cast(msg.errorType)); + struct HiSysEventParam params[] = { + { .name = { *APP_ID }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(msg.appId.c_str()) }, + .arraySize = 0 }, + { .name = { *STORE_ID }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(msg.storeId.c_str()) }, + .arraySize = 0 }, + { .name = { *MODULE_NAME }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(msg.moduleName.c_str()) }, + .arraySize = 0 }, + { .name = { *ERROR_TYPE }, + .t = HISYSEVENT_INT32, + .v = { .i32 = static_cast(msg.errorType) }, + .arraySize = 0 }, + }; + OH_HiSysEvent_Write( + DATAMGR_DOMAIN, + CoverEventID(dfxCode).c_str(), + HISYSEVENT_FAULT, + params, + sizeof(params) / sizeof(params[0]) + ); }); executors->Execute(std::move(task)); } @@ -121,16 +157,34 @@ void HiViewAdapter::ReportCommFault(int dfxCode, const CommFaultMsg &msg, std::s std::string message; for (size_t i = 0; i < msg.deviceId.size(); i++) { message.append("No: ").append(std::to_string(i)) - .append(" sync to device: ").append(msg.deviceId[i]) - .append(" has error, errCode:").append(std::to_string(msg.errorCode[i])).append(". "); + .append(" sync to device: ").append(msg.deviceId[i]) + .append(" has error, errCode:").append(std::to_string(msg.errorCode[i])).append(". "); } - HiSysEventWrite(HiSysEvent::Domain::DISTRIBUTED_DATAMGR, - CoverEventID(dfxCode), - HiSysEvent::EventType::FAULT, - USER_ID, msg.userId, - APP_ID, msg.appId, - STORE_ID, msg.storeId, - SYNC_ERROR_INFO, message); + struct HiSysEventParam params[] = { + { .name = { *USER_ID }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(msg.userId.c_str()) }, + .arraySize = 0 }, + { .name = { *APP_ID }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(msg.appId.c_str()) }, + .arraySize = 0 }, + { .name = { *STORE_ID }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(msg.storeId.c_str()) }, + .arraySize = 0 }, + { .name = { *SYNC_ERROR_INFO }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(message.c_str()) }, + .arraySize = 0 }, + }; + OH_HiSysEvent_Write( + DATAMGR_DOMAIN, + CoverEventID(dfxCode).c_str(), + HISYSEVENT_FAULT, + params, + sizeof(params) / sizeof(params[0]) + ); }); executors->Execute(std::move(task)); } @@ -141,13 +195,31 @@ void HiViewAdapter::ReportBehaviour(int dfxCode, const BehaviourMsg &msg, std::s std::string message; message.append("Behaviour type : ").append(std::to_string(static_cast(msg.behaviourType))) .append(" behaviour info : ").append(msg.extensionInfo); - HiSysEventWrite(HiSysEvent::Domain::DISTRIBUTED_DATAMGR, - CoverEventID(dfxCode), - HiSysEvent::EventType::BEHAVIOR, - USER_ID, msg.userId, - APP_ID, msg.appId, - STORE_ID, msg.storeId, - BEHAVIOUR_INFO, message); + struct HiSysEventParam params[] = { + { .name = { *USER_ID }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(msg.userId.c_str()) }, + .arraySize = 0 }, + { .name = { *APP_ID }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(msg.appId.c_str()) }, + .arraySize = 0 }, + { .name = { *STORE_ID }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(msg.storeId.c_str()) }, + .arraySize = 0 }, + { .name = { *BEHAVIOUR_INFO }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(message.c_str()) }, + .arraySize = 0 }, + }; + OH_HiSysEvent_Write( + DATAMGR_DOMAIN, + CoverEventID(dfxCode).c_str(), + HISYSEVENT_BEHAVIOR, + params, + sizeof(params) / sizeof(params[0]) + ); }); executors->Execute(std::move(task)); } @@ -177,10 +249,28 @@ void HiViewAdapter::ReportDbSize(const StatisticWrap &stat) return; } - HiSysEventWrite(HiSysEvent::Domain::DISTRIBUTED_DATAMGR, - CoverEventID(stat.code), - HiSysEvent::EventType::STATISTIC, - USER_ID, userId, APP_ID, stat.val.appId, STORE_ID, stat.val.storeId, DB_SIZE, dbSize); + struct HiSysEventParam params[] = { + { .name = { *USER_ID }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(userId.c_str()) }, + .arraySize = 0 }, + { .name = { *APP_ID }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(stat.val.appId.c_str()) }, + .arraySize = 0 }, + { .name = { *STORE_ID }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(stat.val.storeId.c_str()) }, + .arraySize = 0 }, + { .name = { *DB_SIZE }, .t = HISYSEVENT_UINT64, .v = { .ui64 = dbSize }, .arraySize = 0 }, + }; + OH_HiSysEvent_Write( + DATAMGR_DOMAIN, + CoverEventID(stat.code).c_str(), + HISYSEVENT_STATISTIC, + params, + sizeof(params) / sizeof(params[0]) + ); } void HiViewAdapter::InvokeDbSize() @@ -235,15 +325,32 @@ void HiViewAdapter::InvokeTraffic() if (!vh.CalcValueHash(kv.second.val.deviceId, deviceId)) { continue; } - - HiSysEventWrite(HiSysEvent::Domain::DISTRIBUTED_DATAMGR, - CoverEventID(kv.second.code), - HiSysEvent::EventType::STATISTIC, - TAG, POWERSTATS, - APP_ID, kv.second.val.appId, - DEVICE_ID, deviceId, - SEND_SIZE, kv.second.val.sendSize, - RECEIVED_SIZE, kv.second.val.receivedSize); + struct HiSysEventParam params[] = { + { .name = { *TAG }, .t = HISYSEVENT_STRING, .v = { .s = const_cast(POWERSTATS) }, .arraySize = 0 }, + { .name = { *APP_ID }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(kv.second.val.appId.c_str()) }, + .arraySize = 0 }, + { .name = { *DEVICE_ID }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(deviceId.c_str()) }, + .arraySize = 0 }, + { .name = { *SEND_SIZE }, + .t = HISYSEVENT_INT64, + .v = { .i64 = static_cast(kv.second.val.sendSize) }, + .arraySize = 0 }, + { .name = { *RECEIVED_SIZE }, + .t = HISYSEVENT_INT64, + .v = { .i64 = static_cast(kv.second.val.receivedSize) }, + .arraySize = 0 }, + }; + OH_HiSysEvent_Write( + DATAMGR_DOMAIN, + CoverEventID(kv.second.code).c_str(), + HISYSEVENT_STATISTIC, + params, + sizeof(params) / sizeof(params[0]) + ); } trafficStat_.clear(); } @@ -267,13 +374,31 @@ void HiViewAdapter::InvokeVisit() { std::lock_guard lock(visitMutex_); for (auto const &kv : visitStat_) { - HiSysEventWrite(HiSysEvent::Domain::DISTRIBUTED_DATAMGR, - CoverEventID(kv.second.code), - HiSysEvent::EventType::STATISTIC, - TAG, POWERSTATS, - APP_ID, kv.second.val.appId, - INTERFACE_NAME, kv.second.val.interfaceName, - TIMES, kv.second.times); + struct HiSysEventParam params[] = { + { .name = { *TAG }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(POWERSTATS) }, + .arraySize = 0 }, + { .name = { *APP_ID }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(kv.second.val.appId.c_str()) }, + .arraySize = 0 }, + { .name = { *INTERFACE_NAME }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(kv.second.val.interfaceName.c_str()) }, + .arraySize = 0 }, + { .name = { *BEHAVIOUR_INFO }, + .t = HISYSEVENT_INT64, + .v = { .i64 = static_cast(kv.second.times) }, + .arraySize = 0 }, + }; + OH_HiSysEvent_Write( + DATAMGR_DOMAIN, + CoverEventID(kv.second.code).c_str(), + HISYSEVENT_STATISTIC, + params, + sizeof(params) / sizeof(params[0]) + ); } visitStat_.clear(); } @@ -312,15 +437,39 @@ void HiViewAdapter::ReportUdmfBehaviour( return; } ExecutorPool::Task task([dfxCode, msg]() { - HiSysEventWrite(HiSysEvent::Domain::DISTRIBUTED_DATAMGR, - CoverEventID(dfxCode), - HiSysEvent::EventType::BEHAVIOR, - APP_ID, msg.appId, - CHANNEL, msg.channel, - DATA_SIZE, msg.dataSize, - DATA_TYPE, msg.dataType, - OPERATION, msg.operation, - RESULT, msg.result); + struct HiSysEventParam params[] = { + { .name = { *APP_ID }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(msg.appId.c_str()) }, + .arraySize = 0 }, + { .name = { *CHANNEL }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(msg.channel.c_str()) }, + .arraySize = 0 }, + { .name = { *DATA_SIZE }, + .t = HISYSEVENT_INT64, + .v = { .i64 = msg.dataSize }, + .arraySize = 0 }, + { .name = { *DATA_TYPE }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(msg.dataType.c_str()) }, + .arraySize = 0 }, + { .name = { *OPERATION }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(msg.operation.c_str()) }, + .arraySize = 0 }, + { .name = { *RESULT }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(msg.result.c_str()) }, + .arraySize = 0 }, + }; + OH_HiSysEvent_Write( + DATAMGR_DOMAIN, + CoverEventID(dfxCode).c_str(), + HISYSEVENT_BEHAVIOR, + params, + sizeof(params) / sizeof(params[0]) + ); }); executors->Execute(std::move(task)); } @@ -332,16 +481,26 @@ void HiViewAdapter::InvokeApiPerformance() std::lock_guard lock(apiPerformanceMutex_); for (auto const &kv : apiPerformanceStat_) { message.append("{\"CODE\":\"").append(std::to_string(kv.second.code)).append("\",") - .append("\"").append(INTERFACE_NAME).append("\":\"").append(kv.second.val.interfaceName).append("\",") - .append("\"").append(TIMES).append("\":").append(std::to_string(kv.second.times)).append(",") - .append("\"").append(AVERAGE_TIMES).append("\":").append(std::to_string(kv.second.val.averageTime)).append(",") - .append("\"").append(WORST_TIMES).append("\":").append(std::to_string(kv.second.val.worstTime)).append("}"); + .append("\"").append(INTERFACE_NAME).append("\":\"").append(kv.second.val.interfaceName).append("\",") + .append("\"").append(TIMES).append("\":").append(std::to_string(kv.second.times)).append(",") + .append("\"").append(AVERAGE_TIMES).append("\":").append(std::to_string(kv.second.val.averageTime)) + .append(",").append("\"").append(WORST_TIMES).append("\":").append(std::to_string(kv.second.val.worstTime)) + .append("}"); } message.append("]"); - HiSysEventWrite(HiSysEvent::Domain::DISTRIBUTED_DATAMGR, - CoverEventID(DfxCodeConstant::API_PERFORMANCE_STATISTIC), - HiSysEvent::EventType::STATISTIC, - INTERFACES, message); + struct HiSysEventParam params[] = { + { .name = { *INTERFACES }, + .t = HISYSEVENT_STRING, + .v = { .s = const_cast(message.c_str()) }, + .arraySize = 0 }, + }; + OH_HiSysEvent_Write( + DATAMGR_DOMAIN, + CoverEventID(DfxCodeConstant::API_PERFORMANCE_STATISTIC).c_str(), + HISYSEVENT_STATISTIC, + params, + sizeof(params) / sizeof(params[0]) + ); apiPerformanceStat_.clear(); ZLOGI("DdsTrace interface: clean"); } @@ -373,7 +532,7 @@ void HiViewAdapter::StartTimerThread(std::shared_ptr executors) std::string HiViewAdapter::CoverEventID(int dfxCode) { - std::string sysEventID = ""; + std::string sysEventID; auto operatorIter = EVENT_COVERT_TABLE.find(dfxCode); if (operatorIter != EVENT_COVERT_TABLE.end()) { sysEventID = operatorIter->second; @@ -381,4 +540,4 @@ std::string HiViewAdapter::CoverEventID(int dfxCode) return sysEventID; } } // namespace DistributedDataDfx -} // namespace OHOS +} // namespace OHOS \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/adapter/dfx/src/hiview_adapter.h b/datamgr_service/services/distributeddataservice/adapter/dfx/src/hiview_adapter.h index cb03b82c..95835639 100644 --- a/datamgr_service/services/distributeddataservice/adapter/dfx/src/hiview_adapter.h +++ b/datamgr_service/services/distributeddataservice/adapter/dfx/src/hiview_adapter.h @@ -22,7 +22,7 @@ #include "dfx_code_constant.h" #include "dfx_types.h" #include "executor_pool.h" -#include "hisysevent.h" +#include "hisysevent_c.h" #include "value_hash.h" namespace OHOS { @@ -76,4 +76,4 @@ private: }; } // namespace DistributedDataDfx } // namespace OHOS -#endif // DISTRIBUTEDDATAMGR_HI_VIEW_ADAPTER_H +#endif // DISTRIBUTEDDATAMGR_HI_VIEW_ADAPTER_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/adapter/dfx/src/radar_reporter.cpp b/datamgr_service/services/distributeddataservice/adapter/dfx/src/radar_reporter.cpp new file mode 100644 index 00000000..56048427 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/adapter/dfx/src/radar_reporter.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "radar_reporter.h" +#include "device_manager_adapter.h" +#include "hisysevent.h" + +namespace OHOS { +namespace DistributedDataDfx { +using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; +RadarReporter::RadarReporter(const char *eventName, int32_t scene, const char *bundleName, const char *funcName) + : eventName_(eventName), funcName_(funcName) +{ + radarParam_.scene_ = scene; + radarParam_.bundleName_ = bundleName; + radarParam_.res_ = RES_IDLE; + Report(radarParam_, funcName_, BEGIN, eventName_); +} + +RadarReporter::~RadarReporter() +{ + Report(radarParam_, funcName_, END, eventName_); +} + +RadarReporter &RadarReporter::operator=(int32_t errCode) +{ + radarParam_.errCode_ = errCode; + return *this; +} + +void RadarReporter::Report(const RadarParam ¶m, const char *funcName, int32_t state, const char *eventName) +{ + int32_t res = state == BEGIN ? param.res_ : (param.errCode_ != NO_ERROR ? RES_FAILED : RES_SUCCESS); + if (state != 0) { + HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::DISTRIBUTED_DATAMGR, eventName, + OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR, ORG_PKG_LABEL, ORG_PKG, FUNC_LABEL, funcName, + BIZ_SCENE_LABEL, param.scene_, BIZ_STAGE_LABEL, param.stage_, BIZ_STATE_LABEL, state, STAGE_RES_LABEL, res, + ERROR_CODE_LABEL, param.errCode_, HOST_PKG, param.bundleName_, LOCAL_UUID_LABEL, + AnonymousUuid(DmAdapter::GetInstance().GetLocalDevice().uuid), CONCURRENT_ID, + std::to_string(param.syncId_)); + } else { + HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::DISTRIBUTED_DATAMGR, eventName, + OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR, ORG_PKG_LABEL, ORG_PKG, FUNC_LABEL, funcName, + BIZ_SCENE_LABEL, param.scene_, BIZ_STAGE_LABEL, param.stage_, STAGE_RES_LABEL, res, ERROR_CODE_LABEL, + param.errCode_, HOST_PKG, param.bundleName_, LOCAL_UUID_LABEL, + AnonymousUuid(DmAdapter::GetInstance().GetLocalDevice().uuid), CONCURRENT_ID, + std::to_string(param.syncId_)); + } + return; +} + +std::string RadarReporter::AnonymousUuid(const std::string &uuid) +{ + if (uuid.length() < BASE_SIZE) { + return DEFAULT_ANONYMOUS; + } + return (uuid.substr(0, HEAD_SIZE) + REPLACE_CHAIN + uuid.substr(uuid.length() - END_SIZE, END_SIZE)); +} +} // namespace DistributedDataDfx +} // namespace OHOS \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/adapter/dfx/test/unittest/distributeddata_dfx_ut_test.cpp b/datamgr_service/services/distributeddataservice/adapter/dfx/test/unittest/distributeddata_dfx_ut_test.cpp index f4887d3c..d79bca48 100644 --- a/datamgr_service/services/distributeddataservice/adapter/dfx/test/unittest/distributeddata_dfx_ut_test.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/dfx/test/unittest/distributeddata_dfx_ut_test.cpp @@ -277,3 +277,209 @@ HWTEST_F(DistributedataDfxUTTest, Dfx007, TestSize.Level0) FakeHivew::Clear(); } +/** + * @tc.name: Dfx008 + * @tc.desc: send data to 1 device, then check reporter message. + * @tc.type: send data + * @tc.author: nhj + */ +HWTEST_F(DistributedataDfxUTTest, Dfx008, TestSize.Level0) +{ + /** + * @tc.steps: step1. get database fault report instance + * @tc.expected: step1. Expect get instance success. + */ + auto behavior = Reporter::GetInstance()->BehaviourReporter(); + EXPECT_NE(nullptr, behavior); + struct BehaviourMsg msg{.userId = "user008", .appId = "myApp08", .storeId = "storeTest08", + .behaviourType = BehaviourType::DATABASE_BACKUP, .extensionInfo="test111"}; + + auto repStatus = behavior->Report(msg); + EXPECT_TRUE(repStatus == ReportStatus::SUCCESS); + /** + * @tc.steps:step2. check dfx reporter. + * @tc.expected: step2. Expect report message success. + */ + std::string val = FakeHivew::GetString("ANONYMOUS_UID"); + if (!val.empty()) { + EXPECT_STREQ(val.c_str(), string("user008").c_str()); + } + val = FakeHivew::GetString("APP_ID"); + if (!val.empty()) { + EXPECT_STREQ(val.c_str(), string("myApp08").c_str()); + } + val = FakeHivew::GetString("STORE_ID"); + if (!val.empty()) { + EXPECT_STREQ(val.c_str(), string("storeTest08").c_str()); + } + FakeHivew::Clear(); +} + +/** + * @tc.name: Dfx009 + * @tc.desc: Set invalid information, call getKvStore, expect return INVALID_ARGS. + * @tc.type: CreateKvStore test + * @tc.author: nhj + */ +HWTEST_F(DistributedataDfxUTTest, Dfx009, TestSize.Level0) +{ + /** + * @tc.steps: step1. Get runtime fault instance. + * @tc.expected: step1. Expect get runtime fault instance success. + */ + auto svFault = Reporter::GetInstance()->ServiceFault(); + auto svFault2 = Reporter::GetInstance()->ServiceFault(); + EXPECT_NE(nullptr, svFault); + EXPECT_EQ(svFault, svFault2); + + struct FaultMsg svMsg{FaultType::SERVICE_FAULT, "myData", "createKvStore", + Fault::SF_CREATE_DIR}; + auto rfReportRet = svFault->Report(svMsg); + /** + * @tc.steps:step2. check report message. + * @tc.expected: step2. Expected reported message. + */ + EXPECT_TRUE(rfReportRet == ReportStatus::SUCCESS); + auto val = FakeHivew::GetString("INTERFACE_NAME"); + if (!val.empty()) { + EXPECT_STREQ(string("createKvStore").c_str(), val.c_str()); + } + auto typeVal = FakeHivew::GetInt("ERROR_TYPE"); + if (typeVal > 0) { + EXPECT_EQ(static_cast(Fault::SF_CREATE_DIR), typeVal); + } + FakeHivew::Clear(); +} + +/** + * @tc.name: Dfx010 + * @tc.desc: Database file size statistic. + * @tc.type: check database file size. + * @tc.author: nhj + */ +HWTEST_F(DistributedataDfxUTTest, Dfx010, TestSize.Level0) +{ + /** + * @tc.steps: step1. get database reporter instance. + * @tc.expected: step1. Expect get success. + */ + auto dbs = Reporter::GetInstance()->DatabaseStatistic(); + EXPECT_NE(nullptr, dbs); + DbStat ds = {"uid", "appid", "storeId002", 100}; + auto dbsRet = dbs->Report(ds); + /** + * @tc.steps:step2. check reporter. + * @tc.expected: step2. Expect statistic database size is 100. + */ + EXPECT_TRUE(dbsRet == ReportStatus::SUCCESS); + auto val = FakeHivew::GetString("STORE_ID"); + if (!val.empty()) { + EXPECT_STREQ(string("storeId002").c_str(), val.c_str()); + } + auto typeVal = FakeHivew::GetInt("DB_SIZE"); + if (typeVal > 0) { + EXPECT_EQ(100, typeVal); + } + FakeHivew::Clear(); +} + +/** + * @tc.name: Dfx011 + * @tc.desc: Send UdmfBehaviourMsg + * @tc.type: Send data + * @tc.author: nhj + */ +HWTEST_F(DistributedataDfxUTTest, Dfx011, TestSize.Level0) +{ + /** + * @tc.steps: step1. get database fault report instance + * @tc.expected: step1. Expect get instance success. + */ + auto UdmfBehavior = Reporter::GetInstance()->BehaviourReporter(); + EXPECT_NE(nullptr, UdmfBehavior); + struct UdmfBehaviourMsg UdMsg{"myApp", "channel", 200, "dataType", "operation", "result"}; + auto repStatus = UdmfBehavior->UDMFReport(UdMsg); + EXPECT_TRUE(repStatus == ReportStatus::SUCCESS); + /** + * @tc.steps:step2. check dfx reporter. + * @tc.expected: step2. Expect report message success. + */ + auto val = FakeHivew::GetString("APP_ID"); + if (!val.empty()) { + EXPECT_STREQ(val.c_str(), string("myApp").c_str()); + } + auto val01 = FakeHivew::GetString("CHANNEL"); + if (!val01.empty()) { + EXPECT_STREQ(val01.c_str(), string("channel").c_str()); + } + auto val02 = FakeHivew::GetString("OPERATION"); + if (!val02.empty()) { + EXPECT_STREQ(val02.c_str(), string("operation").c_str()); + } + auto val03 = FakeHivew::GetString("RESULT"); + if (!val03.empty()) { + EXPECT_STREQ(val03.c_str(), string("result").c_str()); + } + auto val04 = FakeHivew::GetInt("DB_SIZE"); + if (val04 > 0) { + EXPECT_EQ(200, val04); + } + FakeHivew::Clear(); +} + +/** + * @tc.name: Dfx012 + * @tc.desc: send data to 1 device, then check send size. + * @tc.type: send data + * @tc.author: nhj + */ +HWTEST_F(DistributedataDfxUTTest, Dfx012, TestSize.Level0) +{ + /** + * @tc.steps:step1. send data to 1 device + * @tc.expected: step1. Expect put success. + */ + auto ts = Reporter::GetInstance()->TrafficStatistic(); + EXPECT_NE(nullptr, ts); + struct TrafficStat tss = {"appId001", "deviceId001", 100, 200}; + auto tsRet = ts->Report(tss); + /** + * @tc.steps:step2. check dfx reporter. + * @tc.expected: step2. Expect report has same size. + */ + EXPECT_TRUE(tsRet == ReportStatus::SUCCESS); + std::string myuid = "cjsdblvdfbfss11"; + std::string result; + ValueHash vh; + vh.CalcValueHash(myuid, result); + + FakeHivew::Clear(); +} + +/** + * @tc.name: Dfx013 + * @tc.desc: call api performance statistic. + * @tc.type: + * @tc.author: nhj + */ +HWTEST_F(DistributedataDfxUTTest, Dfx013, TestSize.Level0) +{ + /** + * @tc.steps:step1. create call api perforamnce statistic instance + * @tc.expected: step1. Expect get instance success. + */ + auto ap = Reporter::GetInstance()->ApiPerformanceStatistic(); + EXPECT_NE(nullptr, ap); + struct ApiPerformanceStat aps = { "interface", 2000, 500, 1000 }; + auto apRet = ap->Report(aps); + /** + * @tc.steps:step2. check dfx reporter return value. + * @tc.expected: step2. Expect report has same information. + */ + EXPECT_TRUE(apRet == ReportStatus::SUCCESS); + auto val = FakeHivew::GetString("INTERFACE_NAME"); + if (!val.empty()) { + EXPECT_STREQ(string("interface").c_str(), val.c_str()); + } + FakeHivew::Clear(); +} \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/adapter/include/account/account_delegate.h b/datamgr_service/services/distributeddataservice/adapter/include/account/account_delegate.h index d697af14..4c645815 100644 --- a/datamgr_service/services/distributeddataservice/adapter/include/account/account_delegate.h +++ b/datamgr_service/services/distributeddataservice/adapter/include/account/account_delegate.h @@ -64,9 +64,12 @@ public: API_EXPORT virtual void UnsubscribeAccountEvent() = 0; API_EXPORT virtual bool QueryUsers(std::vector &users) = 0; API_EXPORT virtual bool QueryForegroundUsers(std::vector &users) = 0; + API_EXPORT virtual bool IsLoginAccount() = 0; + API_EXPORT virtual bool QueryForegroundUserId(int &foregroundUserId) = 0; API_EXPORT virtual bool IsVerified(int userId) = 0; API_EXPORT virtual bool RegisterHashFunc(HashFunc hash) = 0; API_EXPORT virtual void BindExecutor(std::shared_ptr executors) = 0; + API_EXPORT virtual std::string GetUnencryptedAccountId(int32_t userId = 0) const = 0; API_EXPORT static AccountDelegate *GetInstance(); private: @@ -75,4 +78,4 @@ private: }; } // namespace DistributedKv } // namespace OHOS -#endif // DISTRIBUTEDDATAMGR_ACCOUNT_DELEGATE_H +#endif // DISTRIBUTEDDATAMGR_ACCOUNT_DELEGATE_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/adapter/include/communicator/commu_types.h b/datamgr_service/services/distributeddataservice/adapter/include/communicator/commu_types.h index a940196a..afe72286 100644 --- a/datamgr_service/services/distributeddataservice/adapter/include/communicator/commu_types.h +++ b/datamgr_service/services/distributeddataservice/adapter/include/communicator/commu_types.h @@ -27,6 +27,7 @@ struct API_EXPORT DeviceInfo { std::string deviceName; uint32_t deviceType; int32_t osType; + int32_t authForm; }; enum RouteType : int32_t { diff --git a/datamgr_service/services/distributeddataservice/adapter/include/communicator/communicator_context.h b/datamgr_service/services/distributeddataservice/adapter/include/communicator/communicator_context.h index 1c045697..a77a2db3 100644 --- a/datamgr_service/services/distributeddataservice/adapter/include/communicator/communicator_context.h +++ b/datamgr_service/services/distributeddataservice/adapter/include/communicator/communicator_context.h @@ -39,7 +39,7 @@ public: void NotifySessionReady(const std::string &deviceId); void NotifySessionClose(const std::string &deviceId); void SetSessionListener(const OnCloseAble &closeAbleCallback); - API_EXPORT bool IsSessionReady(const std::string &deviceId); + bool IsSessionReady(const std::string &deviceId); private: CommunicatorContext() = default; 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 3fd6556e..f02d2891 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 @@ -61,7 +61,8 @@ public: std::vector GetRemoteDevices(); std::vector GetOnlineDevices(); bool IsDeviceReady(const std::string &id); - bool IsOHOsType(const std::string &id); + bool IsOHOSType(const std::string &id); + std::string GetEncryptedUuidByNetworkId(const std::string &networkId); size_t GetOnlineSize(); DeviceInfo GetDeviceInfo(const std::string &id); std::string GetUuidByNetworkId(const std::string &networkId); @@ -75,6 +76,7 @@ public: void NotifyReadyEvent(const std::string &uuid); bool IsNetworkAvailable(); NetworkType GetNetworkType(bool retrieve = false); + int32_t GetAuthType(const std::string& id); friend class DataMgrDmStateCall; friend class NetConnCallbackObserver; @@ -114,8 +116,8 @@ private: std::shared_ptr executors_; static constexpr int32_t EFFECTIVE_DURATION = 30 * 1000; // ms static constexpr int32_t NET_LOST_DURATION = 10 * 1000; // ms - uint64_t expireTime_ = GetTimeStamp(); - uint64_t netLostTime_ = GetTimeStamp(); + uint64_t expireTime_ = 0; + uint64_t netLostTime_ = 0; NetworkType defaultNetwork_ = NONE; ConcurrentMap> readyDevices_; }; diff --git a/datamgr_service/services/distributeddataservice/adapter/include/dfx/radar_reporter.h b/datamgr_service/services/distributeddataservice/adapter/include/dfx/radar_reporter.h new file mode 100644 index 00000000..72a6752b --- /dev/null +++ b/datamgr_service/services/distributeddataservice/adapter/include/dfx/radar_reporter.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DISTRIBUTEDDATAMGR_RADAR_REPORTER_H +#define DISTRIBUTEDDATAMGR_RADAR_REPORTER_H +#include +#include + +#include "visibility.h" + +namespace OHOS { +namespace DistributedDataDfx { + +enum BizScene { + // cloud sync + CLOUD_SYNC = 1, + + // cloud share + SHARE = 1, + UNSHARE = 2, + CONFIRM_INVITATION = 3, + CHANGE_CONFIRMATION = 4, + CHANGE_PRIVILEGE = 5, + EXIT_SHARING = 6, +}; + +enum BizStage { + // cloud share + GENERAL_STAGE = 1, + + // cloud sync + TRIGGER_SYNC = 1, + CHECK_SYNC_CONDITION = 2, + START_SYNC = 3, + FINISH_SYNC = 4, +}; + +enum BizState { + BEGIN = 1, + END = 2, +}; + +enum StageRes { + RES_IDLE = 0, + RES_SUCCESS = 1, + RES_FAILED = 2, + RES_CANCELLED = 3, + RES_UNKNOWN = 4, +}; + +struct EventName { + static constexpr const char *CLOUD_SYNC_BEHAVIOR = "DISTRIBUTED_CLOUD_SYNC_BEHAVIOR"; + static constexpr const char *CLOUD_SHARING_BEHAVIOR = "DISTRIBUTED_CLOUD_SHARE_BEHAVIOR"; +}; + +struct RadarParam { + const char *bundleName_ = ""; + int32_t scene_ = CLOUD_SYNC; + int32_t stage_ = GENERAL_STAGE; + uint64_t syncId_ = 0; + int32_t errCode_ = 0; + int32_t res_ = RES_SUCCESS; +}; + +class RadarReporter { +public: + KVSTORE_API RadarReporter(const char *eventName, int32_t scene, const char *bundleName, const char *funcName); + KVSTORE_API ~RadarReporter(); + KVSTORE_API RadarReporter &operator=(int32_t errCode); + KVSTORE_API static void Report(const RadarParam ¶m, const char *funcName, int32_t state = 0, + const char *eventName = EventName::CLOUD_SYNC_BEHAVIOR); + +private: + static std::string AnonymousUuid(const std::string &uuid); + RadarParam radarParam_; + const char *eventName_ = EventName::CLOUD_SYNC_BEHAVIOR; + const char *funcName_; + + static constexpr const char *ORG_PKG_LABEL = "ORG_PKG"; + static constexpr const char *ORG_PKG = "distributddata"; + static constexpr const char *FUNC_LABEL = "FUNC"; + static constexpr const char *BIZ_SCENE_LABEL = "BIZ_SCENE"; + static constexpr const char *BIZ_STATE_LABEL = "BIZ_STATE"; + static constexpr const char *BIZ_STAGE_LABEL = "BIZ_STAGE"; + static constexpr const char *STAGE_RES_LABEL = "STAGE_RES"; + static constexpr const char *ERROR_CODE_LABEL = "ERROR_CODE"; + static constexpr const char *LOCAL_UUID_LABEL = "LOCAL_UUID"; + static constexpr const char *HOST_PKG = "HOST_PKG"; + static constexpr const char *UNKNOW = "UNKNOW"; + static constexpr const char *REPLACE_CHAIN = "**"; + static constexpr const char *DEFAULT_ANONYMOUS = "************"; + static constexpr const char *CONCURRENT_ID = "CONCURRENT_ID"; + static constexpr const int32_t NO_ERROR = 0; + static constexpr const int32_t HEAD_SIZE = 5; + static constexpr const int32_t END_SIZE = 5; + static constexpr const int32_t BASE_SIZE = 12; +}; +} // namespace DistributedDataDfx +} // namespace OHOS +#endif // DISTRIBUTEDDATAMGR_RADAR_REPORTER_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/adapter/permission/BUILD.gn b/datamgr_service/services/distributeddataservice/adapter/permission/BUILD.gn index 659f5f8b..f4f3a0e1 100644 --- a/datamgr_service/services/distributeddataservice/adapter/permission/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/adapter/permission/BUILD.gn @@ -19,6 +19,8 @@ ohos_static_library("distributeddata_permission_static") { cfi = true cfi_cross_dso = true debug = false + boundary_sanitize = true + ubsan = true } sources = [ "src/permission_validator.cpp" ] diff --git a/datamgr_service/services/distributeddataservice/adapter/utils/BUILD.gn b/datamgr_service/services/distributeddataservice/adapter/utils/BUILD.gn index d2813552..eb32cd54 100644 --- a/datamgr_service/services/distributeddataservice/adapter/utils/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/adapter/utils/BUILD.gn @@ -19,6 +19,8 @@ ohos_static_library("distributeddata_utils_static") { cfi = true cfi_cross_dso = true debug = false + boundary_sanitize = true + ubsan = true } sources = [ "src/kvstore_utils.cpp" ] diff --git a/datamgr_service/services/distributeddataservice/app/BUILD.gn b/datamgr_service/services/distributeddataservice/app/BUILD.gn index 9435af06..cc59341f 100644 --- a/datamgr_service/services/distributeddataservice/app/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/app/BUILD.gn @@ -41,33 +41,32 @@ config("module_private_config") { "${kv_store_common_path}", "${kv_store_path}/frameworks/innerkitsimpl/distributeddatasvc/include", "${kv_store_path}/frameworks/innerkitsimpl/distributeddatafwk/include", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/bootstrap/include", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/config/include", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/crypto/include", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/directory/include", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/permission/include", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/matrix/include", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/app/src/session_manager", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/framework/include", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/backup/include", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/kvdb", - "${device_manager_path}/interfaces/inner_kits/native_cpp/include", - "${distributedfilejs_path}/interfaces/kits/js/src/mod_securitylabel", - "../adapter/include/account", - "../adapter/include/permission", - "../adapter/include/installer", - "../adapter/include/broadcaster", - "../adapter/include/utils", - "../adapter/include/dfx", - "../adapter/include", - "../service/dumper/include", + "${data_service_path}/adapter/include/account", + "${data_service_path}/adapter/include/permission", + "${data_service_path}/adapter/include/installer", + "${data_service_path}/adapter/include/broadcaster", + "${data_service_path}/adapter/include/utils", + "${data_service_path}/adapter/include/dfx", + "${data_service_path}/adapter/include", + "${data_service_path}/app/src/session_manager", + "${data_service_path}/framework/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/directory/include", + "${data_service_path}/service/permission/include", + "${data_service_path}/service/matrix/include", + "${data_service_path}/service/backup/include", + "${data_service_path}/service/kvdb", + "${data_service_path}/service/waterversion", + "${data_service_path}/service/dumper/include", # for ipc_core interfaces. "include", "src", "src/security", "src/backup_rule/include", - "//third_party/json/single_include", ] cflags = [ "-Wno-multichar" ] @@ -81,8 +80,11 @@ ohos_shared_library("distributeddataservice") { cfi = true cfi_cross_dso = true debug = false + boundary_sanitize = true + ubsan = true } sources = [ + "${data_service_path}/service/common/xcollie.cpp", "src/db_info_handle_impl.cpp", "src/feature_stub_impl.cpp", "src/kvstore_account_observer.cpp", @@ -108,14 +110,14 @@ ohos_shared_library("distributeddataservice") { configs = [ ":module_private_config" ] deps = [ + "${data_service_path}/adapter:distributeddata_adapter", + "${data_service_path}/adapter/broadcaster:distributeddata_broadcaster_static", + "${data_service_path}/adapter/utils:distributeddata_utils_static", + "${data_service_path}/app/src/checker:distributeddata_checker_static", + "${data_service_path}/app/src/flowctrl_manager:distributeddata_flowctrl_static", "${data_service_path}/app/src/installer:distributeddata_installer_static", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter:distributeddata_adapter", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/broadcaster:distributeddata_broadcaster_static", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/utils:distributeddata_utils_static", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/app/src/checker:distributeddata_checker_static", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/app/src/flowctrl_manager:distributeddata_flowctrl_static", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/framework:distributeddatasvcfwk", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service:distributeddatasvc", + "${data_service_path}/framework:distributeddatasvcfwk", + "${data_service_path}/service:distributeddatasvc", ] external_deps = [ @@ -126,14 +128,18 @@ ohos_shared_library("distributeddataservice") { "bundle_framework:appexecfwk_core", "c_utils:utils", "dataclassification:data_transit_mgr", + "file_api:securitylabel", + "hicollie:libhicollie", "hilog:libhilog", "hisysevent:libhisysevent", "hitrace:hitrace_meter", "hitrace:libhitracechain", "ipc:ipc_core", + "json:nlohmann_json_static", "kv_store:distributeddata_inner", "kv_store:distributeddata_mgr", "kv_store:distributeddb", + "memmgr:memmgrclient", "safwk:system_ability_fwk", "samgr:samgr_proxy", ] diff --git a/datamgr_service/services/distributeddataservice/app/CMakeLists.txt b/datamgr_service/services/distributeddataservice/app/CMakeLists.txt index 251306eb..2faa483b 100644 --- a/datamgr_service/services/distributeddataservice/app/CMakeLists.txt +++ b/datamgr_service/services/distributeddataservice/app/CMakeLists.txt @@ -26,6 +26,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/security) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/session_manager) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/checker) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../service/bootstrap/include) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../service/common) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../service/config/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../service/crypto/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../service/permission/include) diff --git a/datamgr_service/services/distributeddataservice/app/src/checker/BUILD.gn b/datamgr_service/services/distributeddataservice/app/src/checker/BUILD.gn index bd569256..ef5c271e 100644 --- a/datamgr_service/services/distributeddataservice/app/src/checker/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/app/src/checker/BUILD.gn @@ -19,6 +19,8 @@ ohos_static_library("distributeddata_checker_static") { cfi = true cfi_cross_dso = true debug = false + boundary_sanitize = true + ubsan = true } sources = [ "bundle_checker.cpp", diff --git a/datamgr_service/services/distributeddataservice/app/src/feature_stub_impl.cpp b/datamgr_service/services/distributeddataservice/app/src/feature_stub_impl.cpp index bd206e4b..a690ddbe 100644 --- a/datamgr_service/services/distributeddataservice/app/src/feature_stub_impl.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/feature_stub_impl.cpp @@ -124,4 +124,12 @@ int32_t FeatureStubImpl::OnSessionReady(const std::string &device) } return featureImpl_->OnSessionReady(device); } + +int32_t FeatureStubImpl::OnScreenUnlocked(int32_t user) +{ + if (featureImpl_ == nullptr) { + return -1; + } + return featureImpl_->OnScreenUnlocked(user); +} } diff --git a/datamgr_service/services/distributeddataservice/app/src/feature_stub_impl.h b/datamgr_service/services/distributeddataservice/app/src/feature_stub_impl.h index d4a2fb51..e9249a76 100644 --- a/datamgr_service/services/distributeddataservice/app/src/feature_stub_impl.h +++ b/datamgr_service/services/distributeddataservice/app/src/feature_stub_impl.h @@ -41,6 +41,7 @@ public: int32_t Offline(const std::string &device); int32_t OnReady(const std::string &device); int32_t OnSessionReady(const std::string &device); + int32_t OnScreenUnlocked(int32_t user); private: std::shared_ptr featureImpl_; diff --git a/datamgr_service/services/distributeddataservice/app/src/flowctrl_manager/BUILD.gn b/datamgr_service/services/distributeddataservice/app/src/flowctrl_manager/BUILD.gn index 6ef599f8..58bb2bd7 100644 --- a/datamgr_service/services/distributeddataservice/app/src/flowctrl_manager/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/app/src/flowctrl_manager/BUILD.gn @@ -20,6 +20,8 @@ ohos_static_library("distributeddata_flowctrl_static") { cfi = true cfi_cross_dso = true debug = false + boundary_sanitize = true + ubsan = true } sources = [ "kvstore_flowctrl_manager.cpp" ] @@ -29,12 +31,14 @@ ohos_static_library("distributeddata_flowctrl_static") { "${kv_store_path}/frameworks/innerkitsimpl/distributeddatasvc/include", "${kv_store_path}/frameworks/innerkitsimpl/distributeddatafwk/include", "${kv_store_path}/interfaces/innerkits/distributeddata/include", - "//third_party/json/single_include", ] cflags_cc = [ "-fvisibility=hidden" ] - external_deps = [ "c_utils:utils" ] + external_deps = [ + "c_utils:utils", + "json:nlohmann_json_static", + ] subsystem_name = "distributeddatamgr" part_name = "datamgr_service" diff --git a/datamgr_service/services/distributeddataservice/app/src/installer/BUILD.gn b/datamgr_service/services/distributeddataservice/app/src/installer/BUILD.gn index c4c6195a..a4ee8a56 100644 --- a/datamgr_service/services/distributeddataservice/app/src/installer/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/app/src/installer/BUILD.gn @@ -20,6 +20,8 @@ ohos_static_library("distributeddata_installer_static") { cfi = true cfi_cross_dso = true debug = false + boundary_sanitize = true + ubsan = true } sources = [ "installer.cpp", @@ -32,19 +34,17 @@ ohos_static_library("distributeddata_installer_static") { "${kv_store_path}/frameworks/innerkitsimpl/distributeddatasvc/include", "${kv_store_path}/frameworks/innerkitsimpl/distributeddatafwk/include", "${kv_store_path}/interfaces/innerkits/distributeddata/include", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/framework/include", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/kvdb", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/permission/include", - "${device_manager_path}/interfaces/inner_kits/native_cpp/include", - "//third_party/json/single_include", + "${data_service_path}/framework/include", + "${data_service_path}/service/kvdb", + "${data_service_path}/service/permission/include", ] cflags_cc = [ "-fvisibility=hidden" ] deps = [ - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter:distributeddata_adapter", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/framework:distributeddatasvcfwk", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service:distributeddatasvc", + "${data_service_path}/adapter:distributeddata_adapter", + "${data_service_path}/framework:distributeddatasvcfwk", + "${data_service_path}/service:distributeddatasvc", ] external_deps = [ diff --git a/datamgr_service/services/distributeddataservice/app/src/installer/installer_impl.cpp b/datamgr_service/services/distributeddataservice/app/src/installer/installer_impl.cpp index 6cedd71a..0ec512f6 100644 --- a/datamgr_service/services/distributeddataservice/app/src/installer/installer_impl.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/installer/installer_impl.cpp @@ -60,6 +60,10 @@ void InstallEventSubscriber::OnReceiveEvent(const CommonEventData &event) int32_t appIndex = want.GetIntParam(SANDBOX_APP_INDEX, 0); ZLOGI("bundleName:%{public}s, user:%{public}d, appIndex:%{public}d", bundleName.c_str(), userId, appIndex); (this->*(it->second))(bundleName, userId, appIndex); + } else if (action == CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED) { + int32_t userId = want.GetIntParam(USER_ID, -1); + ZLOGI("user:%{public}d ScreenUnlocked", userId); + OnScreenUnlocked(userId); } } @@ -85,6 +89,7 @@ void InstallEventSubscriber::OnUninstall(const std::string &bundleName, int32_t MetaDataManager::GetInstance().DelMeta(meta.appId, true); MetaDataManager::GetInstance().DelMeta(meta.GetKeyLocal(), true); PermitDelegate::GetInstance().DelCache(meta.GetKey()); + MetaDataManager::GetInstance().DelMeta(meta.GetAutoLaunchKey(), true); } } } @@ -114,6 +119,11 @@ void InstallEventSubscriber::OnInstall(const std::string &bundleName, int32_t us kvStoreDataService_->OnInstall(bundleName, userId, appIndex); } +void InstallEventSubscriber::OnScreenUnlocked(int32_t userId) +{ + kvStoreDataService_->OnScreenUnlocked(userId); +} + InstallerImpl::~InstallerImpl() { ZLOGD("destruct"); @@ -143,6 +153,7 @@ Status InstallerImpl::Init(KvStoreDataService *kvStoreDataService, std::shared_p matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED); matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED); matchingSkills.AddEvent(OHOS::AppExecFwk::COMMON_EVENT_SANDBOX_PACKAGE_ADDED); + matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED); CommonEventSubscribeInfo info(matchingSkills); auto subscriber = std::make_shared(info, kvStoreDataService); diff --git a/datamgr_service/services/distributeddataservice/app/src/installer/installer_impl.h b/datamgr_service/services/distributeddataservice/app/src/installer/installer_impl.h index 683ae729..aabcd933 100644 --- a/datamgr_service/services/distributeddataservice/app/src/installer/installer_impl.h +++ b/datamgr_service/services/distributeddataservice/app/src/installer/installer_impl.h @@ -36,6 +36,7 @@ private: void OnUninstall(const std::string &bundleName, int32_t userId, int32_t appIndex); void OnUpdate(const std::string &bundleName, int32_t userId, int32_t appIndex); void OnInstall(const std::string &bundleName, int32_t userId, int32_t appIndex); + void OnScreenUnlocked(int32_t userId); std::map callbacks_; KvStoreDataService *kvStoreDataService_; }; diff --git a/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.cpp b/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.cpp index f7811c54..94d55d6c 100644 --- a/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include "accesstoken_kit.h" #include "auth_delegate.h" @@ -39,6 +40,8 @@ #include "iservice_registry.h" #include "kvstore_account_observer.h" #include "log_print.h" +#include "mem_mgr_client.h" +#include "mem_mgr_proxy.h" #include "metadata/appid_meta_data.h" #include "metadata/meta_data_manager.h" #include "metadata/secret_key_meta_data.h" @@ -112,10 +115,10 @@ void KvStoreDataService::Initialize() #endif CommunicatorContext::GetInstance().SetThreadPool(executors_); auto communicator = std::make_shared(RouteHeadHandlerImpl::Create); + DistributedDB::RuntimeConfig::SetDBInfoHandle(std::make_shared()); auto ret = KvStoreDelegateManager::SetProcessCommunicator(communicator); ZLOGI("set communicator ret:%{public}d.", static_cast(ret)); - WaterVersionManager::GetInstance().Init(); AppDistributedKv::CommunicationProvider::GetInstance(); PermitDelegate::GetInstance().Init(); InitSecurityAdapter(executors_); @@ -138,7 +141,6 @@ void KvStoreDataService::Initialize() return Upgrade::GetInstance().GetEncryptedUuidByMeta(meta); }; DBConfig::SetTranslateToDeviceIdCallback(translateCall); - DistributedDB::RuntimeConfig::SetDBInfoHandle(std::make_shared()); } sptr KvStoreDataService::GetFeatureInterface(const std::string &name) @@ -297,6 +299,7 @@ void KvStoreDataService::OnStart() } } AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID); + AddSystemAbilityListener(MEMORY_MANAGER_SA_ID); RegisterStoreInfo(); Handler handlerStoreInfo = std::bind(&KvStoreDataService::DumpStoreInfo, this, std::placeholders::_1, std::placeholders::_2); @@ -316,11 +319,14 @@ void KvStoreDataService::OnAddSystemAbility(int32_t systemAbilityId, const std:: { ZLOGI("add system abilityid:%{public}d", systemAbilityId); (void)deviceId; - if (systemAbilityId != COMMON_EVENT_SERVICE_ID) { - return; + if (systemAbilityId == COMMON_EVENT_SERVICE_ID) { + AccountDelegate::GetInstance()->SubscribeAccountEvent(); + Installer::GetInstance().Init(this, executors_); + } else if (systemAbilityId == MEMORY_MANAGER_SA_ID) { + Memory::MemMgrClient::GetInstance().NotifyProcessStatus(getpid(), 1, 1, + DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID); } - AccountDelegate::GetInstance()->SubscribeAccountEvent(); - Installer::GetInstance().Init(this, executors_); + return; } void KvStoreDataService::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId) @@ -341,6 +347,7 @@ void KvStoreDataService::StartService() KvStoreMetaManager::GetInstance().InitMetaListener(); DeviceMatrix::GetInstance().Initialize(IPCSkeleton::GetCallingTokenID(), Bootstrap::GetInstance().GetMetaDBName()); AutoSyncMatrix::GetInstance().Initialize(); + WaterVersionManager::GetInstance().Init(); LoadFeatures(); bool ret = SystemAbility::Publish(this); if (!ret) { @@ -364,7 +371,7 @@ void KvStoreDataService::StartService() return status; }; KvStoreDelegateManager::SetAutoLaunchRequestCallback(autoLaunch); - ZLOGI("Publish ret: %{public}d", static_cast(ret)); + ZLOGI("Start distributedata Success, Publish ret: %{public}d", static_cast(ret)); } void KvStoreDataService::OnStoreMetaChanged( @@ -392,7 +399,6 @@ void KvStoreDataService::OnStoreMetaChanged( bool KvStoreDataService::ResolveAutoLaunchParamByIdentifier( const std::string &identifier, DistributedDB::AutoLaunchParam ¶m) { - ZLOGI("start"); std::vector entries; std::string localDeviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; if (!MetaDataManager::GetInstance().LoadMeta(StoreMetaData::GetPrefix({ localDeviceId }), entries)) { @@ -400,6 +406,7 @@ bool KvStoreDataService::ResolveAutoLaunchParamByIdentifier( return false; } + auto accountId = AccountDelegate::GetInstance()->GetUnencryptedAccountId(); for (const auto &storeMeta : entries) { if ((!param.userId.empty() && (param.userId != storeMeta.user)) || (localDeviceId != storeMeta.deviceId) || ((StoreMetaData::STORE_RELATIONAL_BEGIN <= storeMeta.storeType) && @@ -408,13 +415,12 @@ bool KvStoreDataService::ResolveAutoLaunchParamByIdentifier( continue; } const std::string &itemTripleIdentifier = - DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(storeMeta.user, storeMeta.appId, + DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(accountId, storeMeta.appId, storeMeta.storeId, false); const std::string &itemDualIdentifier = DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier("", storeMeta.appId, storeMeta.storeId, true); if (identifier == itemTripleIdentifier && storeMeta.bundleName != Bootstrap::GetInstance().GetProcessLabel()) { - // old triple tuple identifier, should SetEqualIdentifier - ResolveAutoLaunchCompatible(storeMeta, identifier); + ResolveAutoLaunchCompatible(storeMeta, identifier, accountId); } if (identifier == itemDualIdentifier || identifier == itemTripleIdentifier) { ZLOGI("identifier find"); @@ -464,17 +470,18 @@ DistributedDB::SecurityOption KvStoreDataService::ConvertSecurity(int securityLe } } -void KvStoreDataService::ResolveAutoLaunchCompatible(const StoreMetaData &storeMeta, const std::string &identifier) +void KvStoreDataService::ResolveAutoLaunchCompatible(const StoreMetaData &storeMeta, const std::string &identifier, + const std::string &accountId) { - ZLOGI("AutoLaunch:peer device is old tuple, begin to open store"); - if (storeMeta.storeType > KvStoreType::SINGLE_VERSION || storeMeta.version > STORE_VERSION) { + if (storeMeta.storeType > KvStoreType::SINGLE_VERSION) { ZLOGW("no longer support multi or higher version store type"); return; } - + ZLOGI("AutoLaunch:peer device is old tuple, begin to open store, storeId: %{public}s", + Anonymous::Change(storeMeta.storeId).c_str()); // open store and SetEqualIdentifier, then close store after 60s DistributedDB::KvStoreDelegateManager delegateManager(storeMeta.appId, storeMeta.user); - delegateManager.SetKvStoreConfig({ storeMeta.dataDir }); + delegateManager.SetKvStoreConfig({ DirectoryManager::GetInstance().GetStorePath(storeMeta) }); Options options = { .createIfMissing = false, .encrypt = storeMeta.isEncrypt, @@ -494,12 +501,11 @@ void KvStoreDataService::ResolveAutoLaunchCompatible(const StoreMetaData &storeM InitNbDbOption(options, secretKey.sKey, dbOptions); DistributedDB::KvStoreNbDelegate *store = nullptr; delegateManager.GetKvStore(storeMeta.storeId, dbOptions, - [&store, &storeMeta](int status, DistributedDB::KvStoreNbDelegate *delegate) { + [&store, &storeMeta, &accountId](int status, DistributedDB::KvStoreNbDelegate *delegate) { ZLOGI("temporary open db for equal identifier, ret:%{public}d", status); if (delegate != nullptr) { - KvStoreTuple tuple = { storeMeta.user, storeMeta.appId, storeMeta.storeId }; - UpgradeManager::SetCompatibleIdentifyByType(delegate, tuple, IDENTICAL_ACCOUNT_GROUP); - UpgradeManager::SetCompatibleIdentifyByType(delegate, tuple, PEER_TO_PEER_GROUP); + KvStoreTuple tuple = { accountId, storeMeta.appId, storeMeta.storeId }; + UpgradeManager::SetCompatibleIdentifyByType(delegate, tuple); store = delegate; } }); @@ -549,6 +555,7 @@ Status KvStoreDataService::InitNbDbOption(const Options &options, const std::vec void KvStoreDataService::OnStop() { ZLOGI("begin."); + Memory::MemMgrClient::GetInstance().NotifyProcessStatus(getpid(), 1, 0, DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID); } KvStoreDataService::KvStoreClientDeathObserverImpl::KvStoreClientDeathObserverImpl( @@ -790,6 +797,15 @@ int32_t KvStoreDataService::OnInstall(const std::string &bundleName, int32_t use return SUCCESS; } +int32_t KvStoreDataService::OnScreenUnlocked(int32_t user) +{ + features_.ForEachCopies([user](const auto &key, sptr &value) { + value->OnScreenUnlocked(user); + return false; + }); + return SUCCESS; +} + int32_t KvStoreDataService::ClearAppStorage(const std::string &bundleName, int32_t userId, int32_t appIndex, int32_t tokenId) { diff --git a/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.h b/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.h index c3e0a818..ae5b3b1c 100644 --- a/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.h +++ b/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.h @@ -118,6 +118,8 @@ public: int32_t OnInstall(const std::string &bundleName, int32_t user, int32_t index); + int32_t OnScreenUnlocked(int32_t user); + private: void NotifyAccountEvent(const AccountEventInfo &eventInfo); class KvStoreClientDeathObserverImpl { @@ -165,7 +167,8 @@ private: Status AppExit(pid_t uid, pid_t pid, uint32_t token, const AppId &appId); bool ResolveAutoLaunchParamByIdentifier(const std::string &identifier, DistributedDB::AutoLaunchParam ¶m); - void ResolveAutoLaunchCompatible(const StoreMetaData &storeMeta, const std::string &identifier); + void ResolveAutoLaunchCompatible(const StoreMetaData &storeMeta, const std::string &identifier, + const std::string &accountId); static DistributedDB::SecurityOption ConvertSecurity(int securityLevel); static Status InitNbDbOption(const Options &options, const std::vector &cipherKey, DistributedDB::KvStoreNbDelegate::Option &dbOption); diff --git a/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service_stub.cpp b/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service_stub.cpp index f8a13daa..ca3deb44 100644 --- a/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service_stub.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service_stub.cpp @@ -21,14 +21,17 @@ #include "message_parcel.h" #include "types.h" #include "log_print.h" +#include "xcollie.h" namespace OHOS { namespace DistributedKv { +using namespace OHOS::DistributedData; constexpr KvStoreDataServiceStub::RequestHandler KvStoreDataServiceStub::HANDLERS[static_cast(KvStoreDataServiceInterfaceCode::SERVICE_CMD_LAST)]; int32_t KvStoreDataServiceStub::RegisterClientDeathObserverOnRemote(MessageParcel &data, MessageParcel &reply) { + XCollie xcollie(__FUNCTION__, HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY); AppId appId = { data.ReadString() }; sptr kvStoreClientDeathObserverProxy = data.ReadRemoteObject(); if (kvStoreClientDeathObserverProxy == nullptr) { @@ -43,6 +46,7 @@ int32_t KvStoreDataServiceStub::RegisterClientDeathObserverOnRemote(MessageParce int32_t KvStoreDataServiceStub::GetFeatureInterfaceOnRemote(MessageParcel &data, MessageParcel &reply) { + XCollie xcollie(__FUNCTION__, HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY); std::string name; if (!ITypesUtil::Unmarshal(data, name)) { return -1; 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 c3466956..31a5fd76 100644 --- a/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.cpp @@ -22,6 +22,7 @@ #include "account_delegate.h" #include "bootstrap.h" +#include "cloud/change_event.h" #include "communication_provider.h" #include "crypto_manager.h" #include "device_manager_adapter.h" @@ -29,16 +30,22 @@ #include "directory/directory_manager.h" #include "eventcenter/event_center.h" #include "kvstore_data_service.h" +#include "kv_radar_reporter.h" #include "log_print.h" #include "matrix_event.h" #include "metadata/meta_data_manager.h" +#include "metadata/store_meta_data_local.h" #include "metadata/version_meta_data.h" #include "runtime_config.h" +#include "safe_block_queue.h" +#include "store/general_store.h" +#include "store/store_info.h" #include "utils/anonymous.h" #include "utils/block_integer.h" #include "utils/crypto.h" #include "utils/ref_count.h" #include "utils/converter.h" +#include "water_version_manager.h" namespace OHOS { namespace DistributedKv { @@ -87,17 +94,8 @@ void KvStoreMetaManager::InitMetaListener() ZLOGW("register metaMgr failed: %{public}d.", status); return; } - status = DmAdapter::GetInstance().StartWatchDeviceChange(&dbInfoListener_, { "notifyDbInfos" }); - if (status != AppDistributedKv::Status::SUCCESS) { - ZLOGW("register notifyDbInfos failed: %{public}d.", status); - return; - } - ZLOGI("register metaMgr and notifyDbInfos device change success."); - SubscribeMetaKvStore(); - SyncMeta(); InitBroadcast(); - InitDeviceOnline(); NotifyAllAutoSyncDBInfo(); } @@ -128,41 +126,6 @@ void KvStoreMetaManager::InitBroadcast() ZLOGI("observer matrix broadcast %{public}d.", result); } -void KvStoreMetaManager::InitDeviceOnline() -{ - ZLOGI("observer matrix online event."); - using DBStatuses = std::map; - EventCenter::GetInstance().Subscribe(DeviceMatrix::MATRIX_ONLINE, [this](const Event &event) { - auto &matrixEvent = static_cast(event); - auto data = matrixEvent.GetMatrixData(); - auto deviceId = matrixEvent.GetDeviceId(); - auto onComplete = - [deviceId, data, refCount = matrixEvent.StealRefCount()](const DBStatuses &statuses) mutable { - auto finEvent = std::make_unique(DeviceMatrix::MATRIX_META_FINISHED, deviceId, data); - finEvent->SetRefCount(std::move(refCount)); - auto it = statuses.find(deviceId); - if (it != statuses.end() && it->second == DBStatus::OK) { - DeviceMatrix::GetInstance().OnExchanged(deviceId, DeviceMatrix::META_STORE_MASK); - } - ZLOGI("dynamic:0x%{public}08x statics:0x%{public}08x device:%{public}s status:%{public}d online", - data.dynamic, data.statics, Anonymous::Change(deviceId).c_str(), - it == statuses.end() ? DBStatus::OK : it->second); - EventCenter::GetInstance().PostEvent(std::move(finEvent)); - }; - auto store = GetMetaKvStore(); - uint16_t mask = data.dynamic & DEFAULT_MASK; - if (((mask & DeviceMatrix::META_STORE_MASK) != 0) && store != nullptr) { - auto status = store->Sync({ deviceId }, DistributedDB::SyncMode::SYNC_MODE_PUSH_PULL, onComplete); - if (status == OK) { - return; - } - ZLOGW("meta online sync error 0x%{public}08x device:%{public}s %{public}d", mask, - Anonymous::Change(deviceId).c_str(), status); - } - onComplete({ }); - }); -} - void KvStoreMetaManager::InitMetaData() { ZLOGI("start."); @@ -185,6 +148,7 @@ void KvStoreMetaManager::InitMetaData() data.isAutoSync = false; data.isBackup = false; data.isEncrypt = false; + data.isNeedCompress = true; data.storeType = KvStoreType::SINGLE_VERSION; data.dataType = DataType::TYPE_DYNAMICAL; data.schema = ""; @@ -195,12 +159,20 @@ void KvStoreMetaManager::InitMetaData() data.securityLevel = SecurityLevel::S1; data.area = EL1; data.tokenId = tokenId; + StoreMetaDataLocal localData; + localData.isAutoSync = false; + localData.isBackup = false; + localData.isEncrypt = false; + localData.dataDir = metaDBDirectory_; + localData.schema = ""; + localData.isPublic = true; if (!(MetaDataManager::GetInstance().SaveMeta(data.GetKey(), data) && - MetaDataManager::GetInstance().SaveMeta(data.GetKey(), data, true))) { + MetaDataManager::GetInstance().SaveMeta(data.GetKey(), data, true) && + MetaDataManager::GetInstance().SaveMeta(data.GetKeyLocal(), localData, true))) { ZLOGE("save meta fail"); } UpdateMetaData(); - SetSyncer(); + SetCloudSyncer(); ZLOGI("end."); } @@ -262,33 +234,47 @@ KvStoreMetaManager::NbDelegate KvStoreMetaManager::GetMetaKvStore() if (metaDelegate_ != nullptr) { return metaDelegate_; } - std::lock_guard lock(mutex_); - if (metaDelegate_ == nullptr) { - metaDelegate_ = CreateMetaKvStore(); - auto fullName = GetBackupPath(); - auto backup = [fullName](const auto &store) -> int32_t { - DistributedDB::CipherPassword password; - return store->Export(fullName, password); - }; - MetaDataManager::GetInstance().Initialize(metaDelegate_, backup); + if (metaDelegate_ != nullptr) { + return metaDelegate_; } + + metaDelegate_ = CreateMetaKvStore(); + auto fullName = GetBackupPath(); + auto backup = [executors = executors_, queue = std::make_shared>(MAX_TASK_COUNT), fullName]( + const auto &store) -> int32_t { + auto result = queue->PushNoWait([fullName](const auto &store) -> int32_t { + return store->Export(fullName, {}, true); + }); + if (!result) { + return OK; + } + executors->Schedule(std::chrono::hours(RETRY_INTERVAL), GetBackupTask(queue, executors, store)); + return OK; + }; + MetaDataManager::GetInstance().Initialize(metaDelegate_, backup); return metaDelegate_; } +ExecutorPool::Task KvStoreMetaManager::GetBackupTask( + TaskQueue queue, std::shared_ptr executors, const NbDelegate store) +{ + return [queue, executors, store]() { + Backup backupTask; + if (!queue->PopNotWait(backupTask)) { + return; + } + if (backupTask(store) != OK && queue->PushNoWait(backupTask)) { + executors->Schedule(std::chrono::hours(RETRY_INTERVAL), GetBackupTask(queue, executors, store)); + } + }; +} + KvStoreMetaManager::NbDelegate KvStoreMetaManager::CreateMetaKvStore() { DistributedDB::DBStatus dbStatusTmp = DistributedDB::DBStatus::NOT_SUPPORT; DistributedDB::KvStoreNbDelegate::Option option; - option.createIfNecessary = true; - option.isMemoryDb = false; - option.createDirByStoreIdOnly = true; - option.isEncryptedDb = false; - option.isNeedIntegrityCheck = true; - option.isNeedRmCorruptedDb = true; - option.isNeedCompressOnSync = true; - option.compressionRate = COMPRESS_RATE; - option.secOption = { DistributedDB::S1, DistributedDB::ECE }; + InitDBOption(option); DistributedDB::KvStoreNbDelegate *delegate = nullptr; delegateManager_.GetKvStore(Bootstrap::GetInstance().GetMetaDBName(), option, [&delegate, &dbStatusTmp](DistributedDB::DBStatus dbStatus, DistributedDB::KvStoreNbDelegate *nbDelegate) { @@ -296,6 +282,23 @@ KvStoreMetaManager::NbDelegate KvStoreMetaManager::CreateMetaKvStore() dbStatusTmp = dbStatus; }); + if (dbStatusTmp == DistributedDB::DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB) { + ZLOGE("meta data corrupted!"); + option.isNeedRmCorruptedDb = true; + auto fullName = GetBackupPath(); + delegateManager_.GetKvStore(Bootstrap::GetInstance().GetMetaDBName(), option, + [&delegate, &dbStatusTmp, &fullName](DistributedDB::DBStatus dbStatus, + DistributedDB::KvStoreNbDelegate *nbDelegate) { + delegate = nbDelegate; + dbStatusTmp = dbStatus; + if (dbStatusTmp == DistributedDB::DBStatus::OK && delegate != nullptr) { + ZLOGI("start to recover meta data"); + DistributedDB::CipherPassword password; + delegate->Import(fullName, password); + } + }); + } + if (dbStatusTmp != DistributedDB::DBStatus::OK || delegate == nullptr) { ZLOGE("GetKvStore return error status: %{public}d or delegate is nullptr", static_cast(dbStatusTmp)); return nullptr; @@ -321,82 +324,51 @@ KvStoreMetaManager::NbDelegate KvStoreMetaManager::CreateMetaKvStore() return NbDelegate(delegate, release); } -void KvStoreMetaManager::SetSyncer() +void KvStoreMetaManager::InitDBOption(DistributedDB::KvStoreNbDelegate::Option &option) { - auto syncer = [this](const auto &store, int32_t status) { - DeviceMatrix::GetInstance().OnChanged(DeviceMatrix::META_STORE_MASK); - auto size = DmAdapter::GetInstance().GetOnlineSize(); - ZLOGI("syncer status: %{public}d online device:%{public}zu", status, size); - if (size == 0) { - return; - } + option.createIfNecessary = true; + option.isMemoryDb = false; + option.createDirByStoreIdOnly = true; + option.isEncryptedDb = false; + option.isNeedIntegrityCheck = true; + option.isNeedRmCorruptedDb = false; + option.isNeedCompressOnSync = true; + option.compressionRate = COMPRESS_RATE; + option.secOption = { DistributedDB::S1, DistributedDB::ECE }; +} + +void KvStoreMetaManager::SetCloudSyncer() +{ + auto cloudSyncer = [this]() { std::lock_guard lock(mutex_); if (delaySyncTaskId_ == Executor::INVALID_TASK_ID) { - delaySyncTaskId_ = - executors_->Schedule(std::chrono::milliseconds(DELAY_SYNC), SyncTask(store, status)); + delaySyncTaskId_ = executors_->Schedule(std::chrono::milliseconds(DELAY_SYNC), CloudSyncTask()); } else { - delaySyncTaskId_ = - executors_->Reset(delaySyncTaskId_, std::chrono::milliseconds(DELAY_SYNC)); + delaySyncTaskId_ = executors_->Reset(delaySyncTaskId_, std::chrono::milliseconds(DELAY_SYNC)); } }; - MetaDataManager::GetInstance().SetSyncer(syncer); + MetaDataManager::GetInstance().SetCloudSyncer(cloudSyncer); } -std::function KvStoreMetaManager::SyncTask(const NbDelegate &store, int32_t status) +std::function KvStoreMetaManager::CloudSyncTask() { - return [this, store, status]() mutable { + return [this]() { { std::lock_guard lock(mutex_); delaySyncTaskId_ = ExecutorPool::INVALID_TASK_ID; } - std::vector devs; - auto devices = DmAdapter::GetInstance().GetOnlineDevices(); - for (auto const &dev : devices) { - devs.push_back(dev.uuid); - } - if (devs.empty()) { - return; - } - status = store->Sync(devs, DistributedDB::SyncMode::SYNC_MODE_PUSH_PULL, [](auto &results) { - for (auto &[uuid, status] : results) { - if (status != DistributedDB::OK) { - continue; - } - DeviceMatrix::GetInstance().OnExchanged(uuid, DeviceMatrix::META_STORE_MASK); - ZLOGI("uuid is: %{public}s, and status is: %{public}d", Anonymous::Change(uuid).c_str(), status); - } - }); - if (status != DistributedDB::OK) { - ZLOGW("meta data sync error %{public}d.", status); - } - }; -} - -void KvStoreMetaManager::SyncMeta() -{ - std::vector devs; - auto deviceList = DmAdapter::GetInstance().GetRemoteDevices(); - for (auto const &dev : deviceList) { - devs.push_back(dev.uuid); - } - - if (devs.empty()) { - ZLOGW("meta db sync fail, devices is empty."); - return; - } - - auto metaDelegate = GetMetaKvStore(); - if (metaDelegate == nullptr) { - ZLOGW("meta db sync failed."); - return; - } - auto onComplete = [this](const std::map &) { - ZLOGD("meta db sync complete end."); + auto bundleName = Bootstrap::GetInstance().GetProcessLabel(); + auto storeName = Bootstrap::GetInstance().GetMetaDBName(); + DeviceMatrix::GetInstance().OnChanged(DeviceMatrix::META_STORE_MASK); + DistributedData::StoreInfo storeInfo; + storeInfo.bundleName = bundleName; + storeInfo.storeName = storeName; + auto mixMode = static_cast(GeneralStore::MixMode(GeneralStore::CLOUD_TIME_FIRST, + GeneralStore::AUTO_SYNC_MODE)); + auto info = ChangeEvent::EventInfo(mixMode, 0, true, nullptr, nullptr); + auto evt = std::make_unique(std::move(storeInfo), std::move(info)); + EventCenter::GetInstance().PostEvent(std::move(evt)); }; - auto dbStatus = metaDelegate->Sync(devs, DistributedDB::SyncMode::SYNC_MODE_PUSH_PULL, onComplete); - if (dbStatus != DistributedDB::OK) { - ZLOGW("meta db sync failed, error is %{public}d.", dbStatus); - } } void KvStoreMetaManager::SubscribeMetaKvStore() @@ -450,7 +422,6 @@ void KvStoreMetaManager::MetaDeviceChangeListenerImpl::OnDeviceChanged(const App if (info.uuid == DmAdapter::CLOUD_DEVICE_UUID) { return; } - EventCenter::Defer defer; switch (type) { case AppDistributedKv::DeviceChangeType::DEVICE_OFFLINE: DeviceMatrix::GetInstance().Offline(info.uuid); @@ -569,7 +540,6 @@ void KvStoreMetaManager::DBInfoDeviceChangeListenerImpl::OnDeviceChanged(const A ZLOGD("Network change, ignore"); return; } - KvStoreMetaManager::GetInstance().SyncMeta(); KvStoreMetaManager::GetInstance().OnDeviceChange(info.uuid); } diff --git a/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.h b/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.h index a2355edd..492cc1ff 100644 --- a/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.h +++ b/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.h @@ -15,14 +15,17 @@ #ifndef KVSTORE_META_MANAGER_H #define KVSTORE_META_MANAGER_H +#include #include #include "app_device_change_listener.h" #include "executor_pool.h" #include "kv_store_delegate.h" #include "kv_store_delegate_manager.h" +#include "safe_block_queue.h" #include "system_ability.h" #include "types.h" +#include "metadata/meta_data_manager.h" #include "metadata/store_meta_data.h" namespace OHOS { @@ -53,17 +56,20 @@ public: void InitMetaParameter(); void InitMetaListener(); void InitBroadcast(); - void InitDeviceOnline(); void SubscribeMeta(const std::string &keyPrefix, const ChangeObserver &observer); void BindExecutor(std::shared_ptr executors); private: using NbDelegate = std::shared_ptr; using TaskId = ExecutorPool::TaskId; + using Backup = DistributedData::MetaDataManager::Backup; + using TaskQueue = std::shared_ptr>; NbDelegate GetMetaKvStore(); NbDelegate CreateMetaKvStore(); - void SetSyncer(); + void SetCloudSyncer(); + + std::function CloudSyncTask(); KvStoreMetaManager(); @@ -73,8 +79,6 @@ private: void SubscribeMetaKvStore(); - void SyncMeta(); - void NotifyAllAutoSyncDBInfo(); void OnDataChange(CHANGE_FLAG flag, const std::list& changedData); @@ -90,7 +94,10 @@ private: ExecutorPool::Task GetTask(uint32_t retry); - std::function SyncTask(const NbDelegate &store, int32_t status); + void InitDBOption(DistributedDB::KvStoreNbDelegate::Option &option); + + static ExecutorPool::Task GetBackupTask( + TaskQueue queue, std::shared_ptr executors, const NbDelegate store); class KvStoreMetaObserver : public DistributedDB::KvStoreObserver { public: @@ -124,7 +131,8 @@ private: std::mutex mutex_; std::shared_ptr executors_; TaskId delaySyncTaskId_ = ExecutorPool::INVALID_TASK_ID; - static constexpr int32_t META_VERSION = 2; + static constexpr int32_t META_VERSION = 4; + static constexpr int32_t MAX_TASK_COUNT = 1; }; } // namespace DistributedKv } // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/app/src/security/security.cpp b/datamgr_service/services/distributeddataservice/app/src/security/security.cpp index 4980234f..b3cceb71 100644 --- a/datamgr_service/services/distributeddataservice/app/src/security/security.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/security/security.cpp @@ -214,13 +214,13 @@ DBStatus Security::SetFileSecurityOption(const std::string &filePath, const Secu return INVALID_ARGS; } - bool result = OHOS::DistributedFS::ModuleSecurityLabel::SecurityLabel::SetSecurityLabel(filePath, dataLevel); + bool result = OHOS::FileManagement::ModuleSecurityLabel::SecurityLabel::SetSecurityLabel(filePath, dataLevel); if (result) { return OK; } auto error = errno; - std::string current = OHOS::DistributedFS::ModuleSecurityLabel::SecurityLabel::GetSecurityLabel(filePath); + std::string current = OHOS::FileManagement::ModuleSecurityLabel::SecurityLabel::GetSecurityLabel(filePath); ZLOGE("failed! error:%{public}d current:%{public}s label:%{public}s file:%{public}s", error, current.c_str(), dataLevel.c_str(), filePath.c_str()); if (current == dataLevel) { @@ -244,7 +244,7 @@ DBStatus Security::GetFileSecurityOption(const std::string &filePath, SecurityOp return OK; } - std::string value = OHOS::DistributedFS::ModuleSecurityLabel::SecurityLabel::GetSecurityLabel(filePath); + std::string value = OHOS::FileManagement::ModuleSecurityLabel::SecurityLabel::GetSecurityLabel(filePath); if (!IsXattrValueValid(value)) { option = {NOT_SET, ECE}; return OK; diff --git a/datamgr_service/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.cpp b/datamgr_service/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.cpp index 323b62e9..5d5dc15e 100644 --- a/datamgr_service/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.cpp @@ -76,6 +76,13 @@ DistributedDB::DBStatus RouteHeadHandlerImpl::GetHeadDataSize(uint32_t &headSize } bool flag = false; auto peerCap = UpgradeManager::GetInstance().GetCapability(session_.targetDeviceId, flag); + auto devInfo = DmAdapter::GetInstance().GetDeviceInfo(session_.targetDeviceId); + if (devInfo.osType != OH_OS_TYPE && devInfo.deviceType == + static_cast(DistributedHardware::DmDeviceType::DEVICE_TYPE_CAR)) { + ZLOGI("type car set version. devicdId:%{public}s", Anonymous::Change(session_.targetDeviceId).c_str()); + flag = true; + peerCap.version = CapMetaData::CURRENT_VERSION; + } if (!flag) { ZLOGI("get peer cap failed"); return DistributedDB::DB_ERROR; diff --git a/datamgr_service/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.h b/datamgr_service/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.h index 79a045fd..4cc31add 100644 --- a/datamgr_service/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.h +++ b/datamgr_service/services/distributeddataservice/app/src/session_manager/route_head_handler_impl.h @@ -78,6 +78,8 @@ private: std::string deviceId_; Session session_; uint32_t headSize_; + + static constexpr int32_t OH_OS_TYPE = 10; }; } // namespace OHOS::DistributedData #endif // DISTRIBUTEDDATAMGR_ROUTE_HEAD_HANDLER_H diff --git a/datamgr_service/services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp b/datamgr_service/services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp index 584fb918..0627708f 100644 --- a/datamgr_service/services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp @@ -87,58 +87,52 @@ bool UpgradeManager::InitLocalCapability() return status; } +void UpgradeManager::GetIdentifierParams(std::vector &devices, + const std::vector &uuids, int32_t authType) +{ + for (const auto &devId : uuids) { + if (DmAdapter::GetInstance().IsOHOSType(devId)) { + continue; + } + if (DmAdapter::GetInstance().GetAuthType(devId) != authType) { + continue; + } + devices.push_back(devId); + } +} + void UpgradeManager::SetCompatibleIdentifyByType(DistributedDB::KvStoreNbDelegate *storeDelegate, - const KvStoreTuple &tuple, DistributedData::AUTH_GROUP_TYPE groupType) + const KvStoreTuple &tuple) { if (storeDelegate == nullptr) { ZLOGE("null store delegate"); return; } - auto localDevice = DmAdapter::GetInstance().GetLocalDevice().uuid; - auto devices = - AuthDelegate::GetInstance()->GetTrustedDevicesByType(groupType, std::stoi(tuple.userId), tuple.appId); - auto result = std::remove_if(devices.begin(), devices.end(), [&localDevice](const std::string &device) { - if (localDevice == device) { - return true; - } - bool flag = false; - auto capability = DistributedData::UpgradeManager::GetInstance().GetCapability(device, flag); - return !flag || capability.version >= DistributedData::CapMetaData::CURRENT_VERSION; - }); - devices.erase(result, devices.end()); - - bool isSuccess = false; - auto compatibleUser = UpgradeManager::GetIdentifierByType(groupType, isSuccess); - if (!isSuccess) { - ZLOGW("get identifier by type failed"); + auto uuids = DmAdapter::ToUUID(DmAdapter::GetInstance().GetRemoteDevices()); + if (uuids.empty()) { + ZLOGI("no remote devs"); return; } - auto syncIdentifier = - DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(compatibleUser, tuple.appId, tuple.storeId); - ZLOGI("set compatible identifier, store:%{public}s, user:%{public}s, device:%{public}.10s", - Anonymous::Change(tuple.storeId).c_str(), compatibleUser.c_str(), - DistributedData::Serializable::Marshall(devices).c_str()); - storeDelegate->SetEqualIdentifier(syncIdentifier, devices); -} - -std::string UpgradeManager::GetIdentifierByType(int32_t groupType, bool &isSuccess) -{ - isSuccess = true; - if (groupType == PEER_TO_PEER_GROUP) { - return "default"; - } else if (groupType == IDENTICAL_ACCOUNT_GROUP) { - auto accountId = AccountDelegate::GetInstance()->GetCurrentAccountId(); - if (accountId.empty()) { - ZLOGE("failed to get current account id"); - isSuccess = false; - return {}; - } - return accountId; - } else { - ZLOGW("not supported group type:%{public}d", groupType); - isSuccess = false; - return {}; + std::vector sameAccountDevs {}; + std::vector defaultAccountDevs {}; + GetIdentifierParams(sameAccountDevs, uuids, IDENTICAL_ACCOUNT); + GetIdentifierParams(defaultAccountDevs, uuids, NO_ACCOUNT); + if (!sameAccountDevs.empty()) { + auto syncIdentifier = + DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(tuple.userId, tuple.appId, tuple.storeId); + ZLOGI("same account set compatible identifier store:%{public}s, user:%{public}s, device:%{public}.10s", + Anonymous::Change(tuple.storeId).c_str(), Anonymous::Change(tuple.userId).c_str(), + DistributedData::Serializable::Marshall(sameAccountDevs).c_str()); + storeDelegate->SetEqualIdentifier(syncIdentifier, sameAccountDevs); + } + if (!defaultAccountDevs.empty()) { + auto syncIdentifier = + DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(defaultAccountId, tuple.appId, tuple.storeId); + ZLOGI("no account set compatible identifier, store:%{public}s, device:%{public}.10s", + Anonymous::Change(tuple.storeId).c_str(), + DistributedData::Serializable::Marshall(defaultAccountDevs).c_str()); + storeDelegate->SetEqualIdentifier(syncIdentifier, defaultAccountDevs); } } } // namespace OHOS::DistributedData diff --git a/datamgr_service/services/distributeddataservice/app/src/session_manager/upgrade_manager.h b/datamgr_service/services/distributeddataservice/app/src/session_manager/upgrade_manager.h index 795178f4..9fc71a2f 100644 --- a/datamgr_service/services/distributeddataservice/app/src/session_manager/upgrade_manager.h +++ b/datamgr_service/services/distributeddataservice/app/src/session_manager/upgrade_manager.h @@ -32,9 +32,11 @@ public: static UpgradeManager &GetInstance(); void Init(std::shared_ptr executors); CapMetaData GetCapability(const std::string &deviceId, bool &status); - static void SetCompatibleIdentifyByType( - KvStoreNbDelegate *storeDelegate, const KvStoreTuple &tuple, AUTH_GROUP_TYPE groupType); static std::string GetIdentifierByType(int32_t groupType, bool &isSuccess); + static void SetCompatibleIdentifyByType( + KvStoreNbDelegate *storeDelegate, const KvStoreTuple &tuple); + static void GetIdentifierParams(std::vector &devices, + const std::vector &uuids, int32_t authType); private: static constexpr int RETRY_INTERVAL = 500; // milliseconds @@ -42,6 +44,10 @@ private: ExecutorPool::Task GetTask(); ConcurrentMap capabilities_ {}; std::shared_ptr executors_; + + static constexpr int32_t NO_ACCOUNT = 0; + static constexpr int32_t IDENTICAL_ACCOUNT = 1; + static constexpr const char *defaultAccountId = "default"; }; } // namespace OHOS::DistributedData #endif // DISTRIBUTEDDATAMGR_UPGRADE_MANAGER_H diff --git a/datamgr_service/services/distributeddataservice/app/test/BUILD.gn b/datamgr_service/services/distributeddataservice/app/test/BUILD.gn index 66ecc1b2..178d7ecd 100644 --- a/datamgr_service/services/distributeddataservice/app/test/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/app/test/BUILD.gn @@ -20,28 +20,29 @@ config("module_private_config") { visibility = [ ":*" ] include_dirs = [ "${kv_store_path}/frameworks/innerkitsimpl/distributeddatasvc/include", - "//foundation/distributeddatamgr/kv_store/frameworks/common", - "//foundation/distributeddatamgr/kv_store/frameworks/innerkitsimpl/distributeddatafwk/include", - "//foundation/distributeddatamgr/kv_store/frameworks/innerkitsimpl/distributeddatafwk/src", - "//foundation/distributeddatamgr/kv_store/frameworks/innerkitsimpl/kvdb/include", - "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata/include", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/include/permission", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/include/account", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/include", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/include/dfx", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/include/broadcaster", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/include/utils", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/framework/include", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/bootstrap/include", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/config/include", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/crypto/include", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/directory/include", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/permission/include", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/matrix/include", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/app/src/session_manager", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service/kvdb", - "//foundation/distributeddatamgr/distributedfile/interfaces/kits/js/src/mod_securitylabel", - "//foundation/distributedhardware/device_manager/interfaces/inner_kits/native_cpp/include", + "${kv_store_path}/frameworks/common", + "${kv_store_path}/frameworks/innerkitsimpl/distributeddatafwk/include", + "${kv_store_path}/frameworks/innerkitsimpl/distributeddatafwk/src", + "${kv_store_path}/frameworks/innerkitsimpl/kvdb/include", + "${kv_store_path}/interfaces/innerkits/distributeddata/include", + "${data_service_path}/adapter/include/permission", + "${data_service_path}/adapter/include/account", + "${data_service_path}/adapter/include", + "${data_service_path}/adapter/include/dfx", + "${data_service_path}/adapter/include/broadcaster", + "${data_service_path}/adapter/include/utils", + "${data_service_path}/framework/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/directory/include", + "${data_service_path}/service/permission/include", + "${data_service_path}/service/matrix/include", + "${data_service_path}/service/waterversion", + "${data_service_path}/app/src/session_manager", + "${data_service_path}/service/kvdb", + "${device_manager_path}/interfaces/inner_kits/native_cpp/include", "//commonlibrary/c_utils/base/include", "//utils/system/safwk/native/include", "../include", @@ -67,6 +68,7 @@ config("module_private_config") { ohos_unittest("KvStoreDataServiceTest") { module_out_path = module_output_path sources = [ + "${data_service_path}/service/common/xcollie.cpp", "../src/db_info_handle_impl.cpp", "../src/feature_stub_impl.cpp", "../src/kvstore_account_observer.cpp", @@ -90,11 +92,14 @@ ohos_unittest("KvStoreDataServiceTest") { "c_utils:utils", "dataclassification:data_transit_mgr", "device_auth:deviceauth_sdk", + "file_api:securitylabel", + "hicollie:libhicollie", "hilog:libhilog", "hisysevent:libhisysevent", "hitrace:hitrace_meter", "hitrace:libhitracechain", "ipc:ipc_core", + "memmgr:memmgrclient", "safwk:system_ability_fwk", "samgr:samgr_proxy", ] @@ -112,17 +117,17 @@ ohos_unittest("KvStoreDataServiceTest") { ] deps = [ + "${data_service_path}/adapter:distributeddata_adapter", + "${data_service_path}/adapter/broadcaster:distributeddata_broadcaster_static", + "${data_service_path}/adapter/utils:distributeddata_utils_static", + "${data_service_path}/app/src/checker:distributeddata_checker_static", + "${data_service_path}/app/src/flowctrl_manager:distributeddata_flowctrl_static", "${data_service_path}/app/src/installer:distributeddata_installer_static", + "${data_service_path}/framework:distributeddatasvcfwk", + "${data_service_path}/service:distributeddatasvc", + "${kv_store_path}/frameworks/libs/distributeddb:distributeddb", + "${kv_store_path}/interfaces/innerkits/distributeddata:distributeddata_inner", "${kv_store_path}/interfaces/innerkits/distributeddatamgr:distributeddata_mgr", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter:distributeddata_adapter", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/broadcaster:distributeddata_broadcaster_static", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter/utils:distributeddata_utils_static", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/app/src/checker:distributeddata_checker_static", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/app/src/flowctrl_manager:distributeddata_flowctrl_static", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/framework:distributeddatasvcfwk", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service:distributeddatasvc", - "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb:distributeddb", - "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata:distributeddata_inner", "//third_party/googletest:gtest_main", ] part_name = "datamgr_service" @@ -139,6 +144,12 @@ ohos_unittest("SessionManagerTest") { "unittest/session_manager_test.cpp", ] + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + cflags_cc = [ "-DUT_TEST" ] configs = [ ":module_private_config" ] @@ -149,7 +160,9 @@ ohos_unittest("SessionManagerTest") { "c_utils:utils", "dataclassification:data_transit_mgr", "device_auth:deviceauth_sdk", + "file_api:securitylabel", "hilog:libhilog", + "hisysevent:libhisysevent", "ipc:ipc_core", "safwk:system_ability_fwk", "samgr:samgr_proxy", @@ -189,7 +202,9 @@ ohos_unittest("KvStoreFlowCtrlManagerTest") { "c_utils:utils", "dataclassification:data_transit_mgr", "device_auth:deviceauth_sdk", + "file_api:securitylabel", "hilog:libhilog", + "hisysevent:libhisysevent", "ipc:ipc_core", "safwk:system_ability_fwk", "samgr:samgr_proxy", @@ -230,9 +245,16 @@ ohos_unittest("KvStoreDataServiceClearTest") { "${data_service_path}/app/src/session_manager/session_manager.cpp", "${data_service_path}/app/src/session_manager/upgrade_manager.cpp", "${data_service_path}/app/src/task_manager.cpp", + "${data_service_path}/service/common/xcollie.cpp", "unittest/kvstore_data_service_clear_test.cpp", ] + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + configs = [ ":module_private_config" ] external_deps = [ @@ -243,6 +265,8 @@ ohos_unittest("KvStoreDataServiceClearTest") { "c_utils:utils", "dataclassification:data_transit_mgr", "device_auth:deviceauth_sdk", + "file_api:securitylabel", + "hicollie:libhicollie", "hilog:libhilog", "hisysevent:libhisysevent", "hitrace:hitrace_meter", @@ -251,6 +275,7 @@ ohos_unittest("KvStoreDataServiceClearTest") { "kv_store:distributeddata_inner", "kv_store:distributeddata_mgr", "kv_store:distributeddb", + "memmgr:memmgrclient", "safwk:system_ability_fwk", "samgr:samgr_proxy", ] diff --git a/datamgr_service/services/distributeddataservice/app/test/fuzztest/dataservicestub_fuzzer/BUILD.gn b/datamgr_service/services/distributeddataservice/app/test/fuzztest/dataservicestub_fuzzer/BUILD.gn index 5e6a9098..42946281 100644 --- a/datamgr_service/services/distributeddataservice/app/test/fuzztest/dataservicestub_fuzzer/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/app/test/fuzztest/dataservicestub_fuzzer/BUILD.gn @@ -38,8 +38,10 @@ ohos_fuzztest("DataServiceStubFuzzTest") { "${data_service_path}/app/src/installer", "${data_service_path}/framework/include", "${data_service_path}/service/backup/include", + "${data_service_path}/service/common", "${data_service_path}/service/dumper/include", "${data_service_path}/service/kvdb", + "${data_service_path}/service/waterversion", "${data_service_path}/adapter/include/account", "${data_service_path}/adapter/include/permission", "${data_service_path}/adapter/include/installer", @@ -48,7 +50,6 @@ ohos_fuzztest("DataServiceStubFuzzTest") { "${data_service_path}/adapter/include/dfx", "${data_service_path}/adapter/include", "${device_manager_path}/interfaces/inner_kits/native_cpp/include", - "${distributedfilejs_path}/interfaces/kits/js/src/mod_securitylabel", "//third_party/json/single_include", ] @@ -76,6 +77,7 @@ ohos_fuzztest("DataServiceStubFuzzTest") { "${data_service_path}/app/src/session_manager/session_manager.cpp", "${data_service_path}/app/src/session_manager/upgrade_manager.cpp", "${data_service_path}/app/src/task_manager.cpp", + "${data_service_path}/service/common/xcollie.cpp", "dataservicestub_fuzzer.cpp", ] @@ -99,6 +101,8 @@ ohos_fuzztest("DataServiceStubFuzzTest") { "bundle_framework:appexecfwk_core", "c_utils:utils", "dataclassification:data_transit_mgr", + "file_api:securitylabel", + "hicollie:libhicollie", "hilog:libhilog", "hisysevent:libhisysevent", "hitrace:hitrace_meter", @@ -106,6 +110,7 @@ ohos_fuzztest("DataServiceStubFuzzTest") { "ipc:ipc_core", "kv_store:distributeddata_inner", "kv_store:distributeddata_mgr", + "memmgr:memmgrclient", "safwk:system_ability_fwk", "samgr:samgr_proxy", ] diff --git a/datamgr_service/services/distributeddataservice/framework/BUILD.gn b/datamgr_service/services/distributeddataservice/framework/BUILD.gn index ae6f9413..f069d43e 100644 --- a/datamgr_service/services/distributeddataservice/framework/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/framework/BUILD.gn @@ -21,8 +21,6 @@ config("module_config") { visibility = [ ":*" ] include_dirs = [ "include", - "//third_party/json/single_include", - "//third_party/openssl/include/", "${data_service_path}/adapter/include", "${kv_store_path}/interfaces/innerkits/distributeddata/include", "${kv_store_common_path}", @@ -35,7 +33,6 @@ config("module_public_config") { visibility = [ ":*" ] include_dirs = [ "include", - "//third_party/json/single_include", "${kv_store_common_path}", ] } @@ -43,12 +40,15 @@ config("module_public_config") { ohos_shared_library("distributeddatasvcfwk") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false } sources = [ "backuprule/backup_rule_manager.cpp", + "changeevent/remote_change_event.cpp", "checker/checker_manager.cpp", "cloud/asset_loader.cpp", "cloud/cloud_config_manager.cpp", @@ -72,6 +72,7 @@ ohos_shared_library("distributeddatasvcfwk") { "feature/feature_system.cpp", "feature/static_acts.cpp", "metadata/appid_meta_data.cpp", + "metadata/auto_launch_meta_data.cpp", "metadata/capability_meta_data.cpp", "metadata/capability_range.cpp", "metadata/corrupted_meta_data.cpp", @@ -104,12 +105,12 @@ ohos_shared_library("distributeddatasvcfwk") { public_configs = [ ":module_public_config" ] - deps = [ "//third_party/openssl:libcrypto_shared" ] - external_deps = [ "access_token:libaccesstoken_sdk", "c_utils:utils", "hilog:libhilog", + "json:nlohmann_json_static", + "openssl:libcrypto_shared", ] subsystem_name = "distributeddatamgr" diff --git a/datamgr_service/services/distributeddataservice/framework/CMakeLists.txt b/datamgr_service/services/distributeddataservice/framework/CMakeLists.txt index 5d890d7c..d72ea16e 100644 --- a/datamgr_service/services/distributeddataservice/framework/CMakeLists.txt +++ b/datamgr_service/services/distributeddataservice/framework/CMakeLists.txt @@ -11,6 +11,7 @@ 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") aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/backuprule svcFwkSrc) +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/changeevent svcFwkSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/checker svcFwkSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/dump svcFwkSrc) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/metadata svcFwkSrc) diff --git a/datamgr_service/services/distributeddataservice/framework/changeevent/remote_change_event.cpp b/datamgr_service/services/distributeddataservice/framework/changeevent/remote_change_event.cpp new file mode 100644 index 00000000..5f64f680 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/changeevent/remote_change_event.cpp @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "changeevent/remote_change_event.h" + +namespace OHOS::DistributedData { +RemoteChangeEvent::RemoteChangeEvent(int32_t evtId, DataInfo&& info) + : Event(evtId), info_(std::move(info)) +{ +} + +const RemoteChangeEvent::DataInfo& RemoteChangeEvent::GetDataInfo() const +{ + return info_; +} +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/cloud/cloud_config_manager.cpp b/datamgr_service/services/distributeddataservice/framework/cloud/cloud_config_manager.cpp index e170b071..458cf046 100644 --- a/datamgr_service/services/distributeddataservice/framework/cloud/cloud_config_manager.cpp +++ b/datamgr_service/services/distributeddataservice/framework/cloud/cloud_config_manager.cpp @@ -26,7 +26,7 @@ CloudConfigManager &CloudConfigManager::GetInstance() void CloudConfigManager::Initialize(const std::vector &mapper) { - std::unique_lock lock(mutex_); + // Only called once during initialization, so it can be unlocked for (const auto &info : mapper) { toLocalMapper_.insert_or_assign(info.cloudBundle, info.localBundle); toCloudMapper_.insert_or_assign(info.localBundle, info.cloudBundle); @@ -35,14 +35,12 @@ void CloudConfigManager::Initialize(const std::vector &mapper) std::string CloudConfigManager::ToLocal(const std::string &bundleName) { - std::shared_lock lock(mutex_); auto it = toLocalMapper_.find(bundleName); return it == toLocalMapper_.end() ? bundleName : it->second; } std::string CloudConfigManager::ToCloud(const std::string &bundleName) { - std::shared_lock lock(mutex_); auto it = toCloudMapper_.find(bundleName); return it == toCloudMapper_.end() ? bundleName : it->second; } diff --git a/datamgr_service/services/distributeddataservice/framework/cloud/cloud_info.cpp b/datamgr_service/services/distributeddataservice/framework/cloud/cloud_info.cpp index f6f01847..d723adfe 100644 --- a/datamgr_service/services/distributeddataservice/framework/cloud/cloud_info.cpp +++ b/datamgr_service/services/distributeddataservice/framework/cloud/cloud_info.cpp @@ -25,6 +25,8 @@ bool CloudInfo::Marshal(Serializable::json &node) const SetValue(node[GET_NAME(remainSpace)], remainSpace); SetValue(node[GET_NAME(enableCloud)], enableCloud); SetValue(node[GET_NAME(apps)], apps); + SetValue(node[GET_NAME(maxNumber)], maxNumber); + SetValue(node[GET_NAME(maxSize)], maxSize); return true; } @@ -36,6 +38,12 @@ bool CloudInfo::Unmarshal(const Serializable::json &node) GetValue(node, GET_NAME(remainSpace), remainSpace); GetValue(node, GET_NAME(enableCloud), enableCloud); GetValue(node, GET_NAME(apps), apps); + if (!GetValue(node, GET_NAME(maxNumber), maxNumber) || maxNumber == 0) { + maxNumber = DEFAULT_BATCH_NUMBER; + } + if (!GetValue(node, GET_NAME(maxSize), maxSize) || maxSize == 0) { + maxSize = DEFAULT_BATCH_SIZE; + } return true; } @@ -103,7 +111,7 @@ bool CloudInfo::IsValid() const return !id.empty(); } -bool CloudInfo::Exist(const std::string &bundleName, int32_t instanceId) +bool CloudInfo::Exist(const std::string &bundleName, int32_t instanceId) const { if (bundleName.empty()) { return false; @@ -112,7 +120,7 @@ bool CloudInfo::Exist(const std::string &bundleName, int32_t instanceId) return it != apps.end() && it->second.bundleName == bundleName && it->second.instanceId == instanceId; } -bool CloudInfo::IsOn(const std::string &bundleName, int32_t instanceId) +bool CloudInfo::IsOn(const std::string &bundleName, int32_t instanceId) const { if (bundleName.empty()) { return false; diff --git a/datamgr_service/services/distributeddataservice/framework/cloud/cloud_server.cpp b/datamgr_service/services/distributeddataservice/framework/cloud/cloud_server.cpp index 30ee46a2..05829100 100644 --- a/datamgr_service/services/distributeddataservice/framework/cloud/cloud_server.cpp +++ b/datamgr_service/services/distributeddataservice/framework/cloud/cloud_server.cpp @@ -30,14 +30,14 @@ bool CloudServer::RegisterCloudInstance(CloudServer *instance) return true; } -CloudInfo CloudServer::GetServerInfo(int32_t userId) +CloudInfo CloudServer::GetServerInfo(int32_t userId, bool needSpaceInfo) { return CloudInfo(); } -SchemaMeta CloudServer::GetAppSchema(int32_t userId, const std::string &bundleName) +std::pair CloudServer::GetAppSchema(int32_t userId, const std::string &bundleName) { - return SchemaMeta(); + return { 0, SchemaMeta() }; } int32_t CloudServer::Subscribe(int32_t userId, const std::map> &dbs) @@ -88,4 +88,9 @@ void CloudServer::ReleaseUserInfo(int32_t userId) void CloudServer::Bind(std::shared_ptr executor) { } + +bool CloudServer::IsSupportCloud(int32_t userId) +{ + return false; +} } // namespace OHOS::DistributedData \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/cloud/schema_meta.cpp b/datamgr_service/services/distributeddataservice/framework/cloud/schema_meta.cpp index f7dd8ac0..f22c28ae 100644 --- a/datamgr_service/services/distributeddataservice/framework/cloud/schema_meta.cpp +++ b/datamgr_service/services/distributeddataservice/framework/cloud/schema_meta.cpp @@ -17,6 +17,7 @@ namespace OHOS::DistributedData { bool SchemaMeta::Marshal(Serializable::json &node) const { + SetValue(node[GET_NAME(metaVersion)], metaVersion); SetValue(node[GET_NAME(version)], version); SetValue(node[GET_NAME(bundleName)], bundleName); SetValue(node[GET_NAME(databases)], databases); @@ -25,6 +26,9 @@ bool SchemaMeta::Marshal(Serializable::json &node) const bool SchemaMeta::Unmarshal(const Serializable::json &node) { + if (!GetValue(node, GET_NAME(metaVersion), metaVersion)) { + metaVersion = 0; + } GetValue(node, GET_NAME(version), version); GetValue(node, GET_NAME(bundleName), bundleName); GetValue(node, GET_NAME(databases), databases); diff --git a/datamgr_service/services/distributeddataservice/framework/eventcenter/event_center.cpp b/datamgr_service/services/distributeddataservice/framework/eventcenter/event_center.cpp index 5f2a23cd..6d96707c 100644 --- a/datamgr_service/services/distributeddataservice/framework/eventcenter/event_center.cpp +++ b/datamgr_service/services/distributeddataservice/framework/eventcenter/event_center.cpp @@ -151,5 +151,4 @@ void EventCenter::AsyncQueue::AddHandler(int32_t evtId, std::function +#include + +#include "eventcenter/event.h" + +namespace OHOS::DistributedData { +class API_EXPORT RemoteChangeEvent : public Event { +public: + enum : int32_t { + RDB_META_SAVE = EVT_CHANGE, + DATA_CHANGE, + }; + + struct DataInfo { + std::string userId; + std::string storeId; + std::string deviceId; + std::string bundleName; + std::vector tables; + }; + + RemoteChangeEvent(int32_t evtId, DataInfo&& info); + + ~RemoteChangeEvent() = default; + + const DataInfo& GetDataInfo() const; + +private: + DataInfo info_; +}; +} // namespace OHOS::DistributedData +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_REMOTE_CHANGE_EVENT_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_config_manager.h b/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_config_manager.h index 94f21f46..d68513da 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_config_manager.h +++ b/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_config_manager.h @@ -35,7 +35,6 @@ public: private: std::map toLocalMapper_; std::map toCloudMapper_; - std::shared_mutex mutex_; }; } // namespace DistributedData diff --git a/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_event.h b/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_event.h index 65f3fa0d..0ac070ad 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_event.h +++ b/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_event.h @@ -32,6 +32,7 @@ public: CLOUD_SHARE, MAKE_QUERY, CLOUD_SYNC_FINISHED, + DATA_SYNC, CLOUD_BUTT }; @@ -43,4 +44,4 @@ private: StoreInfo storeInfo_; }; } // namespace OHOS::DistributedData -#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_CLOUD_EVENT_H +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_CLOUD_EVENT_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_info.h b/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_info.h index 14cdf141..35fa2cd5 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_info.h +++ b/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_info.h @@ -20,6 +20,8 @@ namespace OHOS::DistributedData { class API_EXPORT CloudInfo final : public Serializable { public: + static constexpr int32_t DEFAULT_BATCH_NUMBER = 30; + static constexpr int32_t DEFAULT_BATCH_SIZE = 1024 * 512 * 3; // 1.5M struct API_EXPORT AppInfo final : public Serializable { std::string bundleName = ""; std::string appId = ""; @@ -34,6 +36,8 @@ public: std::string id = ""; uint64_t totalSpace = 0; uint64_t remainSpace = 0; + int32_t maxNumber = 0; + int32_t maxSize = 0; bool enableCloud = false; std::map apps; @@ -44,8 +48,8 @@ public: static std::string GetSchemaKey(int32_t user, const std::string &bundleName, int32_t instanceId = 0); static std::string GetSchemaKey(const StoreMetaData &meta); bool IsValid() const; - bool Exist(const std::string &bundleName, int32_t instanceId = 0); - bool IsOn(const std::string &bundleName, int32_t instanceId = 0); + bool Exist(const std::string &bundleName, int32_t instanceId = 0) const; + bool IsOn(const std::string &bundleName, int32_t instanceId = 0) const; bool IsAllSwitchOff() const; static std::string GetPrefix(const std::initializer_list &field); diff --git a/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_server.h b/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_server.h index 460d43dd..daaecf8d 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_server.h +++ b/datamgr_service/services/distributeddataservice/framework/include/cloud/cloud_server.h @@ -29,8 +29,8 @@ public: API_EXPORT static CloudServer *GetInstance(); API_EXPORT static bool RegisterCloudInstance(CloudServer *instance); - virtual CloudInfo GetServerInfo(int32_t userId); - virtual SchemaMeta GetAppSchema(int32_t userId, const std::string &bundleName); + virtual CloudInfo GetServerInfo(int32_t userId, bool needSpaceInfo = true); + virtual std::pair GetAppSchema(int32_t userId, const std::string &bundleName); virtual int32_t Subscribe(int32_t userId, const std::map> &dbs); virtual int32_t Unsubscribe(int32_t userId, const std::map> &dbs); virtual std::shared_ptr ConnectAssetLoader( @@ -42,9 +42,10 @@ public: virtual void Clean(int32_t userId); virtual void ReleaseUserInfo(int32_t userId); virtual void Bind(std::shared_ptr executor); + virtual bool IsSupportCloud(int32_t userId); private: static CloudServer *instance_; }; } // namespace OHOS::DistributedData -#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_CLOUD_SERVER_H +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_CLOUD_SERVER_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/include/cloud/schema_meta.h b/datamgr_service/services/distributeddataservice/framework/include/cloud/schema_meta.h index e65449a2..7e5fd640 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/cloud/schema_meta.h +++ b/datamgr_service/services/distributeddataservice/framework/include/cloud/schema_meta.h @@ -62,6 +62,18 @@ public: static constexpr const char *CLOUD_PRIVILEGE = "cloud_privilege"; static constexpr const char *SHARING_RESOURCE = "#_sharing_resource"; static constexpr const char *HASH_KEY = "#_hash_key"; + + static constexpr uint32_t CURRENT_VERSION = 0x10000; + static inline uint32_t GetLowVersion(uint32_t metaVersion = CURRENT_VERSION) + { + return metaVersion & 0xFFFF; + } + + static inline uint32_t GetHighVersion(uint32_t metaVersion = CURRENT_VERSION) + { + return metaVersion & ~0xFFFF; + } + uint32_t metaVersion = CURRENT_VERSION; int32_t version = 0; std::string bundleName; std::vector databases; 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 4b2a6292..e7a91463 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/cloud/sharing_center.h +++ b/datamgr_service/services/distributeddataservice/framework/include/cloud/sharing_center.h @@ -16,6 +16,7 @@ #ifndef OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_SHARING_CENTER_H #define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_CLOUD_SHARING_CENTER_H +#include #include #include #include @@ -59,7 +60,10 @@ public: using Participants = std::vector; using Results = std::tuple>>; using QueryResults = std::tuple; - + enum CloudShareModule { + CLOUD_SHARE_MODULE_ID = 12, + }; + static const ErrCode SHARING_ERR_OFFSET = ErrCodeOffset(SUBSYS_DISTRIBUTEDDATAMNG, CLOUD_SHARE_MODULE_ID); enum SharingCode : int32_t { SUCCESS = 0, REPEATED_REQUEST, @@ -75,6 +79,7 @@ public: INVALID_INVITATION, RATE_LIMIT, IPC_ERROR, + NOT_SUPPORT, CUSTOM_ERROR = 1000, }; diff --git a/datamgr_service/services/distributeddataservice/framework/include/commonevent/data_change_event.h b/datamgr_service/services/distributeddataservice/framework/include/commonevent/data_change_event.h index 0c2fc718..be3970cd 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/commonevent/data_change_event.h +++ b/datamgr_service/services/distributeddataservice/framework/include/commonevent/data_change_event.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_COMMON_EVENT_H -#define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_COMMON_EVENT_H +#ifndef OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_COMMON_EVENT_DATA_CHANGE_EVENT_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_COMMON_EVENT_DATA_CHANGE_EVENT_H #include "cloud/cloud_event.h" #include "visibility.h" @@ -44,4 +44,4 @@ private: EventInfo info_; }; } // OHOS::DistributedData -#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_COMMON_EVENT_H \ No newline at end of file +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_COMMON_EVENT_DATA_CHANGE_EVENT_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/include/commonevent/data_sync_event.h b/datamgr_service/services/distributeddataservice/framework/include/commonevent/data_sync_event.h new file mode 100644 index 00000000..51e83a7d --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/include/commonevent/data_sync_event.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_COMMON_EVENT_DATA_SYNC_EVENT_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_COMMON_EVENT_DATA_SYNC_EVENT_H + +#include "cloud/cloud_event.h" +#include "visibility.h" +namespace OHOS::DistributedData { +class API_EXPORT DataSyncEvent : public CloudEvent { +public: + enum DataSyncStatus : int32_t { + START, + FINISH, + }; + + DataSyncEvent(StoreInfo storeInfo, uint32_t syncMode, int32_t status) + : CloudEvent(DATA_SYNC, std::move(storeInfo)), syncMode_(syncMode), status_(std::move(status)) + { + } + + ~DataSyncEvent() override = default; + + uint32_t GetSyncMode() const + { + return syncMode_; + } + + uint32_t GetSyncStatus() const + { + return status_; + } + +private: + uint32_t syncMode_; + int32_t status_; +}; +} // OHOS::DistributedData +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_COMMON_EVENT_DATA_SYNC_EVENT_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/include/directory/directory_manager.h b/datamgr_service/services/distributeddataservice/framework/include/directory/directory_manager.h index bdbf46d1..737b7f5f 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/directory/directory_manager.h +++ b/datamgr_service/services/distributeddataservice/framework/include/directory/directory_manager.h @@ -39,6 +39,7 @@ public: API_EXPORT std::string GetMetaBackupPath(uint32_t version = INVALID_VERSION); API_EXPORT std::vector GetVersions(); API_EXPORT void Initialize(const std::vector &strategies); + API_EXPORT bool CreateDirectory(const std::string &path) const; private: using Action = std::string (DirectoryManager::*)(const StoreMetaData &) const; @@ -62,7 +63,6 @@ private: std::vector Split(const std::string &source, const std::string &pattern) const; int32_t GetVersionIndex(uint32_t version) const; std::string GenPath(const StoreMetaData &metaData, uint32_t version, const std::string &exPath = "") const; - bool CreateDirectory(const std::string &path) const; const std::map actions_; std::vector strategies_; }; diff --git a/datamgr_service/services/distributeddataservice/framework/include/eventcenter/event.h b/datamgr_service/services/distributeddataservice/framework/include/eventcenter/event.h index 27bf9df2..618f6fcb 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/eventcenter/event.h +++ b/datamgr_service/services/distributeddataservice/framework/include/eventcenter/event.h @@ -28,7 +28,9 @@ public: EVT_INITED, EVT_UPDATE, EVT_CUSTOM = 0x1000, - EVT_CLOUD = 0x2000 + EVT_CLOUD = 0x2000, + EVT_BIND = 0X3000, + EVT_CHANGE = 0X4000, }; API_EXPORT Event(int32_t evtId); API_EXPORT Event(Event &&) noexcept = delete; diff --git a/datamgr_service/services/distributeddataservice/framework/include/feature/feature_system.h b/datamgr_service/services/distributeddataservice/framework/include/feature/feature_system.h index a56aa0d3..ecadb34d 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/feature/feature_system.h +++ b/datamgr_service/services/distributeddataservice/framework/include/feature/feature_system.h @@ -56,6 +56,7 @@ public: virtual int32_t Offline(const std::string &device); virtual int32_t OnReady(const std::string &device); virtual int32_t OnSessionReady(const std::string &device); + virtual int32_t OnScreenUnlocked(int32_t user); }; using Creator = std::function()>; static FeatureSystem &GetInstance(); diff --git a/datamgr_service/services/distributeddataservice/framework/include/metadata/auto_launch_meta_data.h b/datamgr_service/services/distributeddataservice/framework/include/metadata/auto_launch_meta_data.h new file mode 100644 index 00000000..de1da05c --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/include/metadata/auto_launch_meta_data.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_METADATA_AUTO_LAUNCH_META_DATA_H +#define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_METADATA_AUTO_LAUNCH_META_DATA_H +#include + +#include "serializable/serializable.h" +namespace OHOS::DistributedData { +struct API_EXPORT AutoLaunchMetaData final : public Serializable { + std::map> datas; + + API_EXPORT AutoLaunchMetaData(); + API_EXPORT ~AutoLaunchMetaData() = default; + API_EXPORT bool Marshal(json &node) const override; + API_EXPORT bool Unmarshal(const json &node) override; + API_EXPORT static std::string GetPrefix(const std::initializer_list &fields); +private: + static constexpr const char *PREFIX = "AutoLaunchMetaData"; +}; +} + +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_METADATA_AUTO_LAUNCH_META_DATA_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/include/metadata/matrix_meta_data.h b/datamgr_service/services/distributeddataservice/framework/include/metadata/matrix_meta_data.h index f1564621..ac6ee82a 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/metadata/matrix_meta_data.h +++ b/datamgr_service/services/distributeddataservice/framework/include/metadata/matrix_meta_data.h @@ -38,7 +38,7 @@ public: bool Marshal(json &node) const override; bool Unmarshal(const json &node) override; std::string GetKey() const; - API_EXPORT std::string GetConsistentKey() const; + std::string GetConsistentKey() const; API_EXPORT bool operator==(const MatrixMetaData &meta) const; API_EXPORT bool operator!=(const MatrixMetaData &meta) const; API_EXPORT static std::string GetPrefix(const std::initializer_list &fields); diff --git a/datamgr_service/services/distributeddataservice/framework/include/metadata/meta_data_manager.h b/datamgr_service/services/distributeddataservice/framework/include/metadata/meta_data_manager.h index b1588b70..4c5fb869 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/metadata/meta_data_manager.h +++ b/datamgr_service/services/distributeddataservice/framework/include/metadata/meta_data_manager.h @@ -47,12 +47,14 @@ public: using MetaStore = DistributedDB::KvStoreNbDelegate; using Observer = std::function; using Syncer = std::function &, int32_t)>; + using CloudSyncer = std::function; using Backup = std::function &)>; using Bytes = std::vector; using OnComplete = std::function &)>; API_EXPORT static MetaDataManager &GetInstance(); API_EXPORT void Initialize(std::shared_ptr metaStore, const Backup &backup); API_EXPORT void SetSyncer(const Syncer &syncer); + API_EXPORT void SetCloudSyncer(const CloudSyncer &cloudSyncer); API_EXPORT bool SaveMeta(const std::string &key, const Serializable &value, bool isLocal = false); API_EXPORT bool LoadMeta(const std::string &key, Serializable &value, bool isLocal = false); template @@ -90,6 +92,7 @@ private: ConcurrentMap> metaObservers_; Backup backup_; Syncer syncer_; + CloudSyncer cloudSyncer_; }; } // namespace OHOS::DistributedData -#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_METADATA_META_DATA_MANAGER_H +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_METADATA_META_DATA_MANAGER_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/include/metadata/store_meta_data.h b/datamgr_service/services/distributeddataservice/framework/include/metadata/store_meta_data.h index c837fadd..61bf6fd0 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/metadata/store_meta_data.h +++ b/datamgr_service/services/distributeddataservice/framework/include/metadata/store_meta_data.h @@ -23,11 +23,12 @@ namespace OHOS::DistributedData { struct API_EXPORT StoreMetaData final : public Serializable { // record meta version for compatible, should update when modify store meta data structure. - static constexpr uint32_t CURRENT_VERSION = 0x03000005; + static constexpr uint32_t CURRENT_VERSION = 0x03000006; // UID -> uid, deviceAccountId -> userId, userId -> user static constexpr uint32_t FIELD_CHANGED_TAG = 0x03000003; static constexpr uint32_t UUID_CHANGED_TAG = 0x03000004; static constexpr const char *KEY_PREFIX = "KvStoreMetaData"; + static constexpr const char *ROOT_USER = "0"; uint32_t version = CURRENT_VERSION; bool isAutoSync = false; bool isBackup = false; @@ -36,6 +37,8 @@ struct API_EXPORT StoreMetaData final : public Serializable { bool isManualClean = false; bool isSearchable = false; bool isNeedCompress = false; + bool enableCloud = false; + bool cloudAutoSync = false; int32_t dataType = -1; int32_t storeType = -1; int32_t securityLevel = 0; @@ -78,6 +81,7 @@ struct API_EXPORT StoreMetaData final : public Serializable { API_EXPORT std::string GetSecretKey() const; API_EXPORT std::string GetStrategyKey() const; API_EXPORT std::string GetBackupSecretKey() const; + API_EXPORT std::string GetAutoLaunchKey() const; API_EXPORT std::string GetStoreAlias() const; API_EXPORT StoreInfo GetStoreInfo() const; API_EXPORT static std::string GetKey(const std::initializer_list &fields); diff --git a/datamgr_service/services/distributeddataservice/framework/include/metadata/version_meta_data.h b/datamgr_service/services/distributeddataservice/framework/include/metadata/version_meta_data.h index 07080e37..11aead04 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/metadata/version_meta_data.h +++ b/datamgr_service/services/distributeddataservice/framework/include/metadata/version_meta_data.h @@ -20,7 +20,7 @@ namespace OHOS::DistributedData { class API_EXPORT VersionMetaData final : public Serializable { public: - static constexpr int32_t CURRENT_VERSION = 2; + static constexpr int32_t CURRENT_VERSION = 3; static constexpr int32_t INVALID_VERSION = -1; int32_t version = INVALID_VERSION; diff --git a/datamgr_service/services/distributeddataservice/framework/include/serializable/serializable.h b/datamgr_service/services/distributeddataservice/framework/include/serializable/serializable.h index db35754e..a0b6ad5a 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/serializable/serializable.h +++ b/datamgr_service/services/distributeddataservice/framework/include/serializable/serializable.h @@ -54,21 +54,21 @@ public: virtual bool Marshal(json &node) const = 0; virtual bool Unmarshal(const json &node) = 0; API_EXPORT static bool GetValue(const json &node, const std::string &name, std::string &value); - API_EXPORT static bool GetValue(const json &node, const std::string &name, uint16_t &value); - API_EXPORT static bool GetValue(const json &node, const std::string &name, int32_t &value); API_EXPORT static bool GetValue(const json &node, const std::string &name, uint32_t &value); + API_EXPORT static bool GetValue(const json &node, const std::string &name, int32_t &value); API_EXPORT static bool GetValue(const json &node, const std::string &name, int64_t &value); API_EXPORT static bool GetValue(const json &node, const std::string &name, uint64_t &value); + API_EXPORT static bool GetValue(const json &node, const std::string &name, uint16_t &value); API_EXPORT static bool GetValue(const json &node, const std::string &name, bool &value); API_EXPORT static bool GetValue(const json &node, const std::string &name, std::vector &value); API_EXPORT static bool GetValue(const json &node, const std::string &name, Serializable &value); API_EXPORT static bool SetValue(json &node, const std::string &value); - API_EXPORT static bool SetValue(json &node, const uint16_t &value); - API_EXPORT static bool SetValue(json &node, const int32_t &value); API_EXPORT static bool SetValue(json &node, const uint32_t &value); + API_EXPORT static bool SetValue(json &node, const int32_t &value); API_EXPORT static bool SetValue(json &node, const int64_t &value); - API_EXPORT static bool SetValue(json &node, const uint64_t &value); API_EXPORT static bool SetValue(json &node, const double &value); + API_EXPORT static bool SetValue(json &node, const uint64_t &value); + API_EXPORT static bool SetValue(json &node, const uint16_t &value); // Use bool & to forbid the const T * auto convert to bool, const bool will convert to const uint32_t &value; template API_EXPORT static std::enable_if_t, bool> SetValue(json &node, const T &value) diff --git a/datamgr_service/services/distributeddataservice/framework/include/snapshot/bind_event.h b/datamgr_service/services/distributeddataservice/framework/include/snapshot/bind_event.h index a8514fa0..facb65e9 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/snapshot/bind_event.h +++ b/datamgr_service/services/distributeddataservice/framework/include/snapshot/bind_event.h @@ -25,7 +25,7 @@ namespace OHOS::DistributedData { class API_EXPORT BindEvent : public Event { public: enum : int32_t { - BIND_SNAPSHOT, + BIND_SNAPSHOT = EVT_BIND, COMPENSATE_SYNC, RECOVER_SYNC, }; diff --git a/datamgr_service/services/distributeddataservice/framework/include/store/auto_cache.h b/datamgr_service/services/distributeddataservice/framework/include/store/auto_cache.h index ce1a9f71..9fcf14a4 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/store/auto_cache.h +++ b/datamgr_service/services/distributeddataservice/framework/include/store/auto_cache.h @@ -68,7 +68,7 @@ private: void GarbageCollect(bool isForce); void StartTimer(); struct Delegate : public GeneralWatcher { - Delegate(GeneralStore *delegate, const Watchers &watchers, int32_t user); + Delegate(GeneralStore *delegate, const Watchers &watchers, int32_t user, const StoreMetaData &meta); ~Delegate(); operator Store(); bool operator<(const Time &time) const; @@ -77,12 +77,14 @@ private: void SetObservers(const Watchers &watchers); int32_t OnChange(const Origin &origin, const PRIFields &primaryFields, ChangeInfo &&values) override; int32_t OnChange(const Origin &origin, const Fields &fields, ChangeData &&datas) override; + void PostDataChange(const StoreMetaData &meta, const std::vector &tables); private: mutable Time time_; GeneralStore *store_ = nullptr; Watchers watchers_; int32_t user_; + StoreMetaData meta_; std::shared_mutex mutex_; }; 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 4cd7a24f..17f9db29 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/store/general_store.h +++ b/datamgr_service/services/distributeddataservice/framework/include/store/general_store.h @@ -15,6 +15,7 @@ #ifndef OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_GENERAL_STORE_H #define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_GENERAL_STORE_H +#include #include #include #include @@ -88,9 +89,26 @@ public: std::shared_ptr db_; std::shared_ptr loader_; }; + + struct CloudConfig { + int32_t maxNumber = 30; + int32_t maxSize = 1024 * 512 * 3; // 1.5M + int32_t maxRetryConflictTimes = 3; // default max retry 3 times when version conflict + }; + + struct StoreConfig { + bool enableCloud_ = false; + }; + + enum DistributedDb { + DB_MODE_ID = 1, + }; + static const int32_t DB_ERR_OFFSET = ErrCodeOffset(SUBSYS_DISTRIBUTEDDATAMNG, DB_MODE_ID); + virtual ~GeneralStore() = default; - virtual int32_t Bind(Database &database, const std::map &bindInfos) = 0; + virtual int32_t Bind(Database &database, const std::map &bindInfos, + const CloudConfig &config) = 0; virtual bool IsBound() = 0; @@ -140,6 +158,10 @@ public: virtual int32_t MergeMigratedData(const std::string &tableName, VBuckets &&values) = 0; virtual std::vector GetWaterVersion(const std::string &deviceId) = 0; + + virtual void SetEqualIdentifier(const std::string &appId, const std::string &storeId) {}; + + virtual void SetConfig(const StoreConfig &storeConfig) {}; }; } // namespace OHOS::DistributedData #endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_STORE_GENERAL_STORE_H diff --git a/datamgr_service/services/distributeddataservice/framework/include/store/general_value.h b/datamgr_service/services/distributeddataservice/framework/include/store/general_value.h index 6366b73d..aed711a1 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/store/general_value.h +++ b/datamgr_service/services/distributeddataservice/framework/include/store/general_value.h @@ -46,6 +46,7 @@ struct GenTableDetail { struct GenProgressDetail { int32_t progress; int32_t code; + int32_t dbCode; std::map details; }; diff --git a/datamgr_service/services/distributeddataservice/framework/include/utils/anonymous.h b/datamgr_service/services/distributeddataservice/framework/include/utils/anonymous.h index bf34e8c8..b7ff9cce 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/utils/anonymous.h +++ b/datamgr_service/services/distributeddataservice/framework/include/utils/anonymous.h @@ -21,7 +21,7 @@ namespace OHOS { namespace DistributedData { class Anonymous { public: - API_EXPORT static std::string Change(const std::string &name); + API_EXPORT static std::string Change(const std::string &name, bool end = false); }; } // namespace DistributedData } // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/framework/metadata/auto_launch_meta_data.cpp b/datamgr_service/services/distributeddataservice/framework/metadata/auto_launch_meta_data.cpp new file mode 100644 index 00000000..3224368c --- /dev/null +++ b/datamgr_service/services/distributeddataservice/framework/metadata/auto_launch_meta_data.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "metadata/auto_launch_meta_data.h" + +#include "utils/constant.h" +namespace OHOS::DistributedData { + +AutoLaunchMetaData::AutoLaunchMetaData() +{ +} + +bool AutoLaunchMetaData::Marshal(json& node) const +{ + SetValue(node[GET_NAME(datas)], datas); + return true; +} + +bool AutoLaunchMetaData::Unmarshal(const json& node) +{ + GetValue(node, GET_NAME(datas), datas); + return true; +} + +std::string AutoLaunchMetaData::GetPrefix(const std::initializer_list& fields) +{ + return Constant::Join(PREFIX, Constant::KEY_SEPARATOR, fields); +} +} \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/metadata/meta_data_manager.cpp b/datamgr_service/services/distributeddataservice/framework/metadata/meta_data_manager.cpp index 1e8cd74f..1f77a82b 100644 --- a/datamgr_service/services/distributeddataservice/framework/metadata/meta_data_manager.cpp +++ b/datamgr_service/services/distributeddataservice/framework/metadata/meta_data_manager.cpp @@ -26,13 +26,18 @@ public: using Filter = MetaDataManager::Filter; using MetaStore = MetaDataManager::MetaStore; using Observer = MetaDataManager::Observer; + using DBOrigin = DistributedDB::Origin; + using DBChangeData = DistributedDB::ChangedData; + using Type = DistributedDB::Type; MetaObserver(std::shared_ptr metaStore, std::shared_ptr filter, Observer observer, bool isLocal = false); virtual ~MetaObserver(); // Database change callback void OnChange(const DistributedDB::KvStoreChangedData &data) override; + void OnChange(DBOrigin origin, const std::string &originalId, DBChangeData &&data) override; + void HandleChanges(int32_t flag, std::vector> &priData); private: std::shared_ptr metaStore_; std::shared_ptr filter_; @@ -47,6 +52,9 @@ MetaObserver::MetaObserver(std::shared_ptr metaStore, int mode = isLocal ? DistributedDB::OBSERVER_CHANGES_LOCAL_ONLY : (DistributedDB::OBSERVER_CHANGES_NATIVE | DistributedDB::OBSERVER_CHANGES_FOREIGN); auto status = metaStore_->RegisterObserver(filter_->GetKey(), mode, this); + if (!isLocal) { + status = metaStore_->RegisterObserver(filter_->GetKey(), DistributedDB::OBSERVER_CHANGES_CLOUD, this); + } if (status != DistributedDB::DBStatus::OK) { ZLOGE("register meta observer failed :%{public}d.", status); } @@ -94,6 +102,35 @@ void MetaObserver::OnChange(const DistributedDB::KvStoreChangedData &data) } } +void MetaObserver::OnChange(DBOrigin origin, const std::string &originalId, DBChangeData &&data) +{ + (void)origin; + (void)originalId; + HandleChanges(MetaDataManager::INSERT, data.primaryData[MetaDataManager::INSERT]); + HandleChanges(MetaDataManager::UPDATE, data.primaryData[MetaDataManager::UPDATE]); + HandleChanges(MetaDataManager::DELETE, data.primaryData[MetaDataManager::DELETE]); +} + +void MetaObserver::HandleChanges(int32_t flag, std::vector> &priData) +{ + if (priData.empty()) { + return; + } + for (const auto &priKey : priData) { + if (priKey.empty()) { + continue; + } + auto strValue = std::get_if(&priKey[0]); + if (strValue != nullptr) { + auto key = *strValue; + if (!(*filter_)(key)) { + continue; + } + observer_(key, "", flag); + } + } +} + MetaDataManager &MetaDataManager::GetInstance() { static MetaDataManager instance; @@ -130,6 +167,14 @@ void MetaDataManager::SetSyncer(const Syncer &syncer) syncer_ = syncer; } +void MetaDataManager::SetCloudSyncer(const CloudSyncer &cloudSyncer) +{ + if (metaStore_ == nullptr) { + return; + } + cloudSyncer_ = cloudSyncer; +} + bool MetaDataManager::SaveMeta(const std::string &key, const Serializable &value, bool isLocal) { if (!inited_) { @@ -142,8 +187,8 @@ bool MetaDataManager::SaveMeta(const std::string &key, const Serializable &value if (status == DistributedDB::DBStatus::OK && backup_) { backup_(metaStore_); } - if (!isLocal && syncer_) { - syncer_(metaStore_, status); + if (!isLocal && cloudSyncer_) { + cloudSyncer_(); } if (status != DistributedDB::DBStatus::OK) { ZLOGE("failed! status:%{public}d isLocal:%{public}d, key:%{public}s", @@ -200,8 +245,8 @@ bool MetaDataManager::DelMeta(const std::string &key, bool isLocal) if (status == DistributedDB::DBStatus::OK && backup_) { backup_(metaStore_); } - if (!isLocal && syncer_) { - syncer_(metaStore_, status); + if (!isLocal && cloudSyncer_) { + cloudSyncer_(); } return ((status == DistributedDB::DBStatus::OK) || (status == DistributedDB::DBStatus::NOT_FOUND)); } diff --git a/datamgr_service/services/distributeddataservice/framework/metadata/store_meta_data.cpp b/datamgr_service/services/distributeddataservice/framework/metadata/store_meta_data.cpp index b11bae26..219780e5 100644 --- a/datamgr_service/services/distributeddataservice/framework/metadata/store_meta_data.cpp +++ b/datamgr_service/services/distributeddataservice/framework/metadata/store_meta_data.cpp @@ -15,6 +15,7 @@ #include "metadata/store_meta_data.h" +#include "metadata/auto_launch_meta_data.h" #include "metadata/secret_key_meta_data.h" #include "metadata/store_meta_data_local.h" #include "metadata/strategy_meta_data.h" @@ -52,6 +53,8 @@ bool StoreMetaData::Marshal(json &node) const SetValue(node[GET_NAME(user)], user); SetValue(node[GET_NAME(account)], account); SetValue(node[GET_NAME(dataType)], dataType); + SetValue(node[GET_NAME(enableCloud)], enableCloud); + SetValue(node[GET_NAME(cloudAutoSync)], cloudAutoSync); // compatible with the versions which lower than VERSION_TAG_0000 SetValue(node[GET_NAME(kvStoreType)], storeType); @@ -90,6 +93,8 @@ bool StoreMetaData::Unmarshal(const json &node) GetValue(node, GET_NAME(user), user); GetValue(node, GET_NAME(account), account); GetValue(node, GET_NAME(dataType), dataType); + GetValue(node, GET_NAME(enableCloud), enableCloud); + GetValue(node, GET_NAME(cloudAutoSync), cloudAutoSync); // compatible with the older versions if (version < FIELD_CHANGED_TAG) { @@ -126,15 +131,17 @@ bool StoreMetaData::operator==(const StoreMetaData &metaData) const if (Constant::NotEqual(isAutoSync, metaData.isAutoSync) || Constant::NotEqual(isBackup, metaData.isBackup) || Constant::NotEqual(isDirty, metaData.isDirty) || Constant::NotEqual(isEncrypt, metaData.isEncrypt) || Constant::NotEqual(isSearchable, metaData.isSearchable) || - Constant::NotEqual(isNeedCompress, metaData.isNeedCompress)) { + Constant::NotEqual(isNeedCompress, metaData.isNeedCompress) || + Constant::NotEqual(enableCloud, metaData.enableCloud) || + Constant::NotEqual(cloudAutoSync, metaData.cloudAutoSync)) { return false; } return (version == metaData.version && storeType == metaData.storeType && dataType == metaData.dataType && securityLevel == metaData.securityLevel && area == metaData.area && uid == metaData.uid && tokenId == metaData.tokenId && instanceId == metaData.instanceId && appId == metaData.appId && appType == metaData.appType && bundleName == metaData.bundleName && dataDir == metaData.dataDir && - storeId == metaData.storeId && user == metaData.user && deviceId == metaData.deviceId - ); + storeId == metaData.storeId && user == metaData.user && deviceId == metaData.deviceId && + account == metaData.account); } bool StoreMetaData::operator!=(const StoreMetaData &metaData) const @@ -160,7 +167,7 @@ std::string StoreMetaData::GetKeyLocal() const std::string StoreMetaData::GetSecretKey() const { - if (version < CURRENT_VERSION) { + if (version < UUID_CHANGED_TAG) { return SecretKeyMetaData::GetKey({ user, "default", bundleName, storeId }); } return SecretKeyMetaData::GetKey({ user, "default", bundleName, storeId, std::to_string(instanceId) }); @@ -168,12 +175,17 @@ std::string StoreMetaData::GetSecretKey() const std::string StoreMetaData::GetBackupSecretKey() const { - if (version < CURRENT_VERSION) { + if (version < UUID_CHANGED_TAG) { return SecretKeyMetaData::GetBackupKey({ user, "default", bundleName, storeId }); } return SecretKeyMetaData::GetBackupKey({ user, "default", bundleName, storeId, std::to_string(instanceId) }); } +std::string StoreMetaData::GetAutoLaunchKey() const +{ + return AutoLaunchMetaData::GetPrefix({ deviceId, user, "default", bundleName, storeId }); +} + std::string StoreMetaData::GetStoreAlias() const { return Anonymous::Change(storeId); @@ -211,4 +223,4 @@ StoreInfo StoreMetaData::GetStoreInfo() const return info; } } // namespace DistributedData -} // namespace OHOS +} // namespace OHOS \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/metadata/store_meta_data_local.cpp b/datamgr_service/services/distributeddataservice/framework/metadata/store_meta_data_local.cpp index d95daa90..dcff9a4c 100644 --- a/datamgr_service/services/distributeddataservice/framework/metadata/store_meta_data_local.cpp +++ b/datamgr_service/services/distributeddataservice/framework/metadata/store_meta_data_local.cpp @@ -95,7 +95,8 @@ StoreMetaDataLocal::~StoreMetaDataLocal() bool StoreMetaDataLocal::operator==(const StoreMetaDataLocal &metaData) const { if (Constant::NotEqual(isAutoSync, metaData.isAutoSync) || Constant::NotEqual(isBackup, metaData.isBackup) || - Constant::NotEqual(isDirty, metaData.isDirty) || Constant::NotEqual(isEncrypt, metaData.isEncrypt)) { + Constant::NotEqual(isDirty, metaData.isDirty) || Constant::NotEqual(isEncrypt, metaData.isEncrypt) || + Constant::NotEqual(isPublic, metaData.isPublic)) { return false; } return dataDir == metaData.dataDir; diff --git a/datamgr_service/services/distributeddataservice/framework/store/auto_cache.cpp b/datamgr_service/services/distributeddataservice/framework/store/auto_cache.cpp index 98a5645d..0e5420b2 100644 --- a/datamgr_service/services/distributeddataservice/framework/store/auto_cache.cpp +++ b/datamgr_service/services/distributeddataservice/framework/store/auto_cache.cpp @@ -14,6 +14,8 @@ */ #define LOG_TAG "AutoCache" #include +#include "changeevent/remote_change_event.h" +#include "eventcenter/event_center.h" #include "utils/anonymous.h" #include "store/auto_cache.h" @@ -78,7 +80,7 @@ AutoCache::Store AutoCache::GetStore(const StoreMetaData &meta, const Watchers & return !stores.empty(); } auto result = stores.emplace(std::piecewise_construct, std::forward_as_tuple(meta.storeId), - std::forward_as_tuple(dbStore, watchers, atoi(meta.user.c_str()))); + std::forward_as_tuple(dbStore, watchers, atoi(meta.user.c_str()), meta)); store = result.first->second; StartTimer(); return !stores.empty(); @@ -209,8 +211,9 @@ void AutoCache::Disable(uint32_t tokenId, const std::string& storeId) CloseStore(tokenId, storeId); } -AutoCache::Delegate::Delegate(GeneralStore *delegate, const Watchers &watchers, int32_t user) - : store_(delegate), watchers_(watchers), user_(user) +AutoCache::Delegate::Delegate(GeneralStore *delegate, const Watchers &watchers, int32_t user, + const StoreMetaData &meta) + : store_(delegate), watchers_(watchers), user_(user), meta_(meta) { time_ = std::chrono::steady_clock::now() + std::chrono::minutes(INTERVAL); if (store_ != nullptr) { @@ -269,6 +272,11 @@ int32_t AutoCache::Delegate::GetUser() const int32_t AutoCache::Delegate::OnChange(const Origin &origin, const PRIFields &primaryFields, ChangeInfo &&values) { + std::vector tables; + for (const auto &[table, value] : values) { + tables.emplace_back(table); + } + PostDataChange(meta_, tables); Watchers watchers; { std::unique_lock lock(mutex_); @@ -287,6 +295,11 @@ int32_t AutoCache::Delegate::OnChange(const Origin &origin, const PRIFields &pri int32_t AutoCache::Delegate::OnChange(const Origin &origin, const Fields &fields, ChangeData &&datas) { + std::vector tables; + for (const auto &[table, value] : datas) { + tables.emplace_back(table); + } + PostDataChange(meta_, tables); Watchers watchers; { std::unique_lock lock(mutex_); @@ -302,4 +315,16 @@ int32_t AutoCache::Delegate::OnChange(const Origin &origin, const Fields &fields } return Error::E_OK; } + +void AutoCache::Delegate::PostDataChange(const StoreMetaData &meta, const std::vector &tables) +{ + RemoteChangeEvent::DataInfo info; + info.userId = meta.user; + info.storeId = meta.storeId; + info.deviceId = meta.deviceId; + info.bundleName = meta.bundleName; + info.tables = tables; + auto evt = std::make_unique(RemoteChangeEvent::DATA_CHANGE, std::move(info)); + EventCenter::GetInstance().PostEvent(std::move(evt)); +} } // namespace OHOS::DistributedData diff --git a/datamgr_service/services/distributeddataservice/framework/test/BUILD.gn b/datamgr_service/services/distributeddataservice/framework/test/BUILD.gn index 79b7862f..026e7a90 100644 --- a/datamgr_service/services/distributeddataservice/framework/test/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/framework/test/BUILD.gn @@ -44,6 +44,7 @@ config("module_private_config") { "${data_service_path}/app/src/security", "${data_service_path}/service/crypto/include", "${data_service_path}/service/matrix/include", + "${data_service_path}/service/waterversion", "//third_party/json/single_include", ] ldflags = [ "-Wl,--whole-archive" ] @@ -119,7 +120,7 @@ ohos_unittest("SerializableTest") { ] } -ohos_unittest("UtilsTest") { +ohos_unittest("ServiceUtilsTest") { module_out_path = module_output_path sources = [ "utils_test.cpp" ] @@ -143,13 +144,23 @@ ohos_unittest("UtilsTest") { ohos_unittest("StoreTest") { module_out_path = module_output_path + include_dirs = [ "${data_service_path}/service/test/mock" ] + sources = [ - "../../service/rdb/rdb_query.cpp", + "${data_service_path}/framework/metadata/store_meta_data.cpp", + "${data_service_path}/framework/store/auto_cache.cpp", + "${data_service_path}/service/rdb/rdb_query.cpp", + "${data_service_path}/service/test/mock/general_store_mock.cpp", "store_test.cpp", ] configs = [ ":module_private_config" ] + cflags = [ + "-Dprivate=public", + "-Dprotected=public", + ] + external_deps = [ "access_token:libaccesstoken_sdk", "access_token:libnativetoken", @@ -276,8 +287,43 @@ ohos_unittest("ServiceMetaDataTest") { "meta_data_test.cpp", ] + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + configs = [ ":module_private_config" ] + include_dirs = [ + "${device_manager_path}/interfaces/inner_kits/native_cpp/include", + "../include/", + "../../service/bootstrap/include/", + "../../service/common/", + "../../service/rdb/", + "../../../../../relational_store/interfaces/inner_api/rdb/include", + "../../../../../relational_store/interfaces/inner_api/common_type/include", + "${kv_store_distributeddb_path}/interfaces/include", + "${kv_store_distributeddb_path}/include", + "${kv_store_path}/frameworks/innerkitsimpl/distributeddatasvc/include", + "${kv_store_path}/frameworks/innerkitsimpl/distributeddatafwk/include", + "${kv_store_common_path}", + "${kv_store_path}/frameworks/innerkitsimpl/distributeddatafwk/src", + "${kv_store_path}/frameworks/innerkitsimpl/kvdb/include", + "${kv_store_path}/interfaces/innerkits/distributeddata/include", + "${data_service_path}/adapter/include", + "${data_service_path}/framework/include", + "${data_service_path}/service/config/include", + "${data_service_path}/app/src", + "${data_service_path}/adapter/include/account", + "${data_service_path}/app/src/security", + "${data_service_path}/service/crypto/include", + "${data_service_path}/service/matrix/include", + "${data_service_path}/service/waterversion", + "${data_service_path}/service/kvdb", + "//third_party/json/single_include", + ] + external_deps = [ "c_utils:utils", "dataclassification:data_transit_mgr", @@ -330,10 +376,10 @@ group("unittest") { ":MetaDataManagerTest", ":SerializableTest", ":ServiceMetaDataTest", + ":ServiceUtilsTest", ":StoreMetaDataLocalTest", ":StoreTest", ":SubscriptionTest", - ":UtilsTest", ] } ############################################################################### diff --git a/datamgr_service/services/distributeddataservice/framework/test/cloud_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/cloud_test.cpp index eb7f03a8..15a83e10 100644 --- a/datamgr_service/services/distributeddataservice/framework/test/cloud_test.cpp +++ b/datamgr_service/services/distributeddataservice/framework/test/cloud_test.cpp @@ -17,13 +17,19 @@ #include #include "serializable/serializable.h" +#include "cloud/cloud_db.h" #include "cloud/cloud_info.h" +#include "cloud/cloud_server.h" #include "cloud/schema_meta.h" #include "nlohmann/json.hpp" #include "utils/crypto.h" +#include "store/general_store.h" +#include "store/general_value.h" +#include "store/general_watcher.h" using namespace testing::ext; using namespace OHOS::DistributedData; +namespace OHOS::Test { class CloudInfoTest : public testing::Test { public: static void SetUpTestCase(void){}; @@ -32,6 +38,51 @@ public: void TearDown(){}; }; +class ServicesCloudServerTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp(){}; + void TearDown(){}; +}; + +class ServicesCloudDBTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp(){}; + void TearDown(){}; +}; + +class MockGeneralWatcher : public DistributedData::GeneralWatcher { +public: + int32_t OnChange(const Origin &origin, const PRIFields &primaryFields, + ChangeInfo &&values) override + { + return GeneralError::E_OK; + } + + int32_t OnChange(const Origin &origin, const Fields &fields, ChangeData &&datas) override + { + return GeneralError::E_OK; + } +}; + +class MockQuery : public GenQuery { +public: + static const uint64_t TYPE_ID = 1; + + bool IsEqual(uint64_t tid) override + { + return tid == TYPE_ID; + } + + std::vector GetTables() override + { + return {"table1", "table2"}; + } +}; + /** * @tc.name: GetSchemaPrefix * @tc.desc: Get schema prefix. @@ -336,3 +387,123 @@ HWTEST_F(CloudInfoTest, GetSchemaKeyTest4, TestSize.Level0) auto result = cloudInfo.GetSchemaKey(); ASSERT_EQ(info, result); } + +/** +* @tc.name: CloudServer +* @tc.desc: test CloudServer function. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(ServicesCloudServerTest, CloudServer, TestSize.Level0) +{ + CloudServer cloudServer; + int32_t userId = 100; + cloudServer.GetServerInfo(userId); + std::string bundleName = "com.ohos.cloudtest"; + cloudServer.GetAppSchema(userId, bundleName); + std::map> dbs; + auto result1 = cloudServer.Subscribe(userId, dbs); + EXPECT_EQ(result1, GeneralError::E_OK); + result1 = cloudServer.Unsubscribe(userId, dbs); + EXPECT_EQ(result1, GeneralError::E_OK); + + int user = 1; + uint32_t tokenId = 123; + CloudServer::Database dbMeta; + auto result2 = cloudServer.ConnectAssetLoader(tokenId, dbMeta); + EXPECT_EQ(result2, nullptr); + result2 = cloudServer.ConnectAssetLoader(bundleName, user, dbMeta); + EXPECT_EQ(result2, nullptr); + + auto result3 = cloudServer.ConnectCloudDB(tokenId, dbMeta); + EXPECT_EQ(result3, nullptr); + result3 = cloudServer.ConnectCloudDB(bundleName, user, dbMeta); + EXPECT_EQ(result3, nullptr); + + auto result4 = cloudServer.ConnectSharingCenter(userId, bundleName); + EXPECT_EQ(result4, nullptr); + cloudServer.Clean(userId); + cloudServer.ReleaseUserInfo(userId); + std::shared_ptr executor = std::make_shared(1, 0); + cloudServer.Bind(executor); + auto result5 = cloudServer.IsSupportCloud(userId); + EXPECT_FALSE(result5); +} + +/** +* @tc.name: CloudDB +* @tc.desc: test CloudDB function. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(ServicesCloudDBTest, CloudDB, TestSize.Level0) +{ + CloudDB cloudDB; + std::string table = "table"; + VBucket extend; + VBuckets values; + auto result1 = cloudDB.Execute(table, "sql", extend); + EXPECT_EQ(result1, GeneralError::E_NOT_SUPPORT); + result1 = cloudDB.BatchInsert(table, std::move(values), values); + EXPECT_EQ(result1, GeneralError::E_NOT_SUPPORT); + result1 = cloudDB.BatchUpdate(table, std::move(values), values); + EXPECT_EQ(result1, GeneralError::E_NOT_SUPPORT); + result1 = cloudDB.BatchDelete(table, values); + EXPECT_EQ(result1, GeneralError::E_NOT_SUPPORT); + result1 = cloudDB.PreSharing(table, values); + EXPECT_EQ(result1, GeneralError::E_NOT_SUPPORT); + + CloudDB::Devices devices; + MockQuery query; + CloudDB::Async async; + result1 = cloudDB.Sync(devices, 0, query, async, 0); + EXPECT_EQ(result1, GeneralError::E_NOT_SUPPORT); + + MockGeneralWatcher watcher; + result1 = cloudDB.Watch(1, watcher); + EXPECT_EQ(result1, GeneralError::E_NOT_SUPPORT); + result1 = cloudDB.Unwatch(1, watcher); + EXPECT_EQ(result1, GeneralError::E_NOT_SUPPORT); + + result1 = cloudDB.Lock(); + EXPECT_EQ(result1, GeneralError::E_NOT_SUPPORT); + result1 = cloudDB.Unlock(); + EXPECT_EQ(result1, GeneralError::E_NOT_SUPPORT); + result1 = cloudDB.Heartbeat(); + EXPECT_EQ(result1, GeneralError::E_NOT_SUPPORT); + result1 = cloudDB.Close(); + EXPECT_EQ(result1, GeneralError::E_NOT_SUPPORT); + + auto result2 = cloudDB.Query(table, extend); + EXPECT_EQ(result2, nullptr); + result2 = cloudDB.Query(query, extend); + EXPECT_EQ(result2, nullptr); + + auto result3 = cloudDB.AliveTime(); + EXPECT_EQ(result3, -1); + std::string bundleName = "com.ohos.cloudDBtest"; + auto result4 = cloudDB.GetEmptyCursor(bundleName); + std::pair cursor = { GeneralError::E_NOT_SUPPORT, "" }; + EXPECT_EQ(result4, cursor); +} + +/** +* @tc.name: SchemaMeta +* @tc.desc: test SchemaMeta GetLowVersion and GetHighVersion function. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(CloudInfoTest, SchemaMeta, TestSize.Level0) +{ + SchemaMeta schemaMeta; + auto metaVersion = SchemaMeta::CURRENT_VERSION & 0xFFFF; + auto result1 = schemaMeta.GetLowVersion(); + EXPECT_EQ(result1, metaVersion); + metaVersion = SchemaMeta::CURRENT_VERSION & ~0xFFFF; + auto result2 = schemaMeta.GetHighVersion(); + EXPECT_EQ(result2, metaVersion); +} +} // namespace OHOS::Test diff --git a/datamgr_service/services/distributeddataservice/framework/test/feature_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/feature_test.cpp index 1fdbd16a..5490d043 100644 --- a/datamgr_service/services/distributeddataservice/framework/test/feature_test.cpp +++ b/datamgr_service/services/distributeddataservice/framework/test/feature_test.cpp @@ -18,12 +18,11 @@ using namespace testing::ext; using namespace OHOS::DistributedData; - namespace DistributedDB { struct AutoLaunchParam { }; } - +namespace OHOS::Test { class FeatureSystemTest : public testing::Test { }; @@ -234,7 +233,7 @@ HWTEST_F(FeatureSystemTest, OnUserChangeTest, TestSize.Level1) /** * @tc.name: FeatureTest002 -* @tc.desc: online and offline and onReady +* @tc.desc: online and offline and onReady and onSessionReady * @tc.type: FUNC * @tc.require: * @tc.author: MengYao @@ -254,4 +253,8 @@ HWTEST_F(FeatureSystemTest, FeatureTest002, TestSize.Level1) ret = mockFeature.OnReady(device); EXPECT_EQ(ret, E_OK); + + ret = mockFeature.OnSessionReady(device); + EXPECT_EQ(ret, E_OK); } +} // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/test/general_store_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/general_store_test.cpp index 35cc0a95..88c1362b 100644 --- a/datamgr_service/services/distributeddataservice/framework/test/general_store_test.cpp +++ b/datamgr_service/services/distributeddataservice/framework/test/general_store_test.cpp @@ -19,7 +19,7 @@ using namespace testing::ext; using namespace OHOS::DistributedData; - +namespace OHOS::Test { class GeneralStoreTest : public testing::Test {}; /** @@ -85,5 +85,12 @@ HWTEST_F(GeneralStoreTest, BindInfo, TestSize.Level1) GeneralStore::BindInfo bindInfo(db, loader); ASSERT_EQ(bindInfo.db_, db); ASSERT_EQ(bindInfo.loader_, loader); -} + std::shared_ptr db1 = db; + std::shared_ptr loader1 = loader; + GeneralStore::BindInfo bindInfo1(db1, loader1); + ASSERT_EQ(bindInfo1.db_, db1); + ASSERT_EQ(bindInfo1.loader_, loader1); + EXPECT_FALSE(bindInfo < bindInfo1); +} +} // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/test/meta_data_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/meta_data_test.cpp index 80b8ab8c..992b78a6 100644 --- a/datamgr_service/services/distributeddataservice/framework/test/meta_data_test.cpp +++ b/datamgr_service/services/distributeddataservice/framework/test/meta_data_test.cpp @@ -17,7 +17,6 @@ #include "utils/constant.h" #include #include "bootstrap.h" -#include "device_manager_adapter.h" #include "kvstore_meta_manager.h" #include "metadata/appid_meta_data.h" #include "metadata/corrupted_meta_data.h" @@ -30,12 +29,11 @@ #include "metadata/strategy_meta_data.h" #include "metadata/capability_meta_data.h" #include "metadata/user_meta_data.h" - +#include "metadata/matrix_meta_data.h" using namespace testing::ext; using namespace OHOS; using namespace OHOS::DistributedKv; using namespace OHOS::DistributedData; -using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; namespace OHOS::Test { class ServiceMetaDataTest : public testing::Test { public: @@ -53,7 +51,6 @@ public: KvStoreMetaManager::GetInstance().BindExecutor(executors); KvStoreMetaManager::GetInstance().InitMetaParameter(); KvStoreMetaManager::GetInstance().InitMetaListener(); - DmAdapter::GetInstance().Init(executors); } static void TearDownTestCase(void) {}; void SetUp() {}; @@ -513,6 +510,25 @@ HWTEST_F(ServiceMetaDataTest, StoreMetaData007, TestSize.Level1) EXPECT_FALSE(storemetaData1 != storemetaData2); } +/** +* @tc.name: GetStoreInfo +* @tc.desc: test StoreMetaData GetStoreInfo function +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(ServiceMetaDataTest, GetStoreInfo, TestSize.Level1) +{ + StoreMetaData storeMetaData("100", "appid", "test_store"); + storeMetaData.version = TEST_CURRENT_VERSION; + storeMetaData.instanceId = 1; + + auto result = storeMetaData.GetStoreInfo(); + EXPECT_EQ(result.instanceId, storeMetaData.instanceId); + EXPECT_EQ(result.bundleName, storeMetaData.bundleName); + EXPECT_EQ(result.storeName, storeMetaData.storeId); +} + /** * @tc.name: StrategyMeta001 * @tc.desc: @@ -522,7 +538,7 @@ HWTEST_F(ServiceMetaDataTest, StoreMetaData007, TestSize.Level1) */ HWTEST_F(ServiceMetaDataTest, StrategyMeta001, TestSize.Level1) { - auto deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; + auto deviceId = "deviceId"; StrategyMeta strategyMeta(deviceId, "100", "ohos.test.demo", "test_store"); std::vector local = {"local1"}; std::vector remote = {"remote1"}; @@ -534,10 +550,10 @@ HWTEST_F(ServiceMetaDataTest, StrategyMeta001, TestSize.Level1) StrategyMeta strategyMetaData(deviceId, "200", "ohos.test.test", "test_stores"); std::string key = strategyMeta.GetKey(); - EXPECT_EQ(key, "StrategyMetaData######100###default###ohos.test.demo###test_store"); + EXPECT_EQ(key, "StrategyMetaData###deviceId###100###default###ohos.test.demo###test_store"); std::initializer_list fields = { deviceId, "100", "default", "ohos.test.demo", "test_store" }; std::string prefix = strategyMeta.GetPrefix(fields); - EXPECT_EQ(prefix, "StrategyMetaData######100###default###ohos.test.demo###test_store"); + EXPECT_EQ(prefix, "StrategyMetaData###deviceId###100###default###ohos.test.demo###test_store"); result = MetaDataManager::GetInstance().SaveMeta(key, strategyMeta, true); EXPECT_TRUE(result); @@ -569,7 +585,7 @@ HWTEST_F(ServiceMetaDataTest, StrategyMeta001, TestSize.Level1) */ HWTEST_F(ServiceMetaDataTest, StrategyMeta002, TestSize.Level1) { - auto deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; + auto deviceId = "deviceId"; StrategyMeta strategyMeta(deviceId, "100", "ohos.test.demo", "test_store"); std::vector local = {"local1"}; std::vector remote = {"remote1"}; @@ -582,7 +598,7 @@ HWTEST_F(ServiceMetaDataTest, StrategyMeta002, TestSize.Level1) StrategyMeta strategyMetaData(deviceId, "200", "ohos.test.test", "test_stores"); std::string key = strategyMeta.GetKey(); - EXPECT_EQ(key, "StrategyMetaData######100###default###ohos.test.demo###test_store###1"); + EXPECT_EQ(key, "StrategyMetaData###deviceId###100###default###ohos.test.demo###test_store###1"); result = MetaDataManager::GetInstance().SaveMeta(key, strategyMeta, true); EXPECT_TRUE(result); @@ -707,4 +723,53 @@ HWTEST_F(ServiceMetaDataTest, UserMetaData, TestSize.Level1) auto key = userMetaRow.GetKeyFor(userMetaData.deviceId); EXPECT_EQ(key, "UserMeta###PEER_DEVICE_ID"); } + +/** +* @tc.name: CapabilityRange +* @tc.desc: test CapabilityRange function +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(ServiceMetaDataTest, CapabilityRange, TestSize.Level1) +{ + CapabilityRange capabilityRange; + std::vector local = {"local1"}; + std::vector remote = {"remote1"}; + capabilityRange.localLabel = local; + capabilityRange.remoteLabel = remote; + Serializable::json node1; + capabilityRange.Marshal(node1); + EXPECT_EQ(node1["localLabel"], local); + EXPECT_EQ(node1["remoteLabel"], remote); + + CapabilityRange capRange; + capRange.Unmarshal(node1); + EXPECT_EQ(capRange.localLabel, local); + EXPECT_EQ(capRange.remoteLabel, remote); +} + +/** +* @tc.name: MatrixMetaData +* @tc.desc: test MatrixMetaData operator!= function +* @tc.type: FUNC +* @tc.require: +* @tc.author: nhj +*/ +HWTEST_F(ServiceMetaDataTest, MatrixMetaData, TestSize.Level1) +{ + MatrixMetaData matrixMetaData1; + matrixMetaData1.version = 0; + matrixMetaData1.deviceId = "PEER_DEVICE_ID"; + + MatrixMetaData matrixMetaData2; + matrixMetaData2.version = 0; + matrixMetaData2.deviceId = "PEER_DEVICE_ID"; + + MatrixMetaData matrixMetaData3; + matrixMetaData3.version = 1; + matrixMetaData3.deviceId = "DEVICE_ID"; + EXPECT_TRUE(matrixMetaData1 != matrixMetaData3); + EXPECT_FALSE(matrixMetaData1 != matrixMetaData2); +} } // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/test/store_meta_data_local_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/store_meta_data_local_test.cpp index b061380e..fa78ec5d 100644 --- a/datamgr_service/services/distributeddataservice/framework/test/store_meta_data_local_test.cpp +++ b/datamgr_service/services/distributeddataservice/framework/test/store_meta_data_local_test.cpp @@ -18,8 +18,13 @@ using namespace testing::ext; using OHOS::DistributedData::StoreMetaDataLocal; - +namespace OHOS::Test { class StoreMetaDataLocalTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp(){}; + void TearDown(){}; }; /** @@ -66,4 +71,29 @@ HWTEST_F(StoreMetaDataLocalTest, GetPrefixTest, TestSize.Level1) std::string prefix = metaData.GetPrefix(fields); ASSERT_EQ(prefix, expectedPrefix); -} \ No newline at end of file +} + +/** +* @tc.name: GetPolicy +* @tc.desc: test GetPolicy function +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(StoreMetaDataLocalTest, GetPolicy, TestSize.Level1) +{ + StoreMetaDataLocal metaData; + uint32_t type = UINT32_MAX; + auto policy = metaData.GetPolicy(type); + EXPECT_EQ(policy.type, type); + metaData.policies.push_back(policy); + EXPECT_TRUE(metaData.HasPolicy(type)); + EXPECT_FALSE(policy.IsValueEffect()); + type = 1; + policy = metaData.GetPolicy(type); + EXPECT_NE(policy.type, type); + policy.index = 1; + EXPECT_FALSE(metaData.HasPolicy(type)); + EXPECT_TRUE(policy.IsValueEffect()); +} +} // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/test/store_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/store_test.cpp index e1d58814..322b494a 100644 --- a/datamgr_service/services/distributeddataservice/framework/test/store_test.cpp +++ b/datamgr_service/services/distributeddataservice/framework/test/store_test.cpp @@ -16,14 +16,20 @@ #include "access_token.h" #include "gtest/gtest.h" +#include "general_store_mock.h" #include "log_print.h" +#include "metadata/store_meta_data.h" #include "rdb_query.h" #include "rdb_types.h" +#define private public +#include "store/auto_cache.h" #include "store/general_store.h" #include "store/general_value.h" +#include "store/general_watcher.h" + using namespace testing::ext; using namespace OHOS::DistributedData; - +namespace OHOS::Test { class GeneralValueTest : public testing::Test { public: static void SetUpTestCase(void){}; @@ -31,6 +37,7 @@ public: void SetUp(){}; void TearDown(){}; }; + class GeneralStoreTest : public testing::Test { public: static void SetUpTestCase(void){}; @@ -39,6 +46,14 @@ public: void TearDown(){}; }; +class AutoCacheTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp(){}; + void TearDown(){}; +}; + /** * @tc.name: SetQueryNodesTest * @tc.desc: Set and query nodes. @@ -86,3 +101,75 @@ HWTEST_F(GeneralStoreTest, GetMixModeTest, TestSize.Level2) auto highMode = GeneralStore::GetHighMode(mixMode); EXPECT_EQ(highMode, GeneralStore::AUTO_SYNC_MODE); } + +/** +* @tc.name: OnChange001 +* @tc.desc: AutoCache Delegate OnChange +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(AutoCacheTest, OnChange001, TestSize.Level2) +{ + GeneralStoreMock* store = new (std::nothrow) GeneralStoreMock(); + ASSERT_NE(store, nullptr); + AutoCache::Watchers watchers; + int32_t user = 0; + StoreMetaData meta; + AutoCache::Delegate delegate(store, watchers, user, meta); + delegate.SetObservers(watchers); + GeneralWatcher::Origin origin; + GeneralWatcher::PRIFields primaryFields; + GeneralWatcher::ChangeInfo values; + auto ret = delegate.OnChange(origin, primaryFields, std::move(values)); + EXPECT_EQ(ret, GeneralError::E_OK); +} + +/** +* @tc.name: OnChange002 +* @tc.desc: AutoCache Delegate OnChange +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(AutoCacheTest, OnChange002, TestSize.Level2) +{ + GeneralStoreMock* store = new (std::nothrow) GeneralStoreMock(); + ASSERT_NE(store, nullptr); + AutoCache::Watchers watchers; + int32_t user = 0; + StoreMetaData meta; + AutoCache::Delegate delegate(store, watchers, user, meta); + delegate.SetObservers(watchers); + GeneralWatcher::Origin origin; + GeneralWatcher::Fields fields; + GeneralWatcher::ChangeData datas; + auto ret = delegate.OnChange(origin, fields, std::move(datas)); + EXPECT_EQ(ret, GeneralError::E_OK); +} + +/** +* @tc.name: operatorStore +* @tc.desc: AutoCache Delegate operator Store() +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(AutoCacheTest, operatorStore, TestSize.Level2) +{ + GeneralStoreMock* store = new (std::nothrow) GeneralStoreMock(); + ASSERT_NE(store, nullptr); + AutoCache::Watchers watchers; + int32_t user = 0; + StoreMetaData meta; + AutoCache::Delegate delegate(store, watchers, user, meta); + AutoCache::Store result = static_cast(delegate); + EXPECT_NE(result, nullptr); + GeneralWatcher::Origin origin; + GeneralWatcher::Fields fields; + GeneralWatcher::ChangeData datas; + auto ret = delegate.OnChange(origin, fields, std::move(datas)); + EXPECT_EQ(ret, GeneralError::E_OK); + EXPECT_EQ(delegate.GetUser(), user); +} +} // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/test/utils_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/utils_test.cpp index 435130c1..e81c8602 100644 --- a/datamgr_service/services/distributeddataservice/framework/test/utils_test.cpp +++ b/datamgr_service/services/distributeddataservice/framework/test/utils_test.cpp @@ -12,21 +12,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#define LOG_TAG "UtilsTest" +#define LOG_TAG "ServiceUtilsTest" #include #include "access_token.h" +#include #include "gtest/gtest.h" #include "ipc_skeleton.h" #include "log_print.h" #include "utils/block_integer.h" #include "utils/converter.h" #include "utils/ref_count.h" +#include "utils/endian_converter.h" using namespace testing::ext; using namespace OHOS::DistributedData; - -class UtilsTest : public testing::Test { +namespace OHOS::Test { +class ServiceUtilsTest : public testing::Test { public: + static constexpr uint16_t HOST_VALUE16 = 0x1234; + static constexpr uint16_t NET_VALUE16 = 0x3412; + static constexpr uint32_t HOST_VALUE32 = 0x12345678; + static constexpr uint32_t NET_VALUE32 = 0x78563412; + static constexpr uint64_t HOST_VALUE64 = 0x1234567890ABCDEF; + static constexpr uint64_t NET_VALUE64 = 0xEFCDAB8967452301; static void SetUpTestCase(void){}; static void TearDownTestCase(void){}; void SetUp(){}; @@ -61,9 +69,9 @@ public: * @tc.desc: Storemeta data convert to storeinfo. * @tc.type: FUNC */ -HWTEST_F(UtilsTest, StoreMetaDataConvertToStoreInfo, TestSize.Level2) +HWTEST_F(ServiceUtilsTest, StoreMetaDataConvertToStoreInfo, TestSize.Level2) { - ZLOGI("UtilsTest StoreMetaDataConvertToStoreInfo begin."); + ZLOGI("ServiceUtilsTest StoreMetaDataConvertToStoreInfo begin."); StoreMetaData metaData; metaData.bundleName = "ohos.test.demo1"; metaData.storeId = "test_storeId"; @@ -106,6 +114,8 @@ HWTEST_F(BlockIntegerTest, SymbolOverloadingTest, TestSize.Level2) ASSERT_EQ(blockInteger, 12); ASSERT_TRUE(now2 - now1 >= interval); ASSERT_TRUE(blockInteger < 20); + int result = static_cast(blockInteger); + EXPECT_EQ(result, 12); } /** @@ -117,6 +127,9 @@ HWTEST_F(BlockIntegerTest, SymbolOverloadingTest, TestSize.Level2) */ HWTEST_F(RefCountTest, Constructortest, TestSize.Level2) { + std::function action = []() { }; + RefCount refCountWithAction(action); + EXPECT_TRUE(refCountWithAction); int num = 0; { RefCount refCount([&num]() { @@ -136,6 +149,44 @@ HWTEST_F(RefCountTest, Constructortest, TestSize.Level2) RefCount refCount4 = std::move(refCount2); ASSERT_TRUE(refCount4); ASSERT_EQ(num, 0); + EXPECT_TRUE(static_cast(refCount4)); + + RefCount refCount5 = refCount1; + refCount5 = refCount3; + ASSERT_TRUE(refCount5); + + RefCount refCount6 = std::move(refCount2); + refCount6 = std::move(refCount4); + ASSERT_TRUE(refCount6); } ASSERT_EQ(num, 10); -} \ No newline at end of file +} + +/** +* @tc.name: HostToNet +* @tc.desc: test endian_converter HostToNet function. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(ServiceUtilsTest, HostToNet, TestSize.Level1) +{ + uint16_t netValue16 = HostToNet(HOST_VALUE16); + EXPECT_EQ(netValue16, htole16(HOST_VALUE16)); + + uint16_t hostValue16 = NetToHost(NET_VALUE16); + EXPECT_EQ(hostValue16, le16toh(NET_VALUE16)); + + uint32_t netValue32 = HostToNet(HOST_VALUE32); + EXPECT_EQ(netValue32, htole32(HOST_VALUE32)); + + uint32_t hostValue32 = NetToHost(NET_VALUE32); + EXPECT_EQ(hostValue32, le32toh(NET_VALUE32)); + + uint64_t netValue64 = HostToNet(HOST_VALUE64); + EXPECT_EQ(netValue64, htole64(HOST_VALUE64)); + + uint64_t hostValue64 = NetToHost(NET_VALUE64); + EXPECT_EQ(hostValue64, le64toh(NET_VALUE64)); +} +} // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/utils/anonymous.cpp b/datamgr_service/services/distributeddataservice/framework/utils/anonymous.cpp index 3ebab254..ce2ee7ff 100644 --- a/datamgr_service/services/distributeddataservice/framework/utils/anonymous.cpp +++ b/datamgr_service/services/distributeddataservice/framework/utils/anonymous.cpp @@ -19,9 +19,10 @@ namespace DistributedData { constexpr int32_t HEAD_SIZE = 3; constexpr int32_t END_SIZE = 3; constexpr int32_t MIN_SIZE = HEAD_SIZE + END_SIZE + 3; +constexpr int32_t TAIL_SIZE = 6; constexpr const char *REPLACE_CHAIN = "***"; constexpr const char *DEFAULT_ANONYMOUS = "******"; -std::string Anonymous::Change(const std::string &name) +std::string Anonymous::Change(const std::string &name, bool end) { if (name.length() <= HEAD_SIZE) { return DEFAULT_ANONYMOUS; @@ -31,7 +32,10 @@ std::string Anonymous::Change(const std::string &name) return (name.substr(0, HEAD_SIZE) + REPLACE_CHAIN); } - return (name.substr(0, HEAD_SIZE) + REPLACE_CHAIN + name.substr(name.length() - END_SIZE, END_SIZE)); + if (!end) { + return (name.substr(0, HEAD_SIZE) + REPLACE_CHAIN + name.substr(name.length() - END_SIZE, END_SIZE)); + } + return (REPLACE_CHAIN + name.substr(name.length() - TAIL_SIZE, TAIL_SIZE)); } } // namespace DistributedData } // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/rust/connect_adapter/BUILD.gn b/datamgr_service/services/distributeddataservice/rust/connect_adapter/BUILD.gn index 1db82396..a5759ed5 100644 --- a/datamgr_service/services/distributeddataservice/rust/connect_adapter/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/rust/connect_adapter/BUILD.gn @@ -23,6 +23,8 @@ config("export_connect") { ohos_shared_library("conn_adapter") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false @@ -36,6 +38,7 @@ ohos_shared_library("conn_adapter") { external_deps = [ "ability_base:want", + "ability_runtime:ability_connect_callback_stub", "ability_runtime:extension_manager", "c_utils:utils", "hilog:libhilog", diff --git a/datamgr_service/services/distributeddataservice/rust/extension/BUILD.gn b/datamgr_service/services/distributeddataservice/rust/extension/BUILD.gn index 15a75ef1..302f89d6 100644 --- a/datamgr_service/services/distributeddataservice/rust/extension/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/rust/extension/BUILD.gn @@ -36,6 +36,8 @@ ohos_shared_library("opencloudextension") { ] branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false diff --git a/datamgr_service/services/distributeddataservice/rust/extension/cloud_server_impl.cpp b/datamgr_service/services/distributeddataservice/rust/extension/cloud_server_impl.cpp index 660b9085..41a5f486 100644 --- a/datamgr_service/services/distributeddataservice/rust/extension/cloud_server_impl.cpp +++ b/datamgr_service/services/distributeddataservice/rust/extension/cloud_server_impl.cpp @@ -33,7 +33,7 @@ __attribute__((used)) static bool g_isInit = using namespace Security::AccessToken; using DBMetaMgr = DistributedData::MetaDataManager; using Anonymous = DistributedData::Anonymous; -DBCloudInfo CloudServerImpl::GetServerInfo(int32_t userId) +DBCloudInfo CloudServerImpl::GetServerInfo(int32_t userId, bool needSpaceInfo) { DBCloudInfo result; OhCloudExtCloudSync *server = OhCloudExtCloudSyncNew(userId); @@ -61,12 +61,14 @@ DBCloudInfo CloudServerImpl::GetServerInfo(int32_t userId) return result; } result.id = std::string(reinterpret_cast(id), idLen); - unsigned long long totalSpace = 0; - OhCloudExtCloudInfoGetTotalSpace(pInfo.get(), &totalSpace); - result.totalSpace = totalSpace; - unsigned long long remainSpace = 0; - OhCloudExtCloudInfoGetRemainSpace(pInfo.get(), &remainSpace); - result.remainSpace = remainSpace; + if (needSpaceInfo) { + unsigned long long totalSpace = 0; + OhCloudExtCloudInfoGetTotalSpace(pInfo.get(), &totalSpace); + result.totalSpace = totalSpace; + unsigned long long remainSpace = 0; + OhCloudExtCloudInfoGetRemainSpace(pInfo.get(), &remainSpace); + result.remainSpace = remainSpace; + } OhCloudExtCloudInfoEnabled(pInfo.get(), &result.enableCloud); OhCloudExtHashMap *briefInfo = nullptr; status = OhCloudExtCloudInfoGetAppInfo(pInfo.get(), &briefInfo); @@ -117,13 +119,13 @@ void CloudServerImpl::GetAppInfo(std::shared_ptr briefInfo, D } } -DBSchemaMeta CloudServerImpl::GetAppSchema(int32_t userId, const std::string &bundleName) +std::pair CloudServerImpl::GetAppSchema(int32_t userId, const std::string &bundleName) { DBSchemaMeta dbSchema; dbSchema.bundleName = bundleName; OhCloudExtCloudSync *server = OhCloudExtCloudSyncNew(userId); if (server == nullptr) { - return dbSchema; + return { DBErr::E_ERROR, dbSchema }; } auto pServer = std::shared_ptr(server, [](auto *server) { OhCloudExtCloudSyncFree(server); @@ -131,8 +133,11 @@ DBSchemaMeta CloudServerImpl::GetAppSchema(int32_t userId, const std::string &bu OhCloudExtSchemaMeta *schema = nullptr; auto status = OhCloudExtCloudSyncGetAppSchema(pServer.get(), reinterpret_cast(bundleName.c_str()), bundleName.size(), &schema); + if (status == ERRNO_UNSUPPORTED) { + return { DBErr::E_NOT_SUPPORT, dbSchema }; + } if (status != ERRNO_SUCCESS || schema == nullptr) { - return dbSchema; + return { DBErr::E_ERROR, dbSchema }; } auto pSchema = std::shared_ptr(schema, [](auto *schema) { OhCloudExtSchemaMetaFree(schema); @@ -141,13 +146,13 @@ DBSchemaMeta CloudServerImpl::GetAppSchema(int32_t userId, const std::string &bu OhCloudExtVector *databases = nullptr; status = OhCloudExtSchemaMetaGetDatabases(pSchema.get(), &databases); if (status != ERRNO_SUCCESS || databases == nullptr) { - return dbSchema; + return { DBErr::E_ERROR, dbSchema }; } auto pDatabases = std::shared_ptr(databases, [](auto *databases) { OhCloudExtVectorFree(databases); }); GetDatabases(pDatabases, dbSchema); - return dbSchema; + return { DBErr::E_OK, dbSchema }; } void CloudServerImpl::GetDatabases(std::shared_ptr databases, DBSchemaMeta &dbSchema) diff --git a/datamgr_service/services/distributeddataservice/rust/extension/cloud_server_impl.h b/datamgr_service/services/distributeddataservice/rust/extension/cloud_server_impl.h index d669d6d1..c5e07270 100644 --- a/datamgr_service/services/distributeddataservice/rust/extension/cloud_server_impl.h +++ b/datamgr_service/services/distributeddataservice/rust/extension/cloud_server_impl.h @@ -36,8 +36,8 @@ using DBRelation = DBSub::Relation; using DBErr = DistributedData::GeneralError; class CloudServerImpl : public DistributedData::CloudServer { public: - DBCloudInfo GetServerInfo(int32_t userId) override; - DBSchemaMeta GetAppSchema(int32_t userId, const std::string &bundleName) override; + DBCloudInfo GetServerInfo(int32_t userId, bool needSpaceInfo) override; + std::pair GetAppSchema(int32_t userId, const std::string &bundleName) override; int32_t Subscribe(int32_t userId, const std::map> &dbs) override; int32_t Unsubscribe(int32_t userId, const std::map> &dbs) override; std::shared_ptr ConnectAssetLoader(uint32_t tokenId, const DBMeta &dbMeta) override; @@ -64,4 +64,4 @@ private: std::shared_ptr relations, const std::vector &bundles, DBSub &sub); }; } // namespace OHOS::CloudData -#endif // OHOS_DISTRIBUTED_DATA_SERVICES_EXTENSION_CLOUD_SERVER_IMPL_H +#endif // OHOS_DISTRIBUTED_DATA_SERVICES_EXTENSION_CLOUD_SERVER_IMPL_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/BUILD.gn b/datamgr_service/services/distributeddataservice/service/BUILD.gn index 6ba36e3a..f2b756ec 100644 --- a/datamgr_service/services/distributeddataservice/service/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/BUILD.gn @@ -37,26 +37,23 @@ config("module_public_config") { "permission/include", "rdb", "waterversion", - "//third_party/json/single_include", "${data_service_path}/adapter/include", "${data_service_path}/app/src", "${data_service_path}/framework/include", - "${datashare_path}/frameworks/native/common/include", - "${datashare_path}/interfaces/inner_api/common/include", - "${datashare_path}/interfaces/inner_api/consumer/include", "${kv_store_common_path}", "${kv_store_path}/frameworks/innerkitsimpl/distributeddatafwk/include", "${kv_store_path}/frameworks/innerkitsimpl/kvdb/include", "${kv_store_distributeddb_path}/include/", "${kv_store_distributeddb_path}/interfaces/include/", "${kv_store_distributeddb_path}/interfaces/include/relational", - "${dataobject_path}/interfaces/innerkits", ] } ohos_shared_library("distributeddatasvc") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false @@ -81,6 +78,7 @@ ohos_shared_library("distributeddatasvc") { "cloud/sync_strategies/network_sync_strategy.cpp", "common/common_types_utils.cpp", "common/value_proxy.cpp", + "common/xcollie.cpp", "config/src/config_factory.cpp", "config/src/model/backup_config.cpp", "config/src/model/checker_config.cpp", @@ -95,6 +93,7 @@ ohos_shared_library("distributeddatasvc") { "kvdb/auth_delegate.cpp", "kvdb/kvdb_exporter.cpp", "kvdb/kvdb_general_store.cpp", + "kvdb/kvdb_notifier_proxy.cpp", "kvdb/kvdb_service_impl.cpp", "kvdb/kvdb_service_stub.cpp", "kvdb/kvdb_watcher.cpp", @@ -102,6 +101,7 @@ ohos_shared_library("distributeddatasvc") { "kvdb/query_helper.cpp", "kvdb/upgrade.cpp", "kvdb/user_delegate.cpp", + "matrix/src/auto_sync_matrix.cpp", "matrix/src/device_matrix.cpp", "matrix/src/matrix_event.cpp", "object/object_asset_loader.cpp", @@ -151,9 +151,13 @@ ohos_shared_library("distributeddatasvc") { "device_auth:deviceauth_sdk", "device_manager:devicemanagersdk", "dfs_service:cloudsync_asset_kit_inner", + "dfs_service:distributed_file_daemon_kit_inner", + "hicollie:libhicollie", "hilog:libhilog", + "hisysevent:libhisysevent", "huks:libhukssdk", "ipc:ipc_core", + "json:nlohmann_json_static", "kv_store:distributeddata_inner", "kv_store:distributeddb", "relational_store:native_rdb", diff --git a/datamgr_service/services/distributeddataservice/service/CMakeLists.txt b/datamgr_service/services/distributeddataservice/service/CMakeLists.txt index cbce1341..0781c718 100644 --- a/datamgr_service/services/distributeddataservice/service/CMakeLists.txt +++ b/datamgr_service/services/distributeddataservice/service/CMakeLists.txt @@ -5,6 +5,7 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y -fno-rtti -fvisibility=hidden -D_GNU_SOURCE") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdata-sections -fPIC -fpic -ffunction-sections -D_GLIBC_MOCK") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--no-as-needed -ldl") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wformat=0 -fpermissive -Wattributes") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=deprecated-declarations -Wno-deprecated-declarations") 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 8bda3815..76237bc9 100644 --- a/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.cpp @@ -25,8 +25,10 @@ #include "cloud/cloud_server.h" #include "cloud/cloud_share_event.h" #include "cloud/make_query_event.h" +#include "cloud/sharing_center.h" #include "cloud_value_util.h" #include "communicator/device_manager_adapter.h" +#include "dfx/radar_reporter.h" #include "eventcenter/event_center.h" #include "hap_token_info.h" #include "ipc_skeleton.h" @@ -42,12 +44,14 @@ #include "sync_strategies/network_sync_strategy.h" #include "utils/anonymous.h" #include "values_bucket.h" + namespace OHOS::CloudData { using namespace DistributedData; using namespace DistributedKv; using namespace std::chrono; using namespace SharingUtil; using namespace Security::AccessToken; +using namespace DistributedDataDfx; using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; using Account = OHOS::DistributedKv::AccountDelegate; using AccessTokenKit = Security::AccessToken::AccessTokenKit; @@ -89,7 +93,7 @@ CloudServiceImpl::CloudServiceImpl() } Subscription sub; Subscription::Unmarshall(value, sub); - InitSubTask(sub); + InitSubTask(sub, SUBSCRIPTION_INTERVAL); return true; }, true); } @@ -112,7 +116,7 @@ int32_t CloudServiceImpl::EnableCloud(const std::string &id, const std::mapGetUserByToken(tokenId); + std::lock_guard lock(rwMetaMutex_); auto [status, cloudInfo] = GetCloudInfo(user); if (status != SUCCESS) { return status; @@ -127,7 +132,7 @@ int32_t CloudServiceImpl::DisableCloud(const std::string &id) if (cloudInfo.id != id) { ZLOGE("invalid args, [input] id:%{public}s, [exist] id:%{public}s", Anonymous::Change(id).c_str(), Anonymous::Change(cloudInfo.id).c_str()); - return ERROR; + return INVALID_ARGUMENT; } cloudInfo.enableCloud = false; if (!MetaDataManager::GetInstance().SaveMeta(cloudInfo.GetKey(), cloudInfo, true)) { @@ -141,6 +146,7 @@ int32_t CloudServiceImpl::ChangeAppSwitch(const std::string &id, const std::stri { auto tokenId = IPCSkeleton::GetCallingTokenID(); auto user = Account::GetInstance()->GetUserByToken(tokenId); + std::lock_guard lock(rwMetaMutex_); auto [status, cloudInfo] = GetCloudInfo(user); if (status != SUCCESS) { return status; @@ -148,7 +154,7 @@ int32_t CloudServiceImpl::ChangeAppSwitch(const std::string &id, const std::stri if (cloudInfo.id != id || !cloudInfo.Exist(bundleName)) { ZLOGE("invalid args, [input] id:%{public}s, [exist] id:%{public}s, bundleName:%{public}s", Anonymous::Change(id).c_str(), Anonymous::Change(cloudInfo.id).c_str(), bundleName.c_str()); - return ERROR; + return INVALID_ARGUMENT; } cloudInfo.apps[bundleName].cloudSwitch = (appSwitch == SWITCH_ON); if (!MetaDataManager::GetInstance().SaveMeta(cloudInfo.GetKey(), cloudInfo, true)) { @@ -161,49 +167,70 @@ int32_t CloudServiceImpl::ChangeAppSwitch(const std::string &id, const std::stri return SUCCESS; } -int32_t CloudServiceImpl::DoClean(CloudInfo &cloudInfo, const std::map &actions) +int32_t CloudServiceImpl::DoClean(const CloudInfo &cloudInfo, const std::map &actions) { syncManager_.StopCloudSync(cloudInfo.user); - auto keys = cloudInfo.GetSchemaKey(); for (const auto &[bundle, action] : actions) { if (!cloudInfo.Exist(bundle)) { continue; } SchemaMeta schemaMeta; - if (!MetaDataManager::GetInstance().LoadMeta(keys[bundle], schemaMeta, true)) { + if (!MetaDataManager::GetInstance().LoadMeta(cloudInfo.GetSchemaKey(bundle), schemaMeta, true)) { ZLOGE("failed, no schema meta:bundleName:%{public}s", bundle.c_str()); - return ERROR; - } - for (const auto &database : schemaMeta.databases) { - // action - StoreMetaData meta; - meta.bundleName = schemaMeta.bundleName; - meta.storeId = database.name; - meta.user = std::to_string(cloudInfo.user); - meta.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; - meta.instanceId = cloudInfo.apps[bundle].instanceId; - if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta, true)) { - ZLOGE("failed, no store meta bundleName:%{public}s, storeId:%{public}s", meta.bundleName.c_str(), - meta.GetStoreAlias().c_str()); - continue; - } - AutoCache::Store store = SyncManager::GetStore(meta, cloudInfo.user, false); - if (store == nullptr) { - ZLOGE("store null, storeId:%{public}s", meta.GetStoreAlias().c_str()); - return ERROR; - } - auto status = store->Clean({}, action, ""); - if (status != E_OK) { - 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; - } + continue; } + DoClean(cloudInfo.user, schemaMeta, action); } return SUCCESS; } +void CloudServiceImpl::DoClean(int32_t user, const SchemaMeta &schemaMeta, int32_t action) +{ + StoreMetaData meta; + meta.bundleName = schemaMeta.bundleName; + meta.user = std::to_string(user); + meta.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; + meta.instanceId = 0; + for (const auto &database : schemaMeta.databases) { + // action + meta.storeId = database.name; + if (!GetStoreMetaData(meta)) { + continue; + } + auto store = AutoCache::GetInstance().GetStore(meta, {}); + if (store == nullptr) { + ZLOGE("store null, storeId:%{public}s", meta.GetStoreAlias().c_str()); + continue; + } + auto status = store->Clean({}, action, ""); + if (status != E_OK) { + ZLOGW("remove device data status:%{public}d, user:%{public}d, bundleName:%{public}s, " + "storeId:%{public}s", + status, static_cast(user), meta.bundleName.c_str(), meta.GetStoreAlias().c_str()); + } + } +} + +bool CloudServiceImpl::GetStoreMetaData(StoreMetaData &meta) +{ + if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta, true)) { + if (meta.user == "0") { + ZLOGE("failed, no store meta bundleName:%{public}s, storeId:%{public}s, user = %{public}s", + meta.bundleName.c_str(), meta.GetStoreAlias().c_str(), meta.user.c_str()); + return false; + } + meta.user = "0"; + StoreMetaDataLocal localMeta; + if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKeyLocal(), localMeta, true) || + !localMeta.isPublic || !MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta, true)) { + ZLOGE("meta empty, not public store. bundleName:%{public}s, storeId:%{public}s, user = %{public}s", + meta.bundleName.c_str(), meta.GetStoreAlias().c_str(), meta.user.c_str()); + return false; + } + } + return true; +} + int32_t CloudServiceImpl::Clean(const std::string &id, const std::map &actions) { auto tokenId = IPCSkeleton::GetCallingTokenID(); @@ -247,14 +274,19 @@ int32_t CloudServiceImpl::CheckNotifyConditions(const std::string &id, const std return SUCCESS; } -std::pair> CloudServiceImpl::GetDbInfoFromExtraData(const ExtraData &extraData, - const SchemaMeta &schemaMeta) +std::map> CloudServiceImpl::GetDbInfoFromExtraData( + const ExtraData &extraData, const SchemaMeta &schemaMeta) { + std::map> dbInfos; for (auto &db : schemaMeta.databases) { if (db.alias != extraData.info.containerName) { continue; } std::vector tables; + if (extraData.info.tables.size() == 0) { + dbInfos.emplace(db.name, std::move(tables)); + continue; + } for (auto &table : db.tables) { const auto &tbs = extraData.info.tables; if (std::find(tbs.begin(), tbs.end(), table.alias) == tbs.end()) { @@ -269,9 +301,49 @@ std::pair> CloudServiceImpl::GetDbInfoFrom tables.emplace_back(table.sharedTableName); } } - return { db.name, std::move(tables) }; + if (!tables.empty()) { + dbInfos.emplace(db.name, std::move(tables)); + } } - return { "", {} }; + if (dbInfos.empty()) { + for (auto &db : schemaMeta.databases) { + if (db.alias != extraData.info.containerName) { + continue; + } + std::vector tables; + dbInfos.emplace(db.name, std::move(tables)); + } + } + return dbInfos; +} + +bool CloudServiceImpl::DoKvCloudSync(int32_t userId, const std::string &bundleName) +{ + auto stores = CheckerManager::GetInstance().GetDynamicStores(); + auto staticStores = CheckerManager::GetInstance().GetStaticStores(); + stores.insert(stores.end(), staticStores.begin(), staticStores.end()); + bool found = false; + for (auto &store : stores) { + if (store.bundleName == bundleName || bundleName.empty()) { + found = true; + break; + } + } + if (!found) { + return found; + } + std::vector users; + if (userId != INVALID_USER_ID) { + users.emplace_back(userId); + } else { + Account::GetInstance()->QueryForegroundUsers(users); + } + for (auto user : users) { + for (auto &store : stores) { + syncManager_.DoCloudSync(SyncManager::SyncInfo(user, store.bundleName, store.storeId)); + } + } + return found; } int32_t CloudServiceImpl::NotifyDataChange(const std::string &id, const std::string &bundleName) @@ -309,19 +381,24 @@ int32_t CloudServiceImpl::NotifyDataChange(const std::string &eventId, const std ZLOGD("invalid user:%{public}d", user); return INVALID_ARGUMENT; } + if (DoKvCloudSync(cloudInfo.user, exData.info.bundleName)) { + continue; + } 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; } - auto [storeId, tables] = GetDbInfoFromExtraData(exData, schemaMeta); - if (storeId.empty()) { - ZLOGE("invalid data, storeId:%{public}s, tables size:%{public}zu", Anonymous::Change(storeId).c_str(), - tables.size()); + auto dbInfos = GetDbInfoFromExtraData(exData, schemaMeta); + if (dbInfos.empty()) { + ZLOGE("GetDbInfoFromExtraData failed, empty database info."); return INVALID_ARGUMENT; } - syncManager_.DoCloudSync(SyncManager::SyncInfo(cloudInfo.user, exData.info.bundleName, storeId, tables)); + for (auto &dbInfo : dbInfos) { + syncManager_.DoCloudSync( + SyncManager::SyncInfo(cloudInfo.user, exData.info.bundleName, dbInfo.first, dbInfo.second)); + } } return SUCCESS; } @@ -514,7 +591,7 @@ std::pair CloudServiceImpl::QueryLastSyncInfo(const s int32_t CloudServiceImpl::OnInitialize() { DistributedDB::RuntimeConfig::SetCloudTranslate(std::make_shared()); - Execute(GenTask(0, 0, { WORK_CLOUD_INFO_UPDATE, WORK_SCHEMA_UPDATE, WORK_SUB })); + Execute(GenTask(0, 0, { WORK_CLOUD_INFO_UPDATE, WORK_SCHEMA_UPDATE, WORK_DO_CLOUD_SYNC, WORK_SUB })); std::vector users; Account::GetInstance()->QueryUsers(users); for (auto user : users) { @@ -553,13 +630,13 @@ int32_t CloudServiceImpl::OnUserChange(uint32_t code, const std::string &user, c Anonymous::Change(account).c_str()); switch (code) { case static_cast(AccountStatus::DEVICE_ACCOUNT_SWITCHED): - Execute(GenTask(0, userId, { WORK_CLOUD_INFO_UPDATE, WORK_SCHEMA_UPDATE, WORK_SUB, WORK_DO_CLOUD_SYNC })); + Execute(GenTask(0, userId, { WORK_CLOUD_INFO_UPDATE, WORK_SCHEMA_UPDATE, WORK_DO_CLOUD_SYNC, WORK_SUB })); break; case static_cast(AccountStatus::DEVICE_ACCOUNT_DELETE): Execute(GenTask(0, userId, { WORK_STOP_CLOUD_SYNC, WORK_RELEASE })); break; case static_cast(AccountStatus::DEVICE_ACCOUNT_UNLOCKED): - Execute(GenTask(0, userId, { WORK_CLOUD_INFO_UPDATE, WORK_SCHEMA_UPDATE, WORK_SUB, WORK_DO_CLOUD_SYNC })); + Execute(GenTask(0, userId, { WORK_CLOUD_INFO_UPDATE, WORK_SCHEMA_UPDATE, WORK_DO_CLOUD_SYNC, WORK_SUB })); break; default: break; @@ -567,6 +644,12 @@ int32_t CloudServiceImpl::OnUserChange(uint32_t code, const std::string &user, c return E_OK; } +int32_t CloudServiceImpl::OnScreenUnlocked(int32_t user) +{ + DoKvCloudSync(user); + return E_OK; +} + int32_t CloudServiceImpl::OnReady(const std::string& device) { if (device != DeviceManagerAdapter::CLOUD_DEVICE_UUID) { @@ -578,7 +661,8 @@ int32_t CloudServiceImpl::OnReady(const std::string& device) return SUCCESS; } for (auto user : users) { - Execute(GenTask(0, user, { WORK_CLOUD_INFO_UPDATE, WORK_SCHEMA_UPDATE, WORK_SUB, WORK_DO_CLOUD_SYNC })); + DoKvCloudSync(user); + Execute(GenTask(0, user, { WORK_CLOUD_INFO_UPDATE, WORK_SCHEMA_UPDATE, WORK_DO_CLOUD_SYNC, WORK_SUB })); } return SUCCESS; } @@ -616,7 +700,7 @@ std::pair CloudServiceImpl::GetCloudInfoFromServer(int32_t u CloudInfo cloudInfo; cloudInfo.user = userId; if (!DmAdapter::GetInstance().IsNetworkAvailable()) { - return { ERROR, cloudInfo }; + return { NETWORK_ERROR, cloudInfo }; } auto instance = CloudServer::GetInstance(); if (instance == nullptr) { @@ -625,11 +709,21 @@ std::pair CloudServiceImpl::GetCloudInfoFromServer(int32_t u cloudInfo = instance->GetServerInfo(cloudInfo.user); if (!cloudInfo.IsValid()) { ZLOGE("cloud is empty, user%{public}d", cloudInfo.user); - return { ERROR, cloudInfo }; + return { CLOUD_INFO_INVALID, cloudInfo }; } return { SUCCESS, cloudInfo }; } +int32_t CloudServiceImpl::UpdateCloudInfoFromServer(int32_t user) +{ + auto [status, cloudInfo] = GetCloudInfoFromServer(user); + if (status != SUCCESS || !cloudInfo.IsValid()) { + ZLOGE("userId:%{public}d, status:%{public}d", user, status); + return E_ERROR; + } + return MetaDataManager::GetInstance().SaveMeta(cloudInfo.GetKey(), cloudInfo, true) ? E_OK : E_ERROR; +} + bool CloudServiceImpl::UpdateCloudInfo(int32_t user) { auto [status, cloudInfo] = GetCloudInfoFromServer(user); @@ -649,8 +743,10 @@ bool CloudServiceImpl::UpdateCloudInfo(int32_t user) ReleaseUserInfo(user); ZLOGE("different id, [server] id:%{public}s, [meta] id:%{public}s", Anonymous::Change(cloudInfo.id).c_str(), Anonymous::Change(oldInfo.id).c_str()); + MetaDataManager::GetInstance().DelMeta(Subscription::GetKey(user), true); std::map actions; for (auto &[bundle, app] : cloudInfo.apps) { + MetaDataManager::GetInstance().DelMeta(Subscription::GetRelationKey(user, bundle), true); actions[bundle] = GeneralStore::CleanMode::CLOUD_INFO; } DoClean(oldInfo, actions); @@ -660,7 +756,7 @@ bool CloudServiceImpl::UpdateCloudInfo(int32_t user) bool CloudServiceImpl::UpdateSchema(int32_t user) { - auto [status, cloudInfo] = GetCloudInfoFromServer(user); + auto [status, cloudInfo] = GetCloudInfo(user); if (status != SUCCESS) { ZLOGE("user:%{public}d, status:%{public}d", user, status); return false; @@ -669,9 +765,18 @@ bool CloudServiceImpl::UpdateSchema(int32_t user) for (const auto &[bundle, key] : keys) { SchemaMeta schemaMeta; std::tie(status, schemaMeta) = GetAppSchemaFromServer(user, bundle); + if (status == NOT_SUPPORT) { + ZLOGW("app not support, del cloudInfo! user:%{public}d, bundleName:%{public}s", user, bundle.c_str()); + MetaDataManager::GetInstance().DelMeta(cloudInfo.GetKey()); + return false; + } if (status != SUCCESS) { continue; } + SchemaMeta oldMeta; + if (MetaDataManager::GetInstance().LoadMeta(key, oldMeta, true)) { + UpgradeSchemaMeta(user, oldMeta); + } MetaDataManager::GetInstance().SaveMeta(key, schemaMeta, true); } return true; @@ -681,20 +786,35 @@ std::pair CloudServiceImpl::GetAppSchemaFromServer(int32_t { SchemaMeta schemaMeta; if (!DmAdapter::GetInstance().IsNetworkAvailable()) { - return { ERROR, schemaMeta }; + return { NETWORK_ERROR, schemaMeta }; } auto instance = CloudServer::GetInstance(); if (instance == nullptr) { return { SERVER_UNAVAILABLE, schemaMeta }; } - schemaMeta = instance->GetAppSchema(user, bundleName); - if (!schemaMeta.IsValid()) { - ZLOGE("schema is InValid, user:%{public}d, bundleName:%{public}s", user, bundleName.c_str()); - return { ERROR, schemaMeta }; + int32_t status = E_OK; + std::tie(status, schemaMeta) = instance->GetAppSchema(user, bundleName); + if (status != E_OK || !schemaMeta.IsValid()) { + ZLOGE("schema is InValid, user:%{public}d, bundleName:%{public}s, status:%{public}d", user, bundleName.c_str(), + status); + return { status == E_NOT_SUPPORT ? NOT_SUPPORT : SCHEMA_INVALID, schemaMeta }; } return { SUCCESS, schemaMeta }; } +void CloudServiceImpl::UpgradeSchemaMeta(int32_t user, const SchemaMeta &schemaMeta) +{ + if (schemaMeta.metaVersion == SchemaMeta::CURRENT_VERSION) { + return; + } + // A major schema upgrade requires flag cleaning + if (SchemaMeta::GetHighVersion(schemaMeta.metaVersion) != SchemaMeta::GetHighVersion()) { + ZLOGI("start clean. user:%{public}d, bundleName:%{public}s, metaVersion:%{public}d", user, + schemaMeta.bundleName.c_str(), schemaMeta.metaVersion); + DoClean(user, schemaMeta, GeneralStore::CleanMode::CLOUD_INFO); + } +} + ExecutorPool::Task CloudServiceImpl::GenTask(int32_t retry, int32_t user, Handles handles) { return [this, retry, user, works = std::move(handles)]() mutable { @@ -746,10 +866,14 @@ std::pair CloudServiceImpl::GetSchemaMeta(int32_t userId, c return { ERROR, schemaMeta }; } std::string schemaKey = cloudInfo.GetSchemaKey(bundleName, instanceId); - if (MetaDataManager::GetInstance().LoadMeta(schemaKey, schemaMeta, true)) { + if (MetaDataManager::GetInstance().LoadMeta(schemaKey, schemaMeta, true) && + schemaMeta.metaVersion == SchemaMeta::CURRENT_VERSION) { return { SUCCESS, schemaMeta }; } + UpgradeSchemaMeta(userId, schemaMeta); + if (!Account::GetInstance()->IsVerified(userId)) { + ZLOGE("user:%{public}d is locked!", userId); return { ERROR, schemaMeta }; } std::tie(status, schemaMeta) = GetAppSchemaFromServer(userId, bundleName); @@ -800,6 +924,11 @@ int32_t CloudServiceImpl::CloudStatic::OnAppUninstall(const std::string &bundleN return E_OK; } +int32_t CloudServiceImpl::CloudStatic::OnAppInstall(const std::string &bundleName, int32_t user, int32_t index) +{ + return UpdateCloudInfoFromServer(user); +} + void CloudServiceImpl::GetSchema(const Event &event) { auto &rdbEvent = static_cast(event); @@ -884,14 +1013,13 @@ bool CloudServiceImpl::DoSubscribe(int32_t user) sub.userId = user; MetaDataManager::GetInstance().LoadMeta(sub.GetKey(), sub, true); if (CloudServer::GetInstance() == nullptr) { - ZLOGI("not support cloud server"); + ZLOGE("not support cloud server"); return true; } CloudInfo cloudInfo; cloudInfo.user = sub.userId; - auto exits = MetaDataManager::GetInstance().LoadMeta(cloudInfo.GetKey(), cloudInfo, true); - if (!exits) { + if (!MetaDataManager::GetInstance().LoadMeta(cloudInfo.GetKey(), cloudInfo, true)) { ZLOGW("error, there is no cloud info for user(%{public}d)", sub.userId); return false; } @@ -921,8 +1049,7 @@ bool CloudServiceImpl::DoSubscribe(int32_t user) } SchemaMeta schemaMeta; - exits = MetaDataManager::GetInstance().LoadMeta(cloudInfo.GetSchemaKey(bundle), schemaMeta, true); - if (exits) { + if (MetaDataManager::GetInstance().LoadMeta(cloudInfo.GetSchemaKey(bundle), schemaMeta, true)) { dbs.insert_or_assign(bundle, std::move(schemaMeta.databases)); } } @@ -1069,12 +1196,15 @@ int32_t CloudServiceImpl::Share(const std::string &sharingRes, const Participant ZLOGE("bundleName is empty, sharingRes:%{public}s", Anonymous::Change(sharingRes).c_str()); return E_ERROR; } + RadarReporter radar(EventName::CLOUD_SHARING_BEHAVIOR, BizScene::SHARE, hapInfo.bundleName.c_str(), __FUNCTION__); auto instance = GetSharingHandle(hapInfo); if (instance == nullptr) { + radar = CenterCode::NOT_SUPPORT + SharingCenter::SHARING_ERR_OFFSET; return NOT_SUPPORT; } results = instance->Share(hapInfo.user, hapInfo.bundleName, sharingRes, Convert(participants)); int32_t status = std::get<0>(results); + radar = (status == CenterCode::SUCCESS) ? CenterCode::SUCCESS : (status + SharingCenter::SHARING_ERR_OFFSET); ZLOGD("status:%{public}d", status); return Convert(static_cast(status)); } @@ -1086,12 +1216,15 @@ int32_t CloudServiceImpl::Unshare(const std::string &sharingRes, const Participa ZLOGE("bundleName is empty, sharingRes:%{public}s", Anonymous::Change(sharingRes).c_str()); return E_ERROR; } + RadarReporter radar(EventName::CLOUD_SHARING_BEHAVIOR, BizScene::UNSHARE, hapInfo.bundleName.c_str(), __FUNCTION__); auto instance = GetSharingHandle(hapInfo); if (instance == nullptr) { + radar = CenterCode::NOT_SUPPORT + SharingCenter::SHARING_ERR_OFFSET; return NOT_SUPPORT; } results = instance->Unshare(hapInfo.user, hapInfo.bundleName, sharingRes, Convert(participants)); int32_t status = std::get<0>(results); + radar = (status == CenterCode::SUCCESS) ? CenterCode::SUCCESS : (status + SharingCenter::SHARING_ERR_OFFSET); ZLOGD("status:%{public}d", status); return Convert(static_cast(status)); } @@ -1103,12 +1236,16 @@ int32_t CloudServiceImpl::Exit(const std::string &sharingRes, std::pairExit(hapInfo.user, hapInfo.bundleName, sharingRes); int32_t status = result.first; + radar = (status == CenterCode::SUCCESS) ? CenterCode::SUCCESS : (status + SharingCenter::SHARING_ERR_OFFSET); ZLOGD("status:%{public}d", status); return Convert(static_cast(status)); } @@ -1121,12 +1258,16 @@ int32_t CloudServiceImpl::ChangePrivilege(const std::string &sharingRes, const P ZLOGE("bundleName is empty, sharingRes:%{public}s", Anonymous::Change(sharingRes).c_str()); return E_ERROR; } + RadarReporter radar( + EventName::CLOUD_SHARING_BEHAVIOR, BizScene::CHANGE_PRIVILEGE, hapInfo.bundleName.c_str(), __FUNCTION__); auto instance = GetSharingHandle(hapInfo); if (instance == nullptr) { + radar = CenterCode::NOT_SUPPORT + SharingCenter::SHARING_ERR_OFFSET; return NOT_SUPPORT; } results = instance->ChangePrivilege(hapInfo.user, hapInfo.bundleName, sharingRes, Convert(participants)); int32_t status = std::get<0>(results); + radar = (status == CenterCode::SUCCESS) ? CenterCode::SUCCESS : (status + SharingCenter::SHARING_ERR_OFFSET); ZLOGD("status:%{public}d", status); return Convert(static_cast(status)); } @@ -1176,12 +1317,16 @@ int32_t CloudServiceImpl::ConfirmInvitation(const std::string &invitation, int32 Anonymous::Change(invitation).c_str(), confirmation); return E_ERROR; } + RadarReporter radar( + EventName::CLOUD_SHARING_BEHAVIOR, BizScene::CONFIRM_INVITATION, hapInfo.bundleName.c_str(), __FUNCTION__); auto instance = GetSharingHandle(hapInfo); if (instance == nullptr) { + radar = CenterCode::NOT_SUPPORT + SharingCenter::SHARING_ERR_OFFSET; return NOT_SUPPORT; } result = instance->ConfirmInvitation(hapInfo.user, hapInfo.bundleName, invitation, confirmation); int32_t status = std::get<0>(result); + radar = (status == CenterCode::SUCCESS) ? CenterCode::SUCCESS : (status + SharingCenter::SHARING_ERR_OFFSET); ZLOGD("status:%{public}d", status); return Convert(static_cast(status)); } @@ -1194,12 +1339,16 @@ int32_t CloudServiceImpl::ChangeConfirmation(const std::string &sharingRes, int3 ZLOGE("bundleName is empty, sharingRes:%{public}s", Anonymous::Change(sharingRes).c_str()); return E_ERROR; } + RadarReporter radar( + EventName::CLOUD_SHARING_BEHAVIOR, BizScene::CHANGE_CONFIRMATION, hapInfo.bundleName.c_str(), __FUNCTION__); auto instance = GetSharingHandle(hapInfo); if (instance == nullptr) { + radar = CenterCode::NOT_SUPPORT + SharingCenter::SHARING_ERR_OFFSET; return NOT_SUPPORT; } result = instance->ChangeConfirmation(hapInfo.user, hapInfo.bundleName, sharingRes, confirmation); int32_t status = result.first; + radar = (status == CenterCode::SUCCESS) ? CenterCode::SUCCESS : (status + SharingCenter::SHARING_ERR_OFFSET); ZLOGD("status:%{public}d", status); return Convert(static_cast(status)); } @@ -1231,7 +1380,7 @@ ExecutorPool::Task CloudServiceImpl::GenSubTask(Task task, int32_t user) }; } -void CloudServiceImpl::InitSubTask(const Subscription &sub) +void CloudServiceImpl::InitSubTask(const Subscription &sub, uint64_t minInterval) { auto expire = sub.GetMinExpireTime(); if (expire == INVALID_SUB_TIME) { @@ -1244,7 +1393,7 @@ void CloudServiceImpl::InitSubTask(const Subscription &sub) ZLOGI("Subscription Info, subTask:%{public}" PRIu64", user:%{public}d", subTask_, sub.userId); expire = expire - TIME_BEFORE_SUB; // before 12 hours auto now = static_cast(duration_cast(system_clock::now().time_since_epoch()).count()); - Duration delay = expire > now ? milliseconds(expire - now) : milliseconds(0); + Duration delay = milliseconds(std::max(expire > now ? expire - now : 0, minInterval)); std::lock_guard lock(mutex_); if (subTask_ != ExecutorPool::INVALID_TASK_ID) { if (expire < expireTime_) { @@ -1288,6 +1437,10 @@ int32_t CloudServiceImpl::SaveNetworkStrategy(const std::vector(*strategy); } } + NetworkSyncStrategy::StrategyInfo oldInfo; + MetaDataManager::GetInstance().LoadMeta(info.GetKey(), oldInfo, true); + ZLOGI("Strategy[user:%{public}d,bundleName:%{public}s] to [%{public}d] from [%{public}d]", + info.user, info.bundleName.c_str(), info.strategy, oldInfo.strategy); return MetaDataManager::GetInstance().SaveMeta(info.GetKey(), info, true) ? SUCCESS : ERROR; } } // namespace OHOS::CloudData \ No newline at end of file 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 66a36af2..76476c25 100644 --- a/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.h +++ b/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.h @@ -67,6 +67,7 @@ public: int32_t OnInitialize() override; int32_t OnBind(const BindInfo &info) override; int32_t OnUserChange(uint32_t code, const std::string &user, const std::string &account) override; + int32_t OnScreenUnlocked(int32_t user) override; int32_t OnReady(const std::string &device) override; int32_t Offline(const std::string &device) override; @@ -76,6 +77,7 @@ private: public: ~CloudStatic() override {}; int32_t OnAppUninstall(const std::string &bundleName, int32_t user, int32_t index) override; + int32_t OnAppInstall(const std::string &bundleName, int32_t user, int32_t index) override; }; class Factory { public: @@ -115,6 +117,7 @@ private: static constexpr int32_t WAIT_TIME = 30; // 30 seconds static constexpr int32_t DEFAULT_USER = 0; static constexpr int32_t TIME_BEFORE_SUB = 12 * 60 * 60 * 1000; // 12hours, ms + static constexpr int32_t SUBSCRIPTION_INTERVAL = 60 * 60 * 1000; // 1hours bool UpdateCloudInfo(int32_t user); bool UpdateSchema(int32_t user); @@ -123,12 +126,14 @@ private: bool DoCloudSync(int32_t user); bool StopCloudSync(int32_t user); - std::pair GetCloudInfo(int32_t userId); - std::pair GetCloudInfoFromMeta(int32_t userId); - std::pair GetCloudInfoFromServer(int32_t userId); + static std::pair GetCloudInfo(int32_t userId); + static std::pair GetCloudInfoFromMeta(int32_t userId); + static std::pair GetCloudInfoFromServer(int32_t userId); + static int32_t UpdateCloudInfoFromServer(int32_t user); std::pair GetSchemaMeta(int32_t userId, const std::string &bundleName, int32_t instanceId); std::pair GetAppSchemaFromServer(int32_t user, const std::string &bundleName); + void UpgradeSchemaMeta(int32_t user, const SchemaMeta &schemaMeta); std::map ExecuteStatistics(const std::string &storeId, const CloudInfo &cloudInfo, const SchemaMeta &schemaMeta); StatisticInfos QueryStatistics(const StoreMetaData &storeMetaData, const DistributedData::Database &database); @@ -140,17 +145,20 @@ private: Task GenTask(int32_t retry, int32_t user, Handles handles = { WORK_SUB }); Task GenSubTask(Task task, int32_t user); - void InitSubTask(const Subscription &sub); + void InitSubTask(const Subscription &sub, uint64_t minInterval = 0); void Execute(Task task); void CleanSubscription(Subscription &sub); - int32_t DoClean(CloudInfo &cloudInfo, const std::map &actions); + int32_t DoClean(const CloudInfo &cloudInfo, const std::map &actions); + void DoClean(int32_t user, const SchemaMeta &schemaMeta, int32_t action); std::pair> PreShare(const StoreInfo& storeInfo, DistributedData::GenQuery& query); std::vector ConvertCursor(std::shared_ptr cursor) const; int32_t CheckNotifyConditions(const std::string &id, const std::string &bundleName, CloudInfo &cloudInfo); - std::pair> GetDbInfoFromExtraData( + std::map> GetDbInfoFromExtraData( const DistributedData::ExtraData &extraData, const SchemaMeta &schemaMeta); std::shared_ptr GetSharingHandle(const HapInfo& hapInfo); + bool GetStoreMetaData(StoreMetaData &meta); + bool DoKvCloudSync(int32_t userId, const std::string &bundleName = ""); using SaveStrategy = int32_t (*)(const std::vector &values, const HapInfo &hapInfo); static const SaveStrategy STRATEGY_SAVERS[Strategy::STRATEGY_BUTT]; @@ -159,6 +167,7 @@ private: std::shared_ptr executor_; SyncManager syncManager_; std::mutex mutex_; + std::mutex rwMetaMutex_; TaskId subTask_ = ExecutorPool::INVALID_TASK_ID; uint64_t expireTime_ = static_cast(std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch()).count()); diff --git a/datamgr_service/services/distributeddataservice/service/cloud/cloud_value_util.cpp b/datamgr_service/services/distributeddataservice/service/cloud/cloud_value_util.cpp index 343a330d..cb1e4ea4 100644 --- a/datamgr_service/services/distributeddataservice/service/cloud/cloud_value_util.cpp +++ b/datamgr_service/services/distributeddataservice/service/cloud/cloud_value_util.cpp @@ -136,5 +136,26 @@ Status Convert(CenterCode code) } return Status::SUCCESS; } + +Status Convert(GenErr code) +{ + switch (code) { + case GenErr::E_OK: + return Status::SUCCESS; + case GenErr::E_ERROR: + return Status::ERROR; + case GenErr::E_INVALID_ARGS: + return Status::INVALID_ARGUMENT; + case GenErr::E_BLOCKED_BY_NETWORK_STRATEGY: + return Status::STRATEGY_BLOCKING; + case GenErr::E_CLOUD_DISABLED: + return Status::CLOUD_DISABLE; + case GenErr::E_NETWORK_ERROR: + return Status::NETWORK_ERROR; + default: + break; + } + return Status::ERROR; +} } // namespace::SharingUtil } // namespace OHOS::CloudData diff --git a/datamgr_service/services/distributeddataservice/service/cloud/cloud_value_util.h b/datamgr_service/services/distributeddataservice/service/cloud/cloud_value_util.h index c6640013..4b3e9cdc 100644 --- a/datamgr_service/services/distributeddataservice/service/cloud/cloud_value_util.h +++ b/datamgr_service/services/distributeddataservice/service/cloud/cloud_value_util.h @@ -19,6 +19,7 @@ #include "cloud_service.h" #include "cloud_types.h" #include "cloud/sharing_center.h" +#include "error/general_error.h" namespace OHOS::CloudData { namespace SharingUtil { @@ -29,6 +30,7 @@ using SharingRole = OHOS::DistributedData::SharingCenter::Role; using SharingResults = OHOS::DistributedData::SharingCenter::QueryResults; using CenterCode = OHOS::DistributedData::SharingCenter::SharingCode; using Status = CloudService::Status; +using GenErr = DistributedData::GeneralError; template std::vector Convert(const std::vector &data); @@ -48,6 +50,7 @@ std::vector Convert(const std::vector &participants) std::vector Convert(const std::vector &input); Status Convert(CenterCode code); +Status Convert(GenErr code); } // namespace SharingUtil } // namespace OHOS::CloudData #endif // OHOS_DISTRIBUTED_DATA_SERVICES_CLOUD_CLOUD_VALUE_UTIL_H diff --git a/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.cpp b/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.cpp index 852ae591..c52040fa 100644 --- a/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.cpp +++ b/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.cpp @@ -21,17 +21,21 @@ #include "cloud/cloud_server.h" #include "cloud/schema_meta.h" #include "cloud/sync_event.h" +#include "cloud_value_util.h" #include "device_manager_adapter.h" +#include "dfx/radar_reporter.h" #include "eventcenter/event_center.h" #include "log_print.h" #include "metadata/meta_data_manager.h" #include "sync_strategies/network_sync_strategy.h" #include "user_delegate.h" #include "utils/anonymous.h" - namespace OHOS::CloudData { using namespace DistributedData; +using namespace DistributedDataDfx; using namespace DistributedKv; +using namespace SharingUtil; +using namespace std::chrono; using Account = OHOS::DistributedKv::AccountDelegate; using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; using Defer = EventCenter::Defer; @@ -91,7 +95,7 @@ void SyncManager::SyncInfo::SetError(int32_t code) const if (async_) { GenDetails details; auto &detail = details[id_]; - detail.progress = SYNC_FINISH; + detail.progress = GenProgress::SYNC_FINISH; detail.code = code; async_(std::move(details)); } @@ -244,25 +248,17 @@ ExecutorPool::Task SyncManager::GetSyncTask(int32_t times, bool retry, RefCount times++; return [this, times, retry, keep = std::move(ref), info = std::move(syncInfo)]() mutable { activeInfos_.Erase(info.syncId_); - bool createdByDefaultUser = false; - if (info.user_ == 0) { - std::vector users; - AccountDelegate::GetInstance()->QueryUsers(users); - if (!users.empty()) { - info.user_ = users[0]; - } - createdByDefaultUser = true; - } + bool createdByDefaultUser = InitDefaultUser(info.user_); CloudInfo cloud; cloud.user = info.user_; - std::vector> cloudSyncInfos; - GetCloudSyncInfo(info, cloud, cloudSyncInfos); + auto cloudSyncInfos = GetCloudSyncInfo(info, cloud); if (cloudSyncInfos.empty()) { + ZLOGD("get cloud info failed, user: %{public}d.", cloud.user); info.SetError(E_CLOUD_DISABLED); return; } - UpdateStartSyncInfo(info, cloud, cloudSyncInfos); + UpdateStartSyncInfo(cloudSyncInfos); auto code = IsValid(info, cloud); if (code != E_OK) { for (const auto &[queryKey, syncId] : cloudSyncInfos) { @@ -275,10 +271,12 @@ ExecutorPool::Task SyncManager::GetSyncTask(int32_t times, bool retry, RefCount auto schemas = GetSchemaMeta(cloud, info.bundleName_); if (schemas.empty()) { UpdateSchema(info); - retryer(RETRY_INTERVAL, E_RETRY_TIMEOUT); - return; + schemas = GetSchemaMeta(cloud, info.bundleName_); + if (schemas.empty()) { + retryer(RETRY_INTERVAL, E_RETRY_TIMEOUT, Status::SCHEMA_INVALID); + return; + } } - Defer defer(GetSyncHandler(std::move(retryer)), CloudEvent::CLOUD_SYNC); if (createdByDefaultUser) { info.user_ = 0; @@ -298,7 +296,7 @@ std::function SyncManager::GetSyncHandler(Retryer retryer) GenAsync async = evt.GetAsyncDetail(); GenDetails details; auto &detail = details[SyncInfo::DEFAULT_ID]; - detail.progress = SYNC_FINISH; + detail.progress = GenProgress::SYNC_FINISH; StoreMetaData meta(storeInfo); meta.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta, true)) { @@ -319,24 +317,20 @@ std::function SyncManager::GetSyncHandler(Retryer retryer) } ZLOGD("database:<%{public}d:%{public}s:%{public}s> sync start", storeInfo.user, storeInfo.bundleName.c_str(), meta.GetStoreAlias().c_str()); + RadarReporter::Report( + { storeInfo.bundleName.c_str(), CLOUD_SYNC, TRIGGER_SYNC, storeInfo.syncId }, "GetSyncHandler", BEGIN); SyncParam syncParam = { evt.GetMode(), evt.GetWait(), evt.IsCompensation() }; - auto status = store->Sync({ SyncInfo::DEFAULT_ID }, *(evt.GetQuery()), evt.AutoRetry() - ? [this, retryer, storeInfo](const GenDetails &details) { - if (details.empty()) { - ZLOGE("retry, details empty"); - return; - } - int32_t code = details.begin()->second.code; - if (details.begin()->second.progress == GenProgress::SYNC_FINISH) { - QueryKey queryKey{ GetAccountId(storeInfo.user), storeInfo.bundleName, "" }; - UpdateFinishSyncInfo(queryKey, storeInfo.syncId, code); - } - retryer(GetInterval(code), code); + auto status = store->Sync({ SyncInfo::DEFAULT_ID }, *(evt.GetQuery()), + evt.AutoRetry() ? RetryCallback(storeInfo, retryer) : GetCallback(evt.GetAsyncDetail(), storeInfo), + syncParam); + if (status != E_OK) { + int32_t errCode = status + GenStore::DB_ERR_OFFSET; + RadarReporter::Report({ storeInfo.bundleName.c_str(), CLOUD_SYNC, FINISH_SYNC, storeInfo.syncId, errCode }, + "GetSyncHandler", END); + if (async) { + detail.code = status; + async(std::move(details)); } - : GetCallback(evt.GetAsyncDetail(), storeInfo), syncParam); - if (status != E_OK && async) { - detail.code = status; - async(std::move(details)); } }; } @@ -353,28 +347,31 @@ std::function SyncManager::GetClientChangeHandler() syncInfo.SetQuery(evt.GetQuery()); syncInfo.SetCompensation(evt.IsCompensation()); auto times = evt.AutoRetry() ? RETRY_TIMES - CLIENT_RETRY_TIMES : RETRY_TIMES; - auto task = GetSyncTask(times, evt.AutoRetry(), RefCount(), std::move(syncInfo)); - task(); + executor_->Execute(GetSyncTask(times, evt.AutoRetry(), RefCount(), std::move(syncInfo))); }; } SyncManager::Retryer SyncManager::GetRetryer(int32_t times, const SyncInfo &syncInfo) { if (times >= RETRY_TIMES) { - return [info = SyncInfo(syncInfo)](Duration, int32_t code) mutable { + return [info = SyncInfo(syncInfo)](Duration, int32_t code, int32_t dbCode) mutable { if (code == E_OK || code == E_SYNC_TASK_MERGED) { return true; } info.SetError(code); + RadarReporter::Report( + { info.bundleName_.c_str(), CLOUD_SYNC, FINISH_SYNC, info.syncId_, dbCode }, "GetRetryer", END); return true; }; } - return [this, times, info = SyncInfo(syncInfo)](Duration interval, int32_t code) mutable { + return [this, times, info = SyncInfo(syncInfo)](Duration interval, int32_t code, int32_t dbCode) mutable { if (code == E_OK || code == E_SYNC_TASK_MERGED) { return true; } if (code == E_NO_SPACE_FOR_ASSET || code == E_RECODE_LIMIT_EXCEEDED) { info.SetError(code); + RadarReporter::Report( + { info.bundleName_.c_str(), CLOUD_SYNC, FINISH_SYNC, info.syncId_, dbCode }, "GetRetryer", END); return true; } @@ -419,30 +416,36 @@ void SyncManager::UpdateSchema(const SyncManager::SyncInfo &syncInfo) } std::map SyncManager::GetBindInfos(const StoreMetaData &meta, - const std::vector &users, CloudInfo &info, Database &schemaDatabase, bool mustBind) + const std::vector &users, const Database &schemaDatabase) { auto instance = CloudServer::GetInstance(); if (instance == nullptr) { ZLOGD("not support cloud sync"); return {}; } - std::map bindInfos = {}; + std::map bindInfos; for (auto &activeUser : users) { if (activeUser == 0) { continue; } auto cloudDB = instance->ConnectCloudDB(meta.bundleName, activeUser, schemaDatabase); - auto assetLoader = instance->ConnectAssetLoader(meta.bundleName, activeUser, schemaDatabase); - if (mustBind && (cloudDB == nullptr || assetLoader == nullptr)) { - ZLOGE("failed, no cloud DB <0x%{public}x %{public}s<->%{public}s>", meta.tokenId, + if (cloudDB == nullptr) { + ZLOGE("failed, no cloud DB <%{public}d:0x%{public}x %{public}s<->%{public}s>", meta.tokenId, activeUser, Anonymous::Change(schemaDatabase.name).c_str(), Anonymous::Change(schemaDatabase.alias).c_str()); return {}; } - if (cloudDB != nullptr || assetLoader != nullptr) { - GeneralStore::BindInfo bindInfo((cloudDB != nullptr) ? std::move(cloudDB) : cloudDB, - (assetLoader != nullptr) ? std::move(assetLoader) : assetLoader); - bindInfos[activeUser] = bindInfo; + if (meta.storeType >= StoreMetaData::StoreType::STORE_KV_BEGIN && + meta.storeType <= StoreMetaData::StoreType::STORE_KV_END) { + bindInfos.insert_or_assign(activeUser, GeneralStore::BindInfo{ std::move(cloudDB), nullptr }); + continue; + } + auto assetLoader = instance->ConnectAssetLoader(meta.bundleName, activeUser, schemaDatabase); + if (assetLoader == nullptr) { + ZLOGE("failed, no cloud DB <%{public}d:0x%{public}x %{public}s<->%{public}s>", meta.tokenId, activeUser, + Anonymous::Change(schemaDatabase.name).c_str(), Anonymous::Change(schemaDatabase.alias).c_str()); + return {}; } + bindInfos.insert_or_assign(activeUser, GeneralStore::BindInfo{ std::move(cloudDB), std::move(assetLoader) }); } return bindInfos; } @@ -468,13 +471,12 @@ AutoCache::Store SyncManager::GetStore(const StoreMetaData &meta, int32_t user, CloudInfo info; if (user == 0) { AccountDelegate::GetInstance()->QueryForegroundUsers(users); - if (!users.empty()) { - info.user = users[0]; - } } else { - info.user = user; users.push_back(user); } + if (!users.empty()) { + info.user = users[0]; + } SchemaMeta schemaMeta; std::string schemaKey = info.GetSchemaKey(meta.bundleName, meta.instanceId); if (!MetaDataManager::GetInstance().LoadMeta(std::move(schemaKey), schemaMeta, true)) { @@ -483,19 +485,45 @@ AutoCache::Store SyncManager::GetStore(const StoreMetaData &meta, int32_t user, return nullptr; } auto dbMeta = schemaMeta.GetDataBase(meta.storeId); - std::map bindInfos = GetBindInfos(meta, users, info, dbMeta, mustBind); - store->Bind(dbMeta, bindInfos); + std::map bindInfos = GetBindInfos(meta, users, dbMeta); + if (mustBind && bindInfos.size() != users.size()) { + return nullptr; + } + GeneralStore::CloudConfig config; + if (MetaDataManager::GetInstance().LoadMeta(info.GetKey(), info, true)) { + config.maxNumber = info.maxNumber; + config.maxSize = info.maxSize; + } + store->Bind(dbMeta, bindInfos, config); } return store; } -void SyncManager::GetCloudSyncInfo(SyncInfo &info, CloudInfo &cloud, - std::vector> &cloudSyncInfos) +bool SyncManager::NeedGetCloudInfo(CloudInfo &cloud) { - if (!MetaDataManager::GetInstance().LoadMeta(cloud.GetKey(), cloud, true)) { - ZLOGE("not exist cloud metadata, user: %{public}d.", cloud.user); - return; + return (!MetaDataManager::GetInstance().LoadMeta(cloud.GetKey(), cloud, true) || !cloud.enableCloud) && + DmAdapter::GetInstance().IsNetworkAvailable() && Account::GetInstance()->IsLoginAccount(); +} + +std::vector> SyncManager::GetCloudSyncInfo(const SyncInfo &info, CloudInfo &cloud) +{ + std::vector> cloudSyncInfos; + if (NeedGetCloudInfo(cloud)) { + ZLOGI("get cloud info from server, user: %{public}d.", cloud.user); + auto instance = CloudServer::GetInstance(); + if (instance == nullptr) { + return cloudSyncInfos; + } + cloud = instance->GetServerInfo(cloud.user, false); + if (!cloud.IsValid()) { + ZLOGE("cloud is empty, user: %{public}d", cloud.user); + return cloudSyncInfos; + } + if (!MetaDataManager::GetInstance().SaveMeta(cloud.GetKey(), cloud, true)) { + ZLOGW("save cloud info fail, user: %{public}d", cloud.user); + } } + if (info.bundleName_.empty()) { for (const auto &it : cloud.apps) { QueryKey queryKey{ .accountId = cloud.id, .bundleName = it.first, .storeId = "" }; @@ -505,6 +533,17 @@ void SyncManager::GetCloudSyncInfo(SyncInfo &info, CloudInfo &cloud, QueryKey queryKey{ .accountId = cloud.id, .bundleName = info.bundleName_, .storeId = "" }; cloudSyncInfos.emplace_back(std::make_tuple(queryKey, info.syncId_)); } + return cloudSyncInfos; +} + +void SyncManager::GetLastResults( + const std::string &storeId, std::map &infos, QueryLastResults &results) +{ + for (auto &[key, info] : infos) { + if (info.code != -1) { + results.insert(std::pair(storeId, info)); + } + } } int32_t SyncManager::QueryLastSyncInfo(const std::vector &queryKeys, QueryLastResults &results) @@ -512,54 +551,40 @@ int32_t SyncManager::QueryLastSyncInfo(const std::vector &queryKeys, Q for (auto &queryKey : queryKeys) { std::string storeId = queryKey.storeId; QueryKey key{ .accountId = queryKey.accountId, .bundleName = queryKey.bundleName, .storeId = "" }; - auto it = lastSyncInfos_.find(key); - if (it == lastSyncInfos_.end()) { - return SUCCESS; - } - std::lock_guard lock(mutex_); - it->second.ForEach([&storeId, &results](uint64_t syncId, CloudSyncInfo &info) { - // -1 means sync not finish - if (info.code != -1) { - results.insert(std::pair(storeId, info)); - } - return SUCCESS; - }); + lastSyncInfos_.ComputeIfPresent( + key, [&storeId, &results](auto &key, std::map &vals) { + GetLastResults(storeId, vals, results); + return !vals.empty(); + }); } return SUCCESS; } -void SyncManager::UpdateStartSyncInfo(SyncInfo &syncInfo, CloudInfo &cloud, - std::vector> &cloudSyncInfos) +void SyncManager::UpdateStartSyncInfo(const std::vector> &cloudSyncInfos) { - CloudSyncInfo info; - info.startTime = - std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()) - .count(); - for (auto &[queryKey, syncId] : cloudSyncInfos) { - lastSyncInfos_[queryKey][syncId] = info; + int64_t startTime = duration_cast(system_clock::now().time_since_epoch()).count(); + for (const auto &[queryKey, syncId] : cloudSyncInfos) { + lastSyncInfos_.Compute(queryKey, [id = syncId, startTime](auto &, std::map &val) { + val[id] = { .startTime = startTime }; + return !val.empty(); + }); } } void SyncManager::UpdateFinishSyncInfo(const QueryKey &queryKey, uint64_t syncId, int32_t code) { - auto it = lastSyncInfos_.find(queryKey); - if (it == lastSyncInfos_.end()) { - return; - } - auto [isExist, info] = it->second.Find(syncId); - if (!isExist) { - return; - } - std::lock_guard lock(mutex_); - it->second.EraseIf([syncId](uint64_t id, CloudSyncInfo &info) { - // -1 means sync not finish - return syncId != id && info.code != -1; + lastSyncInfos_.ComputeIfPresent(queryKey, [syncId, code](auto &key, std::map &val) { + for (auto iter = val.begin(); iter != val.end();) { + if (iter->first != syncId && iter->second.code != -1) { + iter = val.erase(iter); + } else { + iter->second.finishTime = duration_cast(system_clock::now().time_since_epoch()).count(); + iter->second.code = code; + iter++; + } + } + return true; }); - info.finishTime = - std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()) - .count(); - info.code = code; - lastSyncInfos_[queryKey][syncId] = info; } std::function SyncManager::GetCallback(const GenAsync &async, @@ -590,7 +615,10 @@ std::function SyncManager::GetCallback(const Gen }; int32_t code = result.begin()->second.code; + int32_t dbCode = (result.begin()->second.dbCode == GenStore::DB_ERR_OFFSET) ? 0 : result.begin()->second.dbCode; UpdateFinishSyncInfo(queryKey, storeInfo.syncId, code); + RadarReporter::Report( + { storeInfo.bundleName.c_str(), CLOUD_SYNC, FINISH_SYNC, storeInfo.syncId, dbCode }, "GetCallback", END); }; } @@ -627,12 +655,46 @@ std::vector SyncManager::GetSchemaMeta(const CloudInfo &cloud, const void SyncManager::DoExceptionalCallback(const GenAsync &async, GenDetails &details, const StoreInfo &storeInfo) { - auto &detail = details[SyncInfo::DEFAULT_ID]; if (async) { - detail.code = E_ERROR; - async(std::move(details)); + details[SyncInfo::DEFAULT_ID].code = E_ERROR; + async(details); } QueryKey queryKey{ GetAccountId(storeInfo.user), storeInfo.bundleName, "" }; UpdateFinishSyncInfo(queryKey, storeInfo.syncId, E_ERROR); } + +bool SyncManager::InitDefaultUser(int32_t &user) +{ + if (user != 0) { + return false; + } + std::vector users; + AccountDelegate::GetInstance()->QueryUsers(users); + if (!users.empty()) { + user = users[0]; + } + return true; +} + +std::function SyncManager::RetryCallback( + const StoreInfo &storeInfo, Retryer retryer) +{ + return [this, retryer, storeInfo](const GenDetails &details) { + if (details.empty()) { + ZLOGE("retry, details empty"); + return; + } + int32_t code = details.begin()->second.code; + int32_t dbCode = details.begin()->second.dbCode; + if (details.begin()->second.progress == GenProgress::SYNC_FINISH) { + QueryKey queryKey{ GetAccountId(storeInfo.user), storeInfo.bundleName, "" }; + UpdateFinishSyncInfo(queryKey, storeInfo.syncId, code); + if (code == E_OK) { + RadarReporter::Report( + { storeInfo.bundleName.c_str(), CLOUD_SYNC, FINISH_SYNC, storeInfo.syncId }, "RetryCallback", END); + } + } + retryer(GetInterval(code), code, dbCode); + }; +} } // namespace OHOS::CloudData \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.h b/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.h index 75547f9b..e4d7b0e4 100644 --- a/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.h +++ b/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.h @@ -84,12 +84,11 @@ private: using Task = ExecutorPool::Task; using TaskId = ExecutorPool::TaskId; using Duration = ExecutorPool::Duration; - using Retryer = std::function; + using Retryer = std::function; using CloudInfo = DistributedData::CloudInfo; using StoreInfo = DistributedData::StoreInfo; using SyncStrategy = DistributedData::SyncStrategy; using SyncId = uint64_t; - using SyncIdCloudInfos = ConcurrentMap; using GeneralError = DistributedData::GeneralError; using GenProgress = DistributedData::GenProgress; using GenDetails = DistributedData::GenDetails; @@ -105,7 +104,11 @@ private: static uint64_t GenerateId(int32_t user); static ExecutorPool::Duration GetInterval(int32_t code); static std::map GetBindInfos(const StoreMetaData &meta, - const std::vector &users, CloudInfo &info, DistributedData::Database &schemaDatabase, bool mustBind); + const std::vector &users, const DistributedData::Database &schemaDatabase); + static std::string GetAccountId(int32_t user); + static std::vector> GetCloudSyncInfo(const SyncInfo &info, CloudInfo &cloud); + static std::vector GetSchemaMeta(const CloudInfo &cloud, const std::string &bundleName); + static bool NeedGetCloudInfo(CloudInfo &cloud); Task GetSyncTask(int32_t times, bool retry, RefCount ref, SyncInfo &&syncInfo); void UpdateSchema(const SyncInfo &syncInfo); std::function GetSyncHandler(Retryer retryer); @@ -114,26 +117,25 @@ private: RefCount GenSyncRef(uint64_t syncId); int32_t Compare(uint64_t syncId, int32_t user); GeneralError IsValid(SyncInfo &info, CloudInfo &cloud); - void GetCloudSyncInfo(SyncInfo &info, CloudInfo &cloud, - std::vector> &cloudSyncInfos); - void UpdateStartSyncInfo(SyncInfo &syncInfo, CloudInfo &cloud, - std::vector> &cloudSyncInfos); + void UpdateStartSyncInfo(const std::vector> &cloudSyncInfos); void UpdateFinishSyncInfo(const QueryKey &queryKey, uint64_t syncId, int32_t code); std::function GetCallback(const GenAsync &async, const StoreInfo &storeInfo); - std::string GetAccountId(int32_t user); std::function GetPostEventTask(const std::vector &schemas, CloudInfo &cloud, SyncInfo &info, bool retry); - std::vector GetSchemaMeta(const CloudInfo &cloud, const std::string &bundleName); void DoExceptionalCallback(const GenAsync &async, GenDetails &details, const StoreInfo &storeInfo); + bool InitDefaultUser(int32_t &user); + std::function RetryCallback( + const StoreInfo &storeInfo, Retryer retryer); + static void GetLastResults( + const std::string &storeId, std::map &infos, QueryLastResults &results); static std::atomic genId_; std::shared_ptr executor_; ConcurrentMap actives_; ConcurrentMap activeInfos_; std::shared_ptr syncStrategy_; - std::map lastSyncInfos_; - std::mutex mutex_; + ConcurrentMap> lastSyncInfos_; }; } // namespace OHOS::CloudData #endif // OHOS_DISTRIBUTED_DATA_SERVICES_CLOUD_SYNC_MANAGER_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/common/xcollie.cpp b/datamgr_service/services/distributeddataservice/service/common/xcollie.cpp new file mode 100644 index 00000000..2bf5bec7 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/common/xcollie.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "xcollie.h" + +namespace OHOS::DistributedData { +XCollie::XCollie(const std::string &tag, uint32_t flag, uint32_t timeoutSeconds, + std::function func, void *arg) +{ + id_ = HiviewDFX::XCollie::GetInstance().SetTimer(tag, timeoutSeconds, func, arg, flag); +} +XCollie::~XCollie() +{ + HiviewDFX::XCollie::GetInstance().CancelTimer(id_); +} +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/common/xcollie.h b/datamgr_service/services/distributeddataservice/service/common/xcollie.h new file mode 100644 index 00000000..aa773267 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/common/xcollie.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_COMMON_XCOLLIE_H +#define OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_COMMON_XCOLLIE_H + +#include +#include "xcollie/xcollie.h" + +namespace OHOS::DistributedData { +class XCollie { +public: + XCollie(const std::string &tag, uint32_t flag, uint32_t timeoutSeconds = RESTART_TIME_THRESHOLD, + std::function func = nullptr, void *arg = nullptr); + ~XCollie(); + +private: + int32_t id_ = -1; + static constexpr int32_t RESTART_TIME_THRESHOLD = 30; +}; +} // namespace OHOS::DistributedData +#endif // OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_COMMON_XCOLLIE_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/data_share/BUILD.gn b/datamgr_service/services/distributeddataservice/service/data_share/BUILD.gn index efffb4e2..ff8b1a46 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/data_share/BUILD.gn @@ -20,13 +20,13 @@ config("module_public_config") { "strategies", "common", "data", - "//third_party/json/single_include", "../../adapter/include", "../../app/src", "../../framework/include", "${datashare_path}/frameworks/native/common/include", "${datashare_path}/interfaces/inner_api/common/include", "${datashare_path}/interfaces/inner_api/consumer/include", + "../common", "../crypto/include", "../permission/include", ] @@ -37,11 +37,14 @@ group("build_module") { ohos_shared_library("data_share_service") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false } sources = [ + "${data_service_path}/service/common/xcollie.cpp", "common/app_connect_manager.cpp", "common/base64_utils.cpp", "common/bundle_mgr_proxy.cpp", @@ -82,6 +85,7 @@ ohos_shared_library("data_share_service") { "strategies/template_strategy.cpp", "subscriber_managers/published_data_subscriber_manager.cpp", "subscriber_managers/rdb_subscriber_manager.cpp", + "sys_event_subscriber.cpp", ] cflags = [ "-Wno-multichar" ] @@ -99,6 +103,7 @@ ohos_shared_library("data_share_service") { external_deps = [ "ability_base:want", "ability_base:zuri", + "ability_runtime:ability_connect_callback_stub", "ability_runtime:dataobs_manager", "ability_runtime:extension_manager", "ability_runtime:wantagent_innerkits", @@ -110,8 +115,11 @@ ohos_shared_library("data_share_service") { "common_event_service:cesfwk_innerkits", "data_share:datashare_common", "device_manager:devicemanagersdk", + "hicollie:libhicollie", "hilog:libhilog", + "hisysevent:libhisysevent", "ipc:ipc_core", + "json:nlohmann_json_static", "kv_store:distributeddb", "relational_store:native_rdb", "relational_store:rdb_data_share_adapter", diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/app_connect_manager.cpp b/datamgr_service/services/distributeddataservice/service/data_share/common/app_connect_manager.cpp index ef52670f..7c945a3e 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/app_connect_manager.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/app_connect_manager.cpp @@ -16,6 +16,7 @@ #include "app_connect_manager.h" +#include "datashare_radar_reporter.h" #include "extension_ability_manager.h" #include "log_print.h" @@ -35,6 +36,8 @@ bool AppConnectManager::Wait(const std::string &bundleName, ZLOGI("start connect %{public}s", bundleName.c_str()); result = connect(); if (!result) { + RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::PROXY_CONNECT_EXT, + RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::CONNECT_EXTENSION_ERROR); ZLOGE("connect failed %{public}s", bundleName.c_str()); blockCache_.Erase(bundleName); return false; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.cpp b/datamgr_service/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.cpp index 7a692802..a54df936 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.cpp @@ -16,6 +16,7 @@ #include "bundle_mgr_proxy.h" #include "account/account_delegate.h" +#include "datashare_radar_reporter.h" #include "if_system_ability_manager.h" #include "iservice_registry.h" #include "log_print.h" @@ -28,16 +29,9 @@ sptr BundleMgrProxy::GetBundleMgrProxy() if (proxy_ != nullptr) { return iface_cast(proxy_); } - sptr systemAbilityManager = - SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); - if (systemAbilityManager == nullptr) { - ZLOGE("Failed to get system ability mgr."); - return nullptr; - } - - proxy_ = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); + proxy_ = CheckBMS(); if (proxy_ == nullptr) { - ZLOGE("Failed to get bundle manager proxy."); + ZLOGE("BMS service not ready to complete."); return nullptr; } deathRecipient_ = new (std::nothrow)BundleMgrProxy::ServiceDeathRecipient(weak_from_this()); @@ -54,6 +48,17 @@ sptr BundleMgrProxy::GetBundleMgrProxy() return iface_cast(proxy_); } +sptr BundleMgrProxy::CheckBMS() +{ + sptr systemAbilityManager = + SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (systemAbilityManager == nullptr) { + ZLOGE("Failed to get system ability mgr."); + return nullptr; + } + return systemAbilityManager->CheckSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); +} + bool BundleMgrProxy::GetBundleInfoFromBMS( const std::string &bundleName, int32_t userId, AppExecFwk::BundleInfo &bundleInfo) { @@ -65,12 +70,16 @@ bool BundleMgrProxy::GetBundleInfoFromBMS( } auto bmsClient = GetBundleMgrProxy(); if (bmsClient == nullptr) { + RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::GET_BMS, + RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::GET_BMS_FAILED); ZLOGE("GetBundleMgrProxy is nullptr!"); return false; } bool ret = bmsClient->GetBundleInfo( bundleName, AppExecFwk::BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO, bundleInfo, userId); if (!ret) { + RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::GET_BMS, + RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::GET_BUNDLE_INFP_FAILED); ZLOGE("GetBundleInfo failed!bundleName is %{public}s, userId is %{public}d", bundleName.c_str(), userId); return false; } diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.h b/datamgr_service/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.h index 974f1a4a..a4137405 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/bundle_mgr_proxy.h @@ -29,6 +29,7 @@ public: static std::shared_ptr GetInstance(); bool GetBundleInfoFromBMS(const std::string &bundleName, int32_t userId, AppExecFwk::BundleInfo &bundleInfo); void Delete(const std::string &bundleName, int32_t userId); + sptr CheckBMS(); private: BundleMgrProxy() = default; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/db_delegate.cpp b/datamgr_service/services/distributeddataservice/service/data_share/common/db_delegate.cpp index 4a0d4777..84b9b544 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/db_delegate.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/db_delegate.cpp @@ -20,16 +20,9 @@ #include "log_print.h" #include "rdb_delegate.h" namespace OHOS::DataShare { -std::shared_ptr DBDelegate::Create(const std::string &dir, int version, bool registerFunction, - bool isEncrypt, const std::string &secretMetaKey) -{ - return std::make_shared(dir, version, registerFunction, isEncrypt, secretMetaKey); -} - std::shared_ptr DBDelegate::Create(DistributedData::StoreMetaData &metaData) { - return std::make_shared(metaData.dataDir, NO_CHANGE_VERSION, true, - metaData.isEncrypt, metaData.isEncrypt ? metaData.GetSecretKey() : ""); + return std::make_shared(metaData, NO_CHANGE_VERSION, true); } std::shared_ptr KvDBDelegate::GetInstance( @@ -38,7 +31,7 @@ std::shared_ptr KvDBDelegate::GetInstance( static std::shared_ptr delegate = nullptr; static std::mutex mutex; std::lock_guard lock(mutex); - if (delegate == nullptr || reInit) { + if ((delegate == nullptr || reInit) && executors != nullptr) { delegate = std::make_shared(dir, executors); } return delegate; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/db_delegate.h b/datamgr_service/services/distributeddataservice/service/data_share/common/db_delegate.h index 560b0185..99f13253 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/db_delegate.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/db_delegate.h @@ -31,8 +31,6 @@ namespace OHOS::DataShare { class DBDelegate { public: - static std::shared_ptr Create(const std::string &dir, int version, bool registerFunction = true, - bool isEncrypt = false, const std::string &secretMetaKey = ""); static std::shared_ptr Create(DistributedData::StoreMetaData &metaData); virtual int64_t Insert(const std::string &tableName, const DataShareValuesBucket &valuesBucket) = 0; virtual int64_t Update(const std::string &tableName, const DataSharePredicates &predicate, diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/extension_ability_manager.cpp b/datamgr_service/services/distributeddataservice/service/data_share/common/extension_ability_manager.cpp index ff316a5d..8a7c7f38 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/extension_ability_manager.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/extension_ability_manager.cpp @@ -48,6 +48,7 @@ int32_t ExtensionAbilityManager::ConnectExtension(const std::string &uri, const if (ret != E_OK) { ZLOGE("Connect ability failed, ret:%{public}d, uri:%{public}s, bundleName:%{public}s", ret, URIUtils::Anonymous(uri).c_str(), bundleName.c_str()); + connectCallbackCache_.Erase(bundleName); return E_ERROR; } return E_OK; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/rdb_delegate.cpp b/datamgr_service/services/distributeddataservice/service/data_share/common/rdb_delegate.cpp index 6eb96e30..603c9fcf 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/rdb_delegate.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/rdb_delegate.cpp @@ -16,6 +16,7 @@ #include "rdb_delegate.h" #include "crypto_manager.h" +#include "datashare_radar_reporter.h" #include "device_manager_adapter.h" #include "metadata/meta_data_manager.h" #include "metadata/store_meta_data.h" @@ -56,14 +57,14 @@ std::string RemindTimerFunc(const std::vector &args) return args[ARG_TIME]; } -RdbDelegate::RdbDelegate(const std::string &dir, int version, bool registerFunction, - bool isEncrypt, const std::string &secretMetaKey) +RdbStoreConfig RdbDelegate::GetConfig(const DistributedData::StoreMetaData &meta, bool registerFunction) { - RdbStoreConfig config(dir); + RdbStoreConfig config(meta.dataDir); config.SetCreateNecessary(false); - if (isEncrypt) { + config.SetBundleName(meta.bundleName); + if (meta.isEncrypt) { DistributedData::SecretKeyMetaData secretKeyMeta; - DistributedData::MetaDataManager::GetInstance().LoadMeta(secretMetaKey, secretKeyMeta, true); + DistributedData::MetaDataManager::GetInstance().LoadMeta(meta.GetSecretKey(), secretKeyMeta, true); std::vector decryptKey; DistributedData::CryptoManager::GetInstance().Decrypt(secretKeyMeta.sKey, decryptKey); config.SetEncryptKey(decryptKey); @@ -72,11 +73,17 @@ RdbDelegate::RdbDelegate(const std::string &dir, int version, bool registerFunct if (registerFunction) { config.SetScalarFunction("remindTimer", ARGS_SIZE, RemindTimerFunc); } + return config; +} + +RdbDelegate::RdbDelegate(const DistributedData::StoreMetaData &meta, int version, bool registerFunction) +{ + RdbStoreConfig config = GetConfig(meta, registerFunction); DefaultOpenCallback callback; store_ = RdbHelper::GetRdbStore(config, version, callback, errCode_); if (errCode_ != E_OK) { ZLOGW("GetRdbStore failed, errCode is %{public}d, dir is %{public}s", errCode_, - DistributedData::Anonymous::Change(dir).c_str()); + DistributedData::Anonymous::Change(meta.dataDir).c_str()); } } @@ -91,6 +98,8 @@ int64_t RdbDelegate::Insert(const std::string &tableName, const DataShareValuesB int ret = store_->Insert(rowId, tableName, bucket); if (ret != E_OK) { ZLOGE("Insert failed %{public}s %{public}d", tableName.c_str(), ret); + RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::PROXY_CALL_RDB, + RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::INSERT_RDB_ERROR); } return rowId; } @@ -107,6 +116,8 @@ int64_t RdbDelegate::Update( int ret = store_->Update(changeCount, bucket, predicates); if (ret != E_OK) { ZLOGE("Update failed %{public}s %{public}d", tableName.c_str(), ret); + RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::PROXY_CALL_RDB, + RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::UPDATE_RDB_ERROR); } return changeCount; } @@ -121,6 +132,8 @@ int64_t RdbDelegate::Delete(const std::string &tableName, const DataSharePredica int ret = store_->Delete(changeCount, predicates); if (ret != E_OK) { ZLOGE("Delete failed %{public}s %{public}d", tableName.c_str(), ret); + RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::PROXY_CALL_RDB, + RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::DELETE_RDB_ERROR); } return changeCount; } @@ -142,6 +155,8 @@ std::pair> RdbDelegate::Query(const std RdbPredicates rdbPredicates = RdbDataShareAdapter::RdbUtils::ToPredicates(predicates, tableName); std::shared_ptr resultSet = store_->QueryByStep(rdbPredicates, columns); if (resultSet == nullptr) { + RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::PROXY_CALL_RDB, + RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::QUERY_RDB_ERROR); ZLOGE("Query failed %{public}s", tableName.c_str()); resultSetCount--; return std::make_pair(E_ERROR, nullptr); diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/rdb_delegate.h b/datamgr_service/services/distributeddataservice/service/data_share/common/rdb_delegate.h index af9a704b..cef51a9c 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/rdb_delegate.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/rdb_delegate.h @@ -31,8 +31,7 @@ namespace OHOS::DataShare { using namespace OHOS::NativeRdb; class RdbDelegate final : public DBDelegate { public: - explicit RdbDelegate(const std::string &dir, int version, bool registerFunction, - bool isEncrypt, const std::string &secretMetaKey); + explicit RdbDelegate(const DistributedData::StoreMetaData &meta, int version, bool registerFunction); int64_t Insert(const std::string &tableName, const DataShareValuesBucket &valuesBucket) override; int64_t Update(const std::string &tableName, const DataSharePredicates &predicate, const DataShareValuesBucket &valuesBucket) override; @@ -44,6 +43,7 @@ public: std::shared_ptr QuerySql(const std::string &sql) override; private: + RdbStoreConfig GetConfig(const DistributedData::StoreMetaData &meta, bool registerFunction); static std::atomic resultSetCount; std::shared_ptr store_; int errCode_ = E_OK; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/scheduler_manager.cpp b/datamgr_service/services/distributeddataservice/service/data_share/common/scheduler_manager.cpp index 7c0c3cc6..cce99c94 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/scheduler_manager.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/scheduler_manager.cpp @@ -32,12 +32,16 @@ SchedulerManager &SchedulerManager::GetInstance() return instance; } -void SchedulerManager::Execute(const std::string &uri, const int32_t userId, const std::string &rdbDir, int version) +void SchedulerManager::Execute(const std::string &uri, const int32_t userId, const std::string &rdbDir, int version, + const std::string &bundleName) { if (!URIUtils::IsDataProxyURI(uri)) { return; } - auto delegate = DBDelegate::Create(rdbDir, version, true); + DistributedData::StoreMetaData meta; + meta.dataDir = rdbDir; + meta.bundleName = bundleName; + auto delegate = DBDelegate::Create(meta); if (delegate == nullptr) { ZLOGE("malloc fail %{public}s", DistributedData::Anonymous::Change(uri).c_str()); return; @@ -50,7 +54,10 @@ void SchedulerManager::Execute(const std::string &uri, const int32_t userId, con void SchedulerManager::Execute(const Key &key, const int32_t userId, const std::string &rdbDir, int version) { - auto delegate = DBDelegate::Create(rdbDir, version, true); + DistributedData::StoreMetaData meta; + meta.dataDir = rdbDir; + meta.bundleName = key.bundleName; + auto delegate = DBDelegate::Create(meta); if (delegate == nullptr) { ZLOGE("malloc fail %{public}s", DistributedData::Anonymous::Change(key.uri).c_str()); return; @@ -109,14 +116,15 @@ void SchedulerManager::SetTimer( auto it = timerCache_.find(key); if (it != timerCache_.end()) { ZLOGD("has current taskId, uri is %{private}s, subscriberId is %{public}" PRId64 ", bundleName is %{public}s", - key.uri.c_str(), key.subscriberId, key.bundleName.c_str()); + DistributedData::Anonymous::Change(key.uri).c_str(), key.subscriberId, key.bundleName.c_str()); auto timerId = it->second; ResetTimerTask(timerId, reminderTime); return; } auto callback = [key, dbPath, version, userId, this]() { ZLOGI("schedule notify start, uri is %{private}s, subscriberId is %{public}" PRId64 ", bundleName is " - "%{public}s", key.uri.c_str(), key.subscriberId, key.bundleName.c_str()); + "%{public}s", DistributedData::Anonymous::Change(key.uri).c_str(), + key.subscriberId, key.bundleName.c_str()); int64_t timerId = -1; { std::lock_guard lock(mutex_); diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/scheduler_manager.h b/datamgr_service/services/distributeddataservice/service/data_share/common/scheduler_manager.h index 7a3744b3..c112dcb5 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/scheduler_manager.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/scheduler_manager.h @@ -26,7 +26,8 @@ namespace OHOS::DataShare { class SchedulerManager { public: static SchedulerManager &GetInstance(); - void Execute(const std::string &uri, const int32_t userId, const std::string &rdbDir, int version); + void Execute(const std::string &uri, const int32_t userId, const std::string &rdbDir, int version, + const std::string &bundleName); void Execute(const Key &key, const int32_t userId, const std::string &rdbDir, int version); void ReExecuteAll(); void SetTimer(const std::string &dbPath, const int32_t userId, int version, const Key &key, int64_t reminderTime); diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/uri_utils.h b/datamgr_service/services/distributeddataservice/service/data_share/common/uri_utils.h index bc275365..ffd4286c 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/uri_utils.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/uri_utils.h @@ -17,8 +17,8 @@ #define DATASHARESERVICE_URI_UTILS_H #include -#include #include +#include namespace OHOS::DataShare { struct UriInfo { std::string bundleName; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_provider_config.cpp b/datamgr_service/services/distributeddataservice/service/data_share/data_provider_config.cpp index 1f3388ab..4d951df5 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_provider_config.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_provider_config.cpp @@ -113,6 +113,7 @@ int DataProviderConfig::GetFromDataProperties(const ProfileInfo &profileInfo, providerInfo_.storeName = profileInfo.storeName; providerInfo_.tableName = profileInfo.tableName; providerInfo_.type = profileInfo.type; + providerInfo_.storeMetaDataFromUri = profileInfo.storeMetaDataFromUri; if (profileInfo.tableConfig.empty()) { return E_OK; } @@ -140,7 +141,7 @@ int DataProviderConfig::GetFromExtensionProperties(const ProfileInfo &profileInf int DataProviderConfig::GetFromExtension() { if (!GetFromUriPath()) { - ZLOGE("Uri Path failed! uri:%{public}s", URIUtils::Anonymous(providerInfo_.uri).c_str()); + ZLOGE("Uri path failed! uri:%{public}s", URIUtils::Anonymous(providerInfo_.uri).c_str()); return E_URI_NOT_EXIST; } BundleInfo bundleInfo; @@ -190,10 +191,22 @@ bool DataProviderConfig::GetFromUriPath() return true; } +void DataProviderConfig::GetMetaDataFromUri() +{ + if (!providerInfo_.storeMetaDataFromUri) { + return; + } + if (!GetFromUriPath()) { + ZLOGE("Uri path failed, not change metaData from uri! uri:%{public}s", + URIUtils::Anonymous(providerInfo_.uri).c_str()); + } +} + std::pair DataProviderConfig::GetProviderInfo() { auto ret = GetFromProxyData(); if (ret == E_OK) { + GetMetaDataFromUri(); return std::make_pair(ret, providerInfo_); } ret = GetFromExtension(); diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_provider_config.h b/datamgr_service/services/distributeddataservice/service/data_share/data_provider_config.h index 43e7b869..dd2f5966 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_provider_config.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_provider_config.h @@ -44,6 +44,7 @@ public: bool singleton = false; bool hasExtension = false; bool allowEmptyPermission = false; + bool storeMetaDataFromUri = false; AccessCrossMode accessCrossMode = AccessCrossMode::USER_UNDEFINED; }; @@ -54,6 +55,7 @@ private: int GetFromExtension(); int GetFromDataProperties(const ProfileInfo &profileInfo, const std::string &moduleName); int GetFromExtensionProperties(const ProfileInfo &profileInfo, const std::string &moduleName); + void GetMetaDataFromUri(); std::pair GetBundleInfo(); enum class PATH_PARAM : int32_t { BUNDLE_NAME = 0, diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_share_db_config.cpp b/datamgr_service/services/distributeddataservice/service/data_share/data_share_db_config.cpp index ecbf2a58..d604a832 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_share_db_config.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_share_db_config.cpp @@ -20,6 +20,7 @@ #include #include "datashare_errno.h" +#include "datashare_radar_reporter.h" #include "device_manager_adapter.h" #include "extension_connect_adaptor.h" #include "log_print.h" @@ -41,26 +42,36 @@ std::pair DataShareDbConfig::QueryMetaData return std::make_pair(isCreated, metaData); } -std::tuple> DataShareDbConfig::GetDbConfig( - const std::string &uri, bool hasExtension, const std::string &bundleName, const std::string &storeName, - int32_t userId) +std::pair DataShareDbConfig::GetMetaData(const std::string &uri, + const std::string &bundleName, const std::string &storeName, int32_t userId, bool hasExtension) { auto [success, metaData] = QueryMetaData(bundleName, storeName, userId); if (!success) { if (!hasExtension) { - ZLOGE("DB not exist, bundleName:%{public}s, storeName:%{public}s, userId:%{public}d", - bundleName.c_str(), storeName.c_str(), userId); - return std::make_tuple(NativeRdb::E_DB_NOT_EXIST, metaData, nullptr); + return std::pair(NativeRdb::E_DB_NOT_EXIST, metaData); } ExtensionConnectAdaptor::TryAndWait(uri, bundleName); auto [succ, meta] = QueryMetaData(bundleName, storeName, userId); if (!succ) { - ZLOGE("Query metaData fail, bundleName:%{public}s, userId:%{public}d, uri:%{public}s", - bundleName.c_str(), userId, URIUtils::Anonymous(uri).c_str()); - return std::make_tuple(NativeRdb::E_DB_NOT_EXIST, meta, nullptr); + return std::pair(NativeRdb::E_DB_NOT_EXIST, meta); } metaData = std::move(meta); } + return std::pair(E_OK, metaData); +} + +std::tuple> DataShareDbConfig::GetDbConfig( + const std::string &uri, bool hasExtension, const std::string &bundleName, const std::string &storeName, + int32_t userId) +{ + auto [errCode, metaData] = GetMetaData(uri, bundleName, storeName, userId, hasExtension); + if (errCode != E_OK) { + ZLOGE("DB not exist,bundleName:%{public}s,storeName:%{public}s,user:%{public}d,err:%{public}d,uri:%{public}s", + bundleName.c_str(), storeName.c_str(), userId, errCode, URIUtils::Anonymous(uri).c_str()); + RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::PROXY_MATEDATA_EXISTS, + RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::META_DATA_NOT_EXISTS); + return std::make_tuple(errCode, metaData, nullptr); + } auto dbDelegate = DBDelegate::Create(metaData); if (dbDelegate == nullptr) { ZLOGE("Create delegate fail, bundleName:%{public}s, userId:%{public}d, uri:%{public}s", diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_share_db_config.h b/datamgr_service/services/distributeddataservice/service/data_share/data_share_db_config.h index 4805870f..441e9cfe 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_share_db_config.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_share_db_config.h @@ -31,6 +31,8 @@ public: std::tuple> GetDbConfig( const std::string &uri, bool hasExtension, const std::string &bundleName, const std::string &storeName, int32_t userId); + std::pair GetMetaData(const std::string &uri, + const std::string &bundleName, const std::string &storeName, int32_t userId, bool hasExtension); private: static std::pair QueryMetaData(const std::string &bundleName, const std::string &storeName, int32_t userId); diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_share_profile_config.cpp b/datamgr_service/services/distributeddataservice/service/data_share/data_share_profile_config.cpp index 244829ad..f179186d 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_share_profile_config.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_share_profile_config.cpp @@ -52,6 +52,20 @@ bool Config::Unmarshal(const json &node) return ret; } +bool LaunchInfo::Marshal(json &node) const +{ + SetValue(node[GET_NAME(storeId)], storeId); + SetValue(node[GET_NAME(tableNames)], tableNames); + return true; +} + +bool LaunchInfo::Unmarshal(const json &node) +{ + GetValue(node, GET_NAME(storeId), storeId); + GetValue(node, GET_NAME(tableNames), tableNames); + return true; +} + bool ProfileInfo::Marshal(json &node) const { SetValue(node[GET_NAME(tableConfig)], tableConfig); @@ -59,6 +73,8 @@ bool ProfileInfo::Marshal(json &node) const SetValue(node[GET_NAME(path)], storeName + SEPARATOR + tableName); SetValue(node[GET_NAME(scope)], scope); SetValue(node[GET_NAME(type)], type); + SetValue(node[GET_NAME(launchInfos)], launchInfos); + SetValue(node[GET_NAME(storeMetaDataFromUri)], storeMetaDataFromUri); return true; } @@ -68,6 +84,8 @@ bool ProfileInfo::Unmarshal(const json &node) GetValue(node, GET_NAME(isSilentProxyEnable), isSilentProxyEnable); GetValue(node, GET_NAME(scope), scope); GetValue(node, GET_NAME(type), type); + GetValue(node, GET_NAME(launchInfos), launchInfos); + GetValue(node, GET_NAME(storeMetaDataFromUri), storeMetaDataFromUri); std::string path; auto ret = GetValue(node, GET_NAME(path), path); if (ret) { diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_share_profile_config.h b/datamgr_service/services/distributeddataservice/service/data_share/data_share_profile_config.h index 1cb90ace..fb5e631a 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_share_profile_config.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_share_profile_config.h @@ -36,6 +36,13 @@ struct Config final : public DistributedData::Serializable { bool Unmarshal(const json &node) override; }; +struct LaunchInfo final : public DistributedData::Serializable { + std::string storeId = ""; + std::vector tableNames; + bool Marshal(json &node) const override; + bool Unmarshal(const json &node) override; +}; + struct ProfileInfo : public DistributedData::Serializable { std::vector tableConfig; bool isSilentProxyEnable = true; @@ -43,6 +50,8 @@ struct ProfileInfo : public DistributedData::Serializable { std::string tableName; std::string scope = "module"; std::string type = "rdb"; + std::vector launchInfos; + bool storeMetaDataFromUri = false; bool Marshal(json &node) const override; bool Unmarshal(const json &node) override; }; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.cpp index 11003a98..57e06390 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.cpp @@ -26,22 +26,31 @@ #include "common_event_manager.h" #include "common_event_support.h" #include "data_ability_observer_interface.h" +#include "data_share_profile_config.h" #include "dataobs_mgr_client.h" #include "datashare_errno.h" +#include "datashare_radar_reporter.h" +#include "device_manager_adapter.h" #include "datashare_template.h" #include "directory/directory_manager.h" +#include "eventcenter/event_center.h" +#include "extension_connect_adaptor.h" #include "dump/dump_manager.h" #include "extension_ability_manager.h" #include "hap_token_info.h" #include "ipc_skeleton.h" #include "log_print.h" +#include "metadata/auto_launch_meta_data.h" +#include "metadata/meta_data_manager.h" #include "matching_skills.h" #include "permit_delegate.h" #include "rdb_helper.h" #include "scheduler_manager.h" #include "subscriber_managers/published_data_subscriber_manager.h" +#include "sys_event_subscriber.h" #include "template_data.h" #include "utils/anonymous.h" +#include "xcollie.h" namespace OHOS::DataShare { using FeatureSystem = DistributedData::FeatureSystem; @@ -63,7 +72,8 @@ DataShareServiceImpl::Factory::~Factory() {} int32_t DataShareServiceImpl::Insert(const std::string &uri, const DataShareValuesBucket &valuesBucket) { ZLOGD("Insert enter."); - if (!IsSilentProxyEnable(uri)) { + XCollie xcollie(__FUNCTION__, HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY); + if (GetSilentProxyStatus(uri, false) != E_OK) { ZLOGW("silent proxy disable, %{public}s", URIUtils::Anonymous(uri).c_str()); return ERROR; } @@ -81,15 +91,19 @@ int32_t DataShareServiceImpl::Insert(const std::string &uri, const DataShareValu bool DataShareServiceImpl::NotifyChange(const std::string &uri) { + RadarReporter::RadarReport report(RadarReporter::NOTIFY_OBSERVER_DATA_CHANGE, + RadarReporter::NOTIFY_DATA_CHANGE, __FUNCTION__); auto obsMgrClient = AAFwk::DataObsMgrClient::GetInstance(); if (obsMgrClient == nullptr) { ZLOGE("obsMgrClient is nullptr"); + report.SetError(RadarReporter::DATA_OBS_EMPTY_ERROR); return false; } ErrCode ret = obsMgrClient->NotifyChange(Uri(uri)); if (ret != ERR_OK) { ZLOGE("obsMgrClient->NotifyChange error return %{public}d", ret); + report.SetError(RadarReporter::NOTIFY_ERROR); return false; } return true; @@ -99,7 +113,8 @@ int32_t DataShareServiceImpl::Update(const std::string &uri, const DataSharePred const DataShareValuesBucket &valuesBucket) { ZLOGD("Update enter."); - if (!IsSilentProxyEnable(uri)) { + XCollie xcollie(__FUNCTION__, HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY); + if (GetSilentProxyStatus(uri, false) != E_OK) { ZLOGW("silent proxy disable, %{public}s", URIUtils::Anonymous(uri).c_str()); return ERROR; } @@ -117,7 +132,8 @@ int32_t DataShareServiceImpl::Update(const std::string &uri, const DataSharePred int32_t DataShareServiceImpl::Delete(const std::string &uri, const DataSharePredicates &predicate) { - if (!IsSilentProxyEnable(uri)) { + XCollie xcollie(__FUNCTION__, HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY); + if (GetSilentProxyStatus(uri, false) != E_OK) { ZLOGW("silent proxy disable, %{public}s", URIUtils::Anonymous(uri).c_str()); return ERROR; } @@ -137,7 +153,8 @@ std::shared_ptr DataShareServiceImpl::Query(const std::strin const DataSharePredicates &predicates, const std::vector &columns, int &errCode) { ZLOGD("Query enter."); - if (!IsSilentProxyEnable(uri)) { + XCollie xcollie(__FUNCTION__, HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY); + if (GetSilentProxyStatus(uri, false) != E_OK) { ZLOGW("silent proxy disable, %{public}s", URIUtils::Anonymous(uri).c_str()); return nullptr; } @@ -183,8 +200,8 @@ int32_t DataShareServiceImpl::DelTemplate(const std::string &uri, const int64_t ZLOGE("get bundleName error, %{public}s", DistributedData::Anonymous::Change(uri).c_str()); return ERROR; } - ZLOGI("Delete template, uri %{private}s, subscriberId %{public}" PRIi64 ", bundleName %{public}s.", uri.c_str(), - subscriberId, tpltId.bundleName_.c_str()); + ZLOGI("Delete template, uri %{private}s, subscriberId %{public}" PRIi64 ", bundleName %{public}s.", + DistributedData::Anonymous::Change(uri).c_str(), subscriberId, tpltId.bundleName_.c_str()); return templateStrategy_.Execute(context, [&uri, &tpltId, &context]() -> int32_t { return TemplateManager::GetInstance().Delete( Key(uri, tpltId.subscriberId_, tpltId.bundleName_), context->currentUserId); @@ -481,10 +498,91 @@ int32_t DataShareServiceImpl::OnBind(const BindInfo &binderInfo) KvDBDelegate::GetInstance(false, saveMeta.dataDir, binderInfo.executors); SchedulerManager::GetInstance().SetExecutorPool(binderInfo.executors); ExtensionAbilityManager::GetInstance().SetExecutorPool(binderInfo.executors); + InitSubEvent(); SubscribeTimeChanged(); + SubscribeChange(); + ZLOGI("end"); return E_OK; } +void DataShareServiceImpl::SubscribeChange() +{ + EventCenter::GetInstance().Subscribe(RemoteChangeEvent::RDB_META_SAVE, [this](const Event &event) { + auto &evt = static_cast(event); + auto dataInfo = evt.GetDataInfo(); + SaveLaunchInfo(dataInfo.bundleName, dataInfo.userId, dataInfo.deviceId); + }); + EventCenter::GetInstance().Subscribe(RemoteChangeEvent::DATA_CHANGE, [this](const Event &event) { + AutoLaunch(event); + }); +} + +void DataShareServiceImpl::SaveLaunchInfo(const std::string &bundleName, const std::string &userId, + const std::string &deviceId) +{ + std::map profileInfos; + if (!DataShareProfileConfig::GetProfileInfo(bundleName, std::stoi(userId), profileInfos)) { + ZLOGE("Get profileInfo failed."); + return; + } + if (profileInfos.empty()) { + return; + } + std::map maps; + for (auto &[uri, value] : profileInfos) { + if (uri.find(EXT_URI_SCHEMA) == std::string::npos) { + continue; + } + std::string extUri = uri; + extUri.insert(strlen(EXT_URI_SCHEMA), "/"); + for (const auto &launchInfo : value.launchInfos) { + AutoLaunchMetaData &autoLaunchMetaData = maps[launchInfo.storeId]; + autoLaunchMetaData.datas.emplace(extUri, launchInfo.tableNames); + } + } + StoreMetaData meta = MakeMetaData(bundleName, userId, deviceId); + for (const auto &[storeId, value] : maps) { + meta.storeId = storeId; + MetaDataManager::GetInstance().SaveMeta(meta.GetAutoLaunchKey(), value, true); + } +} + +void DataShareServiceImpl::AutoLaunch(const Event &event) +{ + auto &evt = static_cast(event); + auto dataInfo = evt.GetDataInfo(); + StoreMetaData meta = MakeMetaData(dataInfo.bundleName, dataInfo.userId, dataInfo.deviceId, dataInfo.storeId); + AutoLaunchMetaData autoLaunchMetaData; + if (!MetaDataManager::GetInstance().LoadMeta(std::move(meta.GetAutoLaunchKey()), autoLaunchMetaData, true)) { + return; + } + if (autoLaunchMetaData.datas.empty()) { + return; + } + std::vector uris; + for (const auto &[uri, metaTables] : autoLaunchMetaData.datas) { + for (const auto &table : dataInfo.tables) + if (std::find(metaTables.begin(), metaTables.end(), table) != metaTables.end()) { + uris.emplace_back(uri); + break; + } + } + for (const auto &uri : uris) { + ExtensionConnectAdaptor::TryAndWait(uri, dataInfo.bundleName); + } +} + +StoreMetaData DataShareServiceImpl::MakeMetaData(const std::string &bundleName, const std::string &userId, + const std::string &deviceId, const std::string storeId) +{ + StoreMetaData meta; + meta.user = userId; + meta.storeId = storeId; + meta.deviceId = deviceId; + meta.bundleName = bundleName; + return meta; +} + void DataShareServiceImpl::OnConnectDone() { std::string callerBundleName; @@ -503,6 +601,7 @@ int32_t DataShareServiceImpl::DataShareStatic::OnAppUninstall(const std::string PublishedData::ClearAging(); TemplateData::Delete(bundleName, user); NativeRdb::RdbHelper::ClearCache(); + BundleMgrProxy::GetInstance()->Delete(bundleName, user); return E_OK; } @@ -515,6 +614,22 @@ int32_t DataShareServiceImpl::OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, return E_OK; } +int32_t DataShareServiceImpl::DataShareStatic::OnAppUpdate(const std::string &bundleName, int32_t user, + int32_t index) +{ + ZLOGI("%{public}s updated", bundleName.c_str()); + BundleMgrProxy::GetInstance()->Delete(bundleName, user); + std::string prefix = StoreMetaData::GetPrefix( + { DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid, std::to_string(user), "default", bundleName }); + std::vector storeMetaData; + MetaDataManager::GetInstance().LoadMeta(prefix, storeMetaData, true); + for (auto &meta : storeMetaData) { + MetaDataManager::GetInstance().DelMeta(meta.GetAutoLaunchKey(), true); + } + SaveLaunchInfo(bundleName, std::to_string(user), DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid); + return E_OK; +} + int32_t DataShareServiceImpl::OnAppUninstall(const std::string &bundleName, int32_t user, int32_t index) { ZLOGI("AppUninstall user=%{public}d, index=%{public}d, bundleName=%{public}s", @@ -607,6 +722,8 @@ int32_t DataShareServiceImpl::OnInitialize() { RegisterDataShareServiceInfo(); RegisterHandler(); + SetServiceReady(); + ZLOGI("Init dataShare service end"); return 0; } @@ -620,19 +737,28 @@ int32_t DataShareServiceImpl::EnableSilentProxy(const std::string &uri, bool ena uint32_t callerTokenId = IPCSkeleton::GetCallingTokenID(); bool ret = dataShareSilentConfig_.EnableSilentProxy(callerTokenId, uri, enable); if (!ret) { - ZLOGE("Enable silent proxy err, %{public}s", DistributedData::Anonymous::Change(uri).c_str()); + ZLOGE("Enable silent proxy err, %{public}s", URIUtils::Anonymous(uri).c_str()); return ERROR; } return E_OK; } -bool DataShareServiceImpl::IsSilentProxyEnable(const std::string &uri) +int32_t DataShareServiceImpl::GetSilentProxyStatus(const std::string &uri, bool isCreateHelper) { + XCollie xcollie(__FUNCTION__, HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY); uint32_t callerTokenId = IPCSkeleton::GetCallingTokenID(); + if (isCreateHelper) { + auto errCode = GetBMSAndMetaDataStatus(uri, callerTokenId); + if (errCode != E_OK) { + ZLOGE("BMS or metaData not ready to complete, token:0x%{public}x, uri:%{public}s", + callerTokenId, URIUtils::Anonymous(uri).c_str()); + return errCode; + } + } int32_t currentUserId = DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(callerTokenId); UriInfo uriInfo; if (!URIUtils::GetInfoFromURI(uri, uriInfo)) { - return true; + return E_OK; } std::string calledBundleName = uriInfo.bundleName; uint32_t calledTokenId = Security::AccessToken::AccessTokenKit::GetHapTokenID(currentUserId, calledBundleName, 0); @@ -641,14 +767,16 @@ bool DataShareServiceImpl::IsSilentProxyEnable(const std::string &uri) } auto success = dataShareSilentConfig_.IsSilentProxyEnable(calledTokenId, currentUserId, calledBundleName, uri); if (!success) { - ZLOGW("silent proxy disable, %{public}s", DistributedData::Anonymous::Change(uri).c_str()); + ZLOGW("silent proxy disable, %{public}s", URIUtils::Anonymous(uri).c_str()); + return E_SILENT_PROXY_DISABLE; } - return success; + return E_OK; } int32_t DataShareServiceImpl::RegisterObserver(const std::string &uri, const sptr &remoteObj) { + XCollie xcollie(__FUNCTION__, HiviewDFX::XCOLLIE_FLAG_LOG); auto callerTokenId = IPCSkeleton::GetCallingTokenID(); DataProviderConfig providerConfig(uri, callerTokenId); auto [errCode, providerInfo] = providerConfig.GetProviderInfo(); @@ -657,7 +785,8 @@ int32_t DataShareServiceImpl::RegisterObserver(const std::string &uri, errCode, URIUtils::Anonymous(providerInfo.uri).c_str()); } if (!providerInfo.allowEmptyPermission && providerInfo.readPermission.empty()) { - ZLOGE("reject permission, tokenId:0x%{public}x, uri:%{public}s", callerTokenId, uri.c_str()); + ZLOGE("reject permission, tokenId:0x%{public}x, uri:%{public}s", + callerTokenId, URIUtils::Anonymous(uri).c_str()); } if (!providerInfo.readPermission.empty() && !PermitDelegate::VerifyPermission(providerInfo.readPermission, callerTokenId)) { @@ -680,6 +809,7 @@ int32_t DataShareServiceImpl::RegisterObserver(const std::string &uri, int32_t DataShareServiceImpl::UnregisterObserver(const std::string &uri, const sptr &remoteObj) { + XCollie xcollie(__FUNCTION__, HiviewDFX::XCOLLIE_FLAG_LOG); auto callerTokenId = IPCSkeleton::GetCallingTokenID(); DataProviderConfig providerConfig(uri, callerTokenId); auto [errCode, providerInfo] = providerConfig.GetProviderInfo(); @@ -688,7 +818,8 @@ int32_t DataShareServiceImpl::UnregisterObserver(const std::string &uri, errCode, URIUtils::Anonymous(providerInfo.uri).c_str()); } if (!providerInfo.allowEmptyPermission && providerInfo.readPermission.empty()) { - ZLOGE("reject permission, tokenId:0x%{public}x, uri:%{public}s", callerTokenId, uri.c_str()); + ZLOGE("reject permission, tokenId:0x%{public}x, uri:%{public}s", + callerTokenId, URIUtils::Anonymous(uri).c_str()); } if (!providerInfo.readPermission.empty() && !PermitDelegate::VerifyPermission(providerInfo.readPermission, callerTokenId)) { @@ -716,12 +847,16 @@ int32_t DataShareServiceImpl::Execute(const std::string &uri, const int32_t toke if (errCode != E_OK) { ZLOGE("Provider failed! token:0x%{public}x,ret:%{public}d,uri:%{public}s", tokenId, errCode, URIUtils::Anonymous(provider.uri).c_str()); + RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::PROXY_GET_SUPPLIER, + RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::SUPPLIER_ERROR); return errCode; } std::string permission = isRead ? provider.readPermission : provider.writePermission; if (!permission.empty() && !PermitDelegate::VerifyPermission(permission, tokenId)) { ZLOGE("Permission denied! token:0x%{public}x, permission:%{public}s, uri:%{public}s", tokenId, permission.c_str(), URIUtils::Anonymous(provider.uri).c_str()); + RADAR_REPORT(__FUNCTION__, RadarReporter::SILENT_ACCESS, RadarReporter::PROXY_PERMISSION, + RadarReporter::FAILED, RadarReporter::ERROR_CODE, RadarReporter::PERMISSION_DENIED_ERROR); return ERROR_PERMISSION_DENIED; } DataShareDbConfig dbConfig; @@ -736,4 +871,45 @@ int32_t DataShareServiceImpl::Execute(const std::string &uri, const int32_t toke } return callback(provider, metaData, dbDelegate); } + +int32_t DataShareServiceImpl::GetBMSAndMetaDataStatus(const std::string &uri, const int32_t tokenId) +{ + DataProviderConfig calledConfig(uri, tokenId); + auto [errCode, calledInfo] = calledConfig.GetProviderInfo(); + if (errCode == E_URI_NOT_EXIST) { + ZLOGE("Create helper invalid uri, token:0x%{public}x, uri:%{public}s", tokenId, + URIUtils::Anonymous(calledInfo.uri).c_str()); + return E_OK; + } + if (errCode != E_OK) { + ZLOGE("CalledInfo failed! token:0x%{public}x,ret:%{public}d,uri:%{public}s", tokenId, + errCode, URIUtils::Anonymous(calledInfo.uri).c_str()); + return E_BMS_NOT_READY; + } + DataShareDbConfig dbConfig; + auto [code, metaData] = dbConfig.GetMetaData(calledInfo.uri, calledInfo.bundleName, + calledInfo.storeName, calledInfo.singleton ? 0 : calledInfo.currentUserId, calledInfo.hasExtension); + if (code != E_OK) { + ZLOGE("Get metaData fail,bundleName:%{public}s,tableName:%{public}s,tokenId:0x%{public}x, uri:%{public}s", + calledInfo.bundleName.c_str(), calledInfo.tableName.c_str(), tokenId, + URIUtils::Anonymous(calledInfo.uri).c_str()); + return E_METADATA_NOT_EXISTS; + } + return E_OK; +} + +void DataShareServiceImpl::InitSubEvent() +{ + EventFwk::MatchingSkills matchingSkills; + matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_BUNDLE_SCAN_FINISHED); + EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills); + subscribeInfo.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON); + auto sysEventSubscriber = std::make_shared(subscribeInfo); + if (!EventFwk::CommonEventManager::SubscribeCommonEvent(sysEventSubscriber)) { + ZLOGE("Subscribe sys event failed."); + } + if (BundleMgrProxy::GetInstance()->CheckBMS() != nullptr) { + sysEventSubscriber->OnBMSReady(); + } +} } // namespace OHOS::DataShare diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.h b/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.h index 8ec5cc28..261f51c7 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_impl.h @@ -23,6 +23,7 @@ #include "bundle_mgr_proxy.h" #include "common_event_subscribe_info.h" #include "common_event_subscriber.h" +#include "changeevent/remote_change_event.h" #include "data_proxy_observer.h" #include "data_provider_config.h" #include "data_share_db_config.h" @@ -30,6 +31,7 @@ #include "data_share_silent_config.h" #include "datashare_template.h" #include "db_delegate.h" +#include "eventcenter/event.h" #include "feature/static_acts.h" #include "get_data_strategy.h" #include "publish_strategy.h" @@ -82,7 +84,7 @@ public: void DumpDataShareServiceInfo(int fd, std::map> ¶ms); int32_t OnInitialize() override; int32_t EnableSilentProxy(const std::string &uri, bool enable) override; - bool IsSilentProxyEnable(const std::string &uri) override; + int32_t GetSilentProxyStatus(const std::string &uri, bool isCreateHelper) override; int32_t RegisterObserver(const std::string &uri, const sptr &remoteObj) override; int32_t UnregisterObserver(const std::string &uri, const sptr &remoteObj) override; @@ -92,6 +94,7 @@ private: public: ~DataShareStatic() override {}; int32_t OnAppUninstall(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; }; class Factory { public: @@ -113,10 +116,19 @@ private: bool NotifyChange(const std::string &uri); bool GetCallerBundleName(std::string &bundleName); int32_t Execute(const std::string &uri, const int32_t tokenId, bool isRead, ExecuteCallback callback); + int32_t GetBMSAndMetaDataStatus(const std::string &uri, const int32_t tokenId); + void InitSubEvent(); + void AutoLaunch(const DistributedData::Event &event); + void SubscribeChange(); + static void SaveLaunchInfo(const std::string &bundleName, const std::string &userId, + const std::string &deviceId); + static DistributedData::StoreMetaData MakeMetaData(const std::string &bundleName, const std::string &userId, + const std::string &deviceId, const std::string storeId = ""); static Factory factory_; static constexpr int32_t ERROR = -1; static constexpr int32_t ERROR_PERMISSION_DENIED = -2; static constexpr const char *PROXY_URI_SCHEMA = "datashareproxy"; + static constexpr const char *EXT_URI_SCHEMA = "datashare://"; PublishStrategy publishStrategy_; GetDataStrategy getDataStrategy_; SubscribeStrategy subscribeStrategy_; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_stub.cpp b/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_stub.cpp index 3e9f0ca7..acad4229 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_stub.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_stub.cpp @@ -38,7 +38,7 @@ bool DataShareServiceStub::CheckInterfaceToken(MessageParcel &data) return true; } -int32_t DataShareServiceStub::OnRemoteInsert(MessageParcel &data, MessageParcel &reply) +int32_t DataShareServiceStub::OnInsert(MessageParcel &data, MessageParcel &reply) { std::string uri; DataShareValuesBucket bucket; @@ -55,7 +55,7 @@ int32_t DataShareServiceStub::OnRemoteInsert(MessageParcel &data, MessageParcel return 0; } -int32_t DataShareServiceStub::OnRemoteUpdate(MessageParcel &data, MessageParcel &reply) +int32_t DataShareServiceStub::OnUpdate(MessageParcel &data, MessageParcel &reply) { std::string uri; DataSharePredicates predicate; @@ -73,7 +73,7 @@ int32_t DataShareServiceStub::OnRemoteUpdate(MessageParcel &data, MessageParcel return 0; } -int32_t DataShareServiceStub::OnRemoteDelete(MessageParcel &data, MessageParcel &reply) +int32_t DataShareServiceStub::OnDelete(MessageParcel &data, MessageParcel &reply) { std::string uri; DataSharePredicates predicate; @@ -89,7 +89,7 @@ int32_t DataShareServiceStub::OnRemoteDelete(MessageParcel &data, MessageParcel return 0; } -int32_t DataShareServiceStub::OnRemoteQuery(MessageParcel &data, MessageParcel &reply) +int32_t DataShareServiceStub::OnQuery(MessageParcel &data, MessageParcel &reply) { std::string uri; DataSharePredicates predicate; @@ -108,7 +108,7 @@ int32_t DataShareServiceStub::OnRemoteQuery(MessageParcel &data, MessageParcel & return 0; } -int32_t DataShareServiceStub::OnRemoteAddTemplate(MessageParcel &data, MessageParcel &reply) +int32_t DataShareServiceStub::OnAddTemplate(MessageParcel &data, MessageParcel &reply) { std::string uri; int64_t subscriberId; @@ -125,7 +125,7 @@ int32_t DataShareServiceStub::OnRemoteAddTemplate(MessageParcel &data, MessagePa return 0; } -int32_t DataShareServiceStub::OnRemoteDelTemplate(MessageParcel &data, MessageParcel &reply) +int32_t DataShareServiceStub::OnDelTemplate(MessageParcel &data, MessageParcel &reply) { std::string uri; int64_t subscriberId; @@ -141,7 +141,7 @@ int32_t DataShareServiceStub::OnRemoteDelTemplate(MessageParcel &data, MessagePa return 0; } -int32_t DataShareServiceStub::OnRemotePublish(MessageParcel &data, MessageParcel &reply) +int32_t DataShareServiceStub::OnPublish(MessageParcel &data, MessageParcel &reply) { Data publishData; std::string bundleName; @@ -157,7 +157,7 @@ int32_t DataShareServiceStub::OnRemotePublish(MessageParcel &data, MessageParcel return 0; } -int32_t DataShareServiceStub::OnRemoteGetData(MessageParcel &data, MessageParcel &reply) +int32_t DataShareServiceStub::OnGetData(MessageParcel &data, MessageParcel &reply) { std::string bundleName; if (!ITypesUtil::Unmarshal(data, bundleName)) { @@ -174,7 +174,7 @@ int32_t DataShareServiceStub::OnRemoteGetData(MessageParcel &data, MessageParcel return 0; } -int32_t DataShareServiceStub::OnRemoteSubscribeRdbData(MessageParcel &data, MessageParcel &reply) +int32_t DataShareServiceStub::OnSubscribeRdbData(MessageParcel &data, MessageParcel &reply) { std::vector uris; TemplateId templateId; @@ -196,7 +196,7 @@ int32_t DataShareServiceStub::OnRemoteSubscribeRdbData(MessageParcel &data, Mess return 0; } -int32_t DataShareServiceStub::OnRemoteUnsubscribeRdbData(MessageParcel &data, MessageParcel &reply) +int32_t DataShareServiceStub::OnUnsubscribeRdbData(MessageParcel &data, MessageParcel &reply) { std::vector uris; TemplateId templateId; @@ -212,7 +212,7 @@ int32_t DataShareServiceStub::OnRemoteUnsubscribeRdbData(MessageParcel &data, Me return 0; } -int32_t DataShareServiceStub::OnRemoteEnableRdbSubs(MessageParcel &data, MessageParcel &reply) +int32_t DataShareServiceStub::OnEnableRdbSubs(MessageParcel &data, MessageParcel &reply) { std::vector uris; TemplateId templateId; @@ -228,7 +228,7 @@ int32_t DataShareServiceStub::OnRemoteEnableRdbSubs(MessageParcel &data, Message return 0; } -int32_t DataShareServiceStub::OnRemoteDisableRdbSubs(MessageParcel &data, MessageParcel &reply) +int32_t DataShareServiceStub::OnDisableRdbSubs(MessageParcel &data, MessageParcel &reply) { std::vector uris; TemplateId templateId; @@ -244,7 +244,7 @@ int32_t DataShareServiceStub::OnRemoteDisableRdbSubs(MessageParcel &data, Messag return 0; } -int32_t DataShareServiceStub::OnRemoteSubscribePublishedData(MessageParcel &data, MessageParcel &reply) +int32_t DataShareServiceStub::OnSubscribePublishedData(MessageParcel &data, MessageParcel &reply) { std::vector uris; int64_t subscriberId; @@ -265,7 +265,7 @@ int32_t DataShareServiceStub::OnRemoteSubscribePublishedData(MessageParcel &data return 0; } -int32_t DataShareServiceStub::OnRemoteUnsubscribePublishedData(MessageParcel &data, MessageParcel &reply) +int32_t DataShareServiceStub::OnUnsubscribePublishedData(MessageParcel &data, MessageParcel &reply) { std::vector uris; int64_t subscriberId; @@ -281,7 +281,7 @@ int32_t DataShareServiceStub::OnRemoteUnsubscribePublishedData(MessageParcel &da return 0; } -int32_t DataShareServiceStub::OnRemoteEnablePubSubs(MessageParcel &data, MessageParcel &reply) +int32_t DataShareServiceStub::OnEnablePubSubs(MessageParcel &data, MessageParcel &reply) { std::vector uris; int64_t subscriberId; @@ -297,7 +297,7 @@ int32_t DataShareServiceStub::OnRemoteEnablePubSubs(MessageParcel &data, Message return 0; } -int32_t DataShareServiceStub::OnRemoteDisablePubSubs(MessageParcel &data, MessageParcel &reply) +int32_t DataShareServiceStub::OnDisablePubSubs(MessageParcel &data, MessageParcel &reply) { std::vector uris; int64_t subscriberId; @@ -313,7 +313,7 @@ int32_t DataShareServiceStub::OnRemoteDisablePubSubs(MessageParcel &data, Messag return 0; } -int32_t DataShareServiceStub::OnRemoteNotifyConnectDone(MessageParcel &data, MessageParcel &reply) +int32_t DataShareServiceStub::OnNotifyConnectDone(MessageParcel &data, MessageParcel &reply) { OnConnectDone(); return 0; @@ -321,8 +321,15 @@ int32_t DataShareServiceStub::OnRemoteNotifyConnectDone(MessageParcel &data, Mes int DataShareServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply) { + int tryTimes = TRY_TIMES; + while (!isReady_.load() && tryTimes > 0) { + tryTimes--; + std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME)); + } auto callingPid = IPCSkeleton::GetCallingPid(); - ZLOGD("code:%{public}u, callingPid:%{public}d", code, callingPid); + if (code != DATA_SHARE_SERVICE_CMD_QUERY) { + ZLOGI("code:%{public}u, callingPid:%{public}d", code, callingPid); + } if (!CheckInterfaceToken(data)) { return DATA_SHARE_ERROR; } @@ -341,7 +348,7 @@ int DataShareServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, Me return res; } -int32_t DataShareServiceStub::OnRemoteNotifyObserver(MessageParcel &data, MessageParcel &reply) +int32_t DataShareServiceStub::OnNotifyObserver(MessageParcel &data, MessageParcel &reply) { std::string uri; if (!ITypesUtil::Unmarshal(data, uri)) { @@ -352,7 +359,7 @@ int32_t DataShareServiceStub::OnRemoteNotifyObserver(MessageParcel &data, Messag return 0; } -int32_t DataShareServiceStub::OnRemoteSetSilentSwitch(MessageParcel &data, MessageParcel &reply) +int32_t DataShareServiceStub::OnSetSilentSwitch(MessageParcel &data, MessageParcel &reply) { std::string uri; bool enable = false; @@ -368,14 +375,14 @@ int32_t DataShareServiceStub::OnRemoteSetSilentSwitch(MessageParcel &data, Messa return E_OK; } -int32_t DataShareServiceStub::OnRemoteIsSilentProxyEnable(MessageParcel &data, MessageParcel &reply) +int32_t DataShareServiceStub::OnGetSilentProxyStatus(MessageParcel &data, MessageParcel &reply) { std::string uri; if (!ITypesUtil::Unmarshal(data, uri)) { ZLOGE("Unmarshal silent enable failed. uri: %{public}s", DistributedData::Anonymous::Change(uri).c_str()); return IPC_STUB_INVALID_DATA_ERR; } - bool enable = IsSilentProxyEnable(uri); + int32_t enable = GetSilentProxyStatus(uri); if (!ITypesUtil::Marshal(reply, enable)) { ZLOGE("Marshal enable:%{public}d failed.", enable); return IPC_STUB_WRITE_PARCEL_ERR; @@ -383,7 +390,7 @@ int32_t DataShareServiceStub::OnRemoteIsSilentProxyEnable(MessageParcel &data, M return E_OK; } -int32_t DataShareServiceStub::OnRemoteRegisterObserver(MessageParcel &data, MessageParcel &reply) +int32_t DataShareServiceStub::OnRegisterObserver(MessageParcel &data, MessageParcel &reply) { std::string uri; sptr remoteObj; @@ -400,7 +407,7 @@ int32_t DataShareServiceStub::OnRemoteRegisterObserver(MessageParcel &data, Mess return E_OK; } -int32_t DataShareServiceStub::OnRemoteUnregisterObserver(MessageParcel &data, MessageParcel &reply) +int32_t DataShareServiceStub::OnUnregisterObserver(MessageParcel &data, MessageParcel &reply) { std::string uri; sptr remoteObj; @@ -416,5 +423,10 @@ int32_t DataShareServiceStub::OnRemoteUnregisterObserver(MessageParcel &data, Me } return E_OK; } + +void DataShareServiceStub::SetServiceReady() +{ + isReady_.store(true); +} } // namespace DataShare } // namespace OHOS \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_stub.h b/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_stub.h index 1790346d..9daede97 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_stub.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_share_service_stub.h @@ -24,56 +24,60 @@ namespace DataShare { class DataShareServiceStub : public IDataShareService, public DistributedData::FeatureSystem::Feature { public: int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply) override; + void SetServiceReady(); private: static constexpr std::chrono::milliseconds TIME_THRESHOLD = std::chrono::milliseconds(500); static bool CheckInterfaceToken(MessageParcel& data); - int32_t OnRemoteInsert(MessageParcel& data, MessageParcel& reply); - int32_t OnRemoteUpdate(MessageParcel& data, MessageParcel& reply); - int32_t OnRemoteDelete(MessageParcel& data, MessageParcel& reply); - int32_t OnRemoteQuery(MessageParcel& data, MessageParcel& reply); - int32_t OnRemoteAddTemplate(MessageParcel& data, MessageParcel& reply); - int32_t OnRemoteDelTemplate(MessageParcel& data, MessageParcel& reply); - int32_t OnRemotePublish(MessageParcel& data, MessageParcel& reply); - int32_t OnRemoteGetData(MessageParcel& data, MessageParcel& reply); - int32_t OnRemoteSubscribeRdbData(MessageParcel& data, MessageParcel& reply); - int32_t OnRemoteUnsubscribeRdbData(MessageParcel& data, MessageParcel& reply); - int32_t OnRemoteEnableRdbSubs(MessageParcel& data, MessageParcel& reply); - int32_t OnRemoteDisableRdbSubs(MessageParcel& data, MessageParcel& reply); - int32_t OnRemoteSubscribePublishedData(MessageParcel& data, MessageParcel& reply); - int32_t OnRemoteUnsubscribePublishedData(MessageParcel& data, MessageParcel& reply); - int32_t OnRemoteEnablePubSubs(MessageParcel& data, MessageParcel& reply); - int32_t OnRemoteDisablePubSubs(MessageParcel& data, MessageParcel& reply); - int32_t OnRemoteNotifyConnectDone(MessageParcel& data, MessageParcel& reply); - int32_t OnRemoteNotifyObserver(MessageParcel& data, MessageParcel& reply); - int32_t OnRemoteSetSilentSwitch(MessageParcel& data, MessageParcel& reply); - int32_t OnRemoteIsSilentProxyEnable(MessageParcel& data, MessageParcel& reply); - int32_t OnRemoteRegisterObserver(MessageParcel& data, MessageParcel& reply); - int32_t OnRemoteUnregisterObserver(MessageParcel& data, MessageParcel& reply); + int32_t OnInsert(MessageParcel& data, MessageParcel& reply); + int32_t OnUpdate(MessageParcel& data, MessageParcel& reply); + int32_t OnDelete(MessageParcel& data, MessageParcel& reply); + int32_t OnQuery(MessageParcel& data, MessageParcel& reply); + int32_t OnAddTemplate(MessageParcel& data, MessageParcel& reply); + int32_t OnDelTemplate(MessageParcel& data, MessageParcel& reply); + int32_t OnPublish(MessageParcel& data, MessageParcel& reply); + int32_t OnGetData(MessageParcel& data, MessageParcel& reply); + int32_t OnSubscribeRdbData(MessageParcel& data, MessageParcel& reply); + int32_t OnUnsubscribeRdbData(MessageParcel& data, MessageParcel& reply); + int32_t OnEnableRdbSubs(MessageParcel& data, MessageParcel& reply); + int32_t OnDisableRdbSubs(MessageParcel& data, MessageParcel& reply); + int32_t OnSubscribePublishedData(MessageParcel& data, MessageParcel& reply); + int32_t OnUnsubscribePublishedData(MessageParcel& data, MessageParcel& reply); + int32_t OnEnablePubSubs(MessageParcel& data, MessageParcel& reply); + int32_t OnDisablePubSubs(MessageParcel& data, MessageParcel& reply); + int32_t OnNotifyConnectDone(MessageParcel& data, MessageParcel& reply); + int32_t OnNotifyObserver(MessageParcel& data, MessageParcel& reply); + int32_t OnSetSilentSwitch(MessageParcel& data, MessageParcel& reply); + int32_t OnGetSilentProxyStatus(MessageParcel& data, MessageParcel& reply); + int32_t OnRegisterObserver(MessageParcel& data, MessageParcel& reply); + int32_t OnUnregisterObserver(MessageParcel& data, MessageParcel& reply); using RequestHandle = int (DataShareServiceStub::*)(MessageParcel &, MessageParcel &); static constexpr RequestHandle HANDLERS[DATA_SHARE_SERVICE_CMD_MAX] = { - &DataShareServiceStub::OnRemoteInsert, - &DataShareServiceStub::OnRemoteDelete, - &DataShareServiceStub::OnRemoteUpdate, - &DataShareServiceStub::OnRemoteQuery, - &DataShareServiceStub::OnRemoteAddTemplate, - &DataShareServiceStub::OnRemoteDelTemplate, - &DataShareServiceStub::OnRemotePublish, - &DataShareServiceStub::OnRemoteGetData, - &DataShareServiceStub::OnRemoteSubscribeRdbData, - &DataShareServiceStub::OnRemoteUnsubscribeRdbData, - &DataShareServiceStub::OnRemoteEnableRdbSubs, - &DataShareServiceStub::OnRemoteDisableRdbSubs, - &DataShareServiceStub::OnRemoteSubscribePublishedData, - &DataShareServiceStub::OnRemoteUnsubscribePublishedData, - &DataShareServiceStub::OnRemoteEnablePubSubs, - &DataShareServiceStub::OnRemoteDisablePubSubs, - &DataShareServiceStub::OnRemoteNotifyConnectDone, - &DataShareServiceStub::OnRemoteNotifyObserver, - &DataShareServiceStub::OnRemoteSetSilentSwitch, - &DataShareServiceStub::OnRemoteIsSilentProxyEnable, - &DataShareServiceStub::OnRemoteRegisterObserver, - &DataShareServiceStub::OnRemoteUnregisterObserver}; + &DataShareServiceStub::OnInsert, + &DataShareServiceStub::OnDelete, + &DataShareServiceStub::OnUpdate, + &DataShareServiceStub::OnQuery, + &DataShareServiceStub::OnAddTemplate, + &DataShareServiceStub::OnDelTemplate, + &DataShareServiceStub::OnPublish, + &DataShareServiceStub::OnGetData, + &DataShareServiceStub::OnSubscribeRdbData, + &DataShareServiceStub::OnUnsubscribeRdbData, + &DataShareServiceStub::OnEnableRdbSubs, + &DataShareServiceStub::OnDisableRdbSubs, + &DataShareServiceStub::OnSubscribePublishedData, + &DataShareServiceStub::OnUnsubscribePublishedData, + &DataShareServiceStub::OnEnablePubSubs, + &DataShareServiceStub::OnDisablePubSubs, + &DataShareServiceStub::OnNotifyConnectDone, + &DataShareServiceStub::OnNotifyObserver, + &DataShareServiceStub::OnSetSilentSwitch, + &DataShareServiceStub::OnGetSilentProxyStatus, + &DataShareServiceStub::OnRegisterObserver, + &DataShareServiceStub::OnUnregisterObserver}; + static constexpr int SLEEP_TIME = 300; + static constexpr int TRY_TIMES = 5; + std::atomic isReady_ = false; }; } // namespace DataShare } // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/service/data_share/idata_share_service.h b/datamgr_service/services/distributeddataservice/service/data_share/idata_share_service.h index ba4cc2e9..aa2da754 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/idata_share_service.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/idata_share_service.h @@ -49,7 +49,7 @@ public: DATA_SHARE_SERVICE_CMD_NOTIFY, DATA_SHARE_SERVICE_CMD_NOTIFY_OBSERVERS, DATA_SHARE_SERVICE_CMD_SET_SILENT_SWITCH, - DATA_SHARE_SERVICE_CMD_IS_SILENT_PROXY_ENABLE, + DATA_SHARE_SERVICE_CMD_GET_SILENT_PROXY_STATUS, DATA_SHARE_SERVICE_CMD_REGISTER_OBSERVER, DATA_SHARE_SERVICE_CMD_UNREGISTER_OBSERVER, DATA_SHARE_SERVICE_CMD_MAX @@ -87,7 +87,7 @@ public: virtual void OnConnectDone() = 0; virtual void NotifyObserver(const std::string &uri) = 0; virtual int32_t EnableSilentProxy(const std::string &uri, bool enable) = 0; - virtual bool IsSilentProxyEnable(const std::string &uri) = 0; + virtual int32_t GetSilentProxyStatus(const std::string &uri, bool isCreateHelper = true) = 0; virtual int32_t RegisterObserver(const std::string &uri, const sptr &remoteObj) = 0; virtual int32_t UnregisterObserver(const std::string &uri, const sptr &remoteObj) = 0; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/strategies/general/load_config_common_strategy.cpp b/datamgr_service/services/distributeddataservice/service/data_share/strategies/general/load_config_common_strategy.cpp index 1343e211..3cc60cdb 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/strategies/general/load_config_common_strategy.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/strategies/general/load_config_common_strategy.cpp @@ -59,7 +59,7 @@ bool LoadConfigCommonStrategy::GetInfoFromProxyURI( if (!success) { return false; } - user = std::move(data); + user = static_cast(std::move(data)); } if (!queryParams[TOKEN_ID_PARAM].empty()) { auto [success, data] = URIUtils::Strtoul(queryParams[TOKEN_ID_PARAM]); diff --git a/datamgr_service/services/distributeddataservice/service/data_share/subscriber_managers/rdb_subscriber_manager.cpp b/datamgr_service/services/distributeddataservice/service/data_share/subscriber_managers/rdb_subscriber_manager.cpp index 734e4f96..1ff14c39 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/subscriber_managers/rdb_subscriber_manager.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/subscriber_managers/rdb_subscriber_manager.cpp @@ -239,7 +239,7 @@ void RdbSubscriberManager::Emit(const std::string &uri, std::shared_ptr return false; }); SchedulerManager::GetInstance().Execute( - uri, context->currentUserId, context->calledSourceDir, context->version); + uri, context->currentUserId, context->calledSourceDir, context->version, context->calledBundleName); } void RdbSubscriberManager::Emit(const std::string &uri, int32_t userId, @@ -257,7 +257,7 @@ void RdbSubscriberManager::Emit(const std::string &uri, int32_t userId, return false; }); SchedulerManager::GetInstance().Execute( - uri, userId, metaData.dataDir, metaData.version); + uri, userId, metaData.dataDir, metaData.version, metaData.bundleName); } void RdbSubscriberManager::SetObserverNotifyOnEnabled(std::vector &nodes) @@ -318,7 +318,10 @@ int RdbSubscriberManager::Notify(const Key &key, int32_t userId, const std::vect DistributedData::Anonymous::Change(key.uri).c_str(), key.subscriberId, key.bundleName.c_str()); return E_TEMPLATE_NOT_EXIST; } - auto delegate = DBDelegate::Create(rdbDir, rdbVersion, true); + DistributedData::StoreMetaData meta; + meta.dataDir = rdbDir; + meta.bundleName = key.bundleName; + auto delegate = DBDelegate::Create(meta); if (delegate == nullptr) { ZLOGE("Create fail %{public}s %{public}s", DistributedData::Anonymous::Change(key.uri).c_str(), key.bundleName.c_str()); @@ -368,7 +371,7 @@ void RdbSubscriberManager::Emit(const std::string &uri, int64_t subscriberId, st return false; }); SchedulerManager::GetInstance().Execute( - uri, context->currentUserId, context->calledSourceDir, context->version); + uri, context->currentUserId, context->calledSourceDir, context->version, context->calledBundleName); } RdbSubscriberManager::ObserverNode::ObserverNode(const sptr &observer, uint32_t firstCallerTokenId, uint32_t callerTokenId) diff --git a/datamgr_service/services/distributeddataservice/service/data_share/sys_event_subscriber.cpp b/datamgr_service/services/distributeddataservice/service/data_share/sys_event_subscriber.cpp new file mode 100644 index 00000000..e802950a --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/data_share/sys_event_subscriber.cpp @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#define LOG_TAG "SysEventSubscriber" +#include "sys_event_subscriber.h" + +#include "common_event_manager.h" +#include "common_event_support.h" +#include "log_print.h" + +namespace OHOS::DataShare { +SysEventSubscriber::SysEventSubscriber(const EventFwk::CommonEventSubscribeInfo& info) + : CommonEventSubscriber(info) +{ + callbacks_ = { { EventFwk::CommonEventSupport::COMMON_EVENT_BUNDLE_SCAN_FINISHED, + &SysEventSubscriber::OnBMSReady } }; +} + +void SysEventSubscriber::OnReceiveEvent(const EventFwk::CommonEventData& event) +{ + EventFwk::Want want = event.GetWant(); + std::string action = want.GetAction(); + auto it = callbacks_.find(action); + if (it != callbacks_.end()) { + (this->*(it->second))(); + } +} + +void SysEventSubscriber::OnBMSReady() +{ + NotifyDataShareReady(); +} + +void SysEventSubscriber::NotifyDataShareReady() +{ + AAFwk::Want want; + want.SetAction("usual.event.DATA_SHARE_READY"); + EventFwk::CommonEventData CommonEventData { want }; + if (!EventFwk::CommonEventManager::PublishCommonEvent(CommonEventData)) { + ZLOGE("Notify dataShare ready failed."); + return; + } + ZLOGI("Notify dataShare ready succeed."); +} +} diff --git a/datamgr_service/services/distributeddataservice/service/data_share/sys_event_subscriber.h b/datamgr_service/services/distributeddataservice/service/data_share/sys_event_subscriber.h new file mode 100644 index 00000000..b266387c --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/data_share/sys_event_subscriber.h @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef DATASHARESERVICE_SYS_EVENT_SUBSCRIBER_H +#define DATASHARESERVICE_SYS_EVENT_SUBSCRIBER_H + +#include "common_event_subscriber.h" + +#include "data_share_service_impl.h" + +namespace OHOS::DataShare { +class SysEventSubscriber : public EventFwk::CommonEventSubscriber { +public: + using SysEventCallback = void (SysEventSubscriber::*)(); + explicit SysEventSubscriber(const EventFwk::CommonEventSubscribeInfo &info); + ~SysEventSubscriber() {} + void OnReceiveEvent(const EventFwk::CommonEventData& event) override; + void OnBMSReady(); + +private: + void NotifyDataShareReady(); + std::map callbacks_; +}; +} +#endif \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/kv_radar_reporter.h b/datamgr_service/services/distributeddataservice/service/kvdb/kv_radar_reporter.h new file mode 100644 index 00000000..b1ea96b8 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/kvdb/kv_radar_reporter.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef KV_RADAR_REPORTER_H +#define KV_RADAR_REPORTER_H + +#include "hisysevent.h" + +namespace OHOS::DistributedKv { +enum BizScene { + ONLINE_DEVICE_SYNC = 1, + BROADCAST_DEVICE_SYNC = 2, + STANDARD_DEVICE_SYNC = 3, +}; + +enum StandardStage { + ADD_SYNC_TASK = 1, + CHECK_DEVICE_ONLINE = 2, + STANDARD_META_SYNC = 3, + OPEN_STORE = 4, + START_SYNC = 5, + FINISH_SYNC = 6, +}; + +enum BroadcastStage { + SEND_BROADCAST = 1, +}; + +enum OnlineStage { + ONLINE_META_SYNC = 1, + ONLINE_META_COMPLETE = 2, +}; + +enum StageRes { + RADAR_START = 0, + RADAR_SUCCESS = 1, + RADAR_FAILED = 2, + RADAR_CANCEL = 3, +}; + +enum BizState { + START = 1, + END = 2, +}; + +enum SyncType { + SYNC = 1, + AUTOSYNC, + REUSE_SOCKET_AUTO_SYNC +}; + +constexpr char DOMAIN[] = "DISTDATAMGR"; +constexpr const char* EVENT_NAME = "DISTRIBUTED_KV_STORE_BEHAVIOR"; +constexpr HiviewDFX::HiSysEvent::EventType TYPE = HiviewDFX::HiSysEvent::EventType::BEHAVIOR; +constexpr const char* ORG_PKG = "distributeddata"; +constexpr const char* ERROR_CODE = "ERROR_CODE"; +constexpr const char* BIZ_STATE = "BIZ_STATE"; +constexpr const char* CONCURRENT_ID = "CONCURRENT_ID"; +constexpr const char* SYNC_STORE_ID = "SYNC_STORE_ID"; +constexpr const char* SYNC_APP_ID = "SYNC_APP_ID"; +constexpr const char* OS_TYPE = "OS_TYPE"; +constexpr const char* SYNC_TYPE = "SYNC_TYPE"; +constexpr const char* DATA_TYPE = "DATA_TYPE"; +constexpr const char* WATER_VERSION = "WATER_VERSION"; +constexpr const char* SCREEN_STATUS = "SCREEN_STATUS"; + +#define RADAR_REPORT(bizScene, bizStage, stageRes, ...) \ +({ \ + HiSysEventWrite(DistributedKv::DOMAIN, DistributedKv::EVENT_NAME, DistributedKv::TYPE, \ + "ORG_PKG", DistributedKv::ORG_PKG, "FUNC", __FUNCTION__, \ + "BIZ_SCENE", bizScene, "BIZ_STAGE", bizStage, "STAGE_RES", stageRes, ##__VA_ARGS__); \ +}) +} // namespace OHOS::DistributedKv +#endif // KV_RADAR_REPORTER_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_general_store.cpp b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_general_store.cpp index 076ae7a7..be9c07e4 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_general_store.cpp +++ b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_general_store.cpp @@ -15,10 +15,12 @@ #define LOG_TAG "KVDBGeneralStore" #include "kvdb_general_store.h" -#include "cloud/schema_meta.h" +#include +#include "bootstrap.h" +#include "checker/checker_manager.h" #include "cloud/cloud_sync_finished_event.h" +#include "cloud/schema_meta.h" #include "crypto_manager.h" -#include "checker/checker_manager.h" #include "device_matrix.h" #include "directory/directory_manager.h" #include "eventcenter/event_center.h" @@ -26,6 +28,7 @@ #include "log_print.h" #include "metadata/meta_data_manager.h" #include "metadata/secret_key_meta_data.h" +#include "metadata/store_meta_data_local.h" #include "query_helper.h" #include "rdb_cloud.h" #include "snapshot/bind_event.h" @@ -33,6 +36,8 @@ #include "user_delegate.h" #include "utils/anonymous.h" #include "water_version_manager.h" +#include "device_manager_adapter.h" +#include "utils/anonymous.h" namespace OHOS::DistributedKv { using namespace DistributedData; @@ -41,7 +46,29 @@ using DBField = DistributedDB::Field; using DBTable = DistributedDB::TableSchema; using DBSchema = DistributedDB::DataBaseSchema; using ClearMode = DistributedDB::ClearMode; - +using DMAdapter = DistributedData::DeviceManagerAdapter; +using DBInterceptedData = DistributedDB::InterceptedData; +constexpr int UUID_WIDTH = 4; +static DBSchema GetDBSchema(const Database &database) +{ + DBSchema schema; + schema.tables.resize(database.tables.size()); + for (size_t i = 0; i < database.tables.size(); i++) { + const Table &table = database.tables[i]; + DBTable &dbTable = schema.tables[i]; + dbTable.name = table.name; + dbTable.sharedTableName = table.sharedTableName; + for (auto &field : table.fields) { + DBField dbField; + dbField.colName = field.colName; + dbField.type = field.type; + dbField.primary = field.primary; + dbField.nullable = field.nullable; + dbTable.fields.push_back(std::move(dbField)); + } + } + return schema; +} KVDBGeneralStore::DBPassword KVDBGeneralStore::GetDBPassword(const StoreMetaData &data) { DBPassword dbPassword; @@ -77,7 +104,6 @@ KVDBGeneralStore::DBSecurity KVDBGeneralStore::GetDBSecurity(int32_t secLevel) KVDBGeneralStore::DBOption KVDBGeneralStore::GetDBOption(const StoreMetaData &data, const DBPassword &password) { DBOption dbOption; - dbOption.syncDualTupleMode = true; // tuple of (appid+storeid) dbOption.createIfNecessary = false; dbOption.isMemoryDb = false; dbOption.isEncryptedDb = data.isEncrypt; @@ -86,25 +112,32 @@ KVDBGeneralStore::DBOption KVDBGeneralStore::GetDBOption(const StoreMetaData &da dbOption.cipher = DistributedDB::CipherType::AES_256_GCM; dbOption.passwd = password; } - - if (data.storeType == KvStoreType::SINGLE_VERSION) { - dbOption.conflictResolvePolicy = DistributedDB::LAST_WIN; - } else if (data.storeType == KvStoreType::DEVICE_COLLABORATION) { + StoreMetaDataLocal local; + MetaDataManager::GetInstance().LoadMeta(data.GetKeyLocal(), local, true); + if (local.isPublic || data.storeType == KvStoreType::DEVICE_COLLABORATION) { dbOption.conflictResolvePolicy = DistributedDB::DEVICE_COLLABORATION; + } else if (data.storeType == KvStoreType::SINGLE_VERSION) { + dbOption.conflictResolvePolicy = DistributedDB::LAST_WIN; + } + if (data.appId == Bootstrap::GetInstance().GetProcessLabel()) { + dbOption.compressionRate = META_COMPRESS_RATE; + dbOption.conflictResolvePolicy = DistributedDB::LAST_WIN; + } else { + dbOption.syncDualTupleMode = true; // tuple of (appid+storeid) } - dbOption.schema = data.schema; dbOption.createDirByStoreIdOnly = true; dbOption.secOption = GetDBSecurity(data.securityLevel); return dbOption; } -KVDBGeneralStore::KVDBGeneralStore(const StoreMetaData &meta) : manager_(meta.appId, meta.user, meta.instanceId) +KVDBGeneralStore::KVDBGeneralStore(const StoreMetaData &meta) + : manager_(meta.appId, meta.appId == Bootstrap::GetInstance().GetProcessLabel() ? defaultAccountId : meta.user, + meta.instanceId) { observer_.storeId_ = meta.storeId; - DBStatus status = DBStatus::NOT_FOUND; - manager_.SetKvStoreConfig({ DirectoryManager::GetInstance().GetStorePath(meta) }); + manager_.SetKvStoreConfig({ meta.dataDir }); std::unique_lock lock(rwMutex_); manager_.GetKvStore( meta.storeId, GetDBOption(meta, GetDBPassword(meta)), [&status, this](auto dbStatus, auto *tmpStore) { @@ -116,6 +149,8 @@ KVDBGeneralStore::KVDBGeneralStore(const StoreMetaData &meta) : manager_(meta.ap manager_.CloseKvStore(delegate_); return; } + SetDBPushDataInterceptor(meta.storeType); + SetDBReceiveDataInterceptor(meta.storeType); delegate_->RegisterObserver({}, DistributedDB::OBSERVER_CHANGES_FOREIGN, &observer_); delegate_->RegisterObserver({}, DistributedDB::OBSERVER_CHANGES_CLOUD, &observer_); InitWaterVersion(meta); @@ -134,6 +169,7 @@ KVDBGeneralStore::KVDBGeneralStore(const StoreMetaData &meta) : manager_(meta.ap storeInfo_.storeName = meta.storeId; storeInfo_.instanceId = meta.instanceId; storeInfo_.user = std::stoi(meta.user); + enableCloud_ = meta.enableCloud; } KVDBGeneralStore::~KVDBGeneralStore() @@ -160,13 +196,16 @@ int32_t KVDBGeneralStore::BindSnapshots(std::shared_ptr &bindInfos) +int32_t KVDBGeneralStore::Bind(Database &database, const std::map &bindInfos, + const CloudConfig &config) { if (bindInfos.empty()) { ZLOGW("No cloudDB!"); return GeneralError::E_OK; } - std::map schemas{}; + + std::map schemas; + auto dbSchema = GetDBSchema(database); for (auto &[userId, bindInfo] : bindInfos) { if (bindInfo.db_ == nullptr) { return GeneralError::E_INVALID_ARGS; @@ -178,31 +217,19 @@ int32_t KVDBGeneralStore::Bind(Database &database, const std::map(bindInfo.db_, nullptr) }); bindInfos_.insert(std::move(bindInfo)); - - DBSchema schema; - schema.tables.resize(database.tables.size()); - for (size_t i = 0; i < database.tables.size(); i++) { - const Table &table = database.tables[i]; - DBTable &dbTable = schema.tables[i]; - dbTable.name = table.name; - dbTable.sharedTableName = table.sharedTableName; - for (auto &field : table.fields) { - DBField dbField; - dbField.colName = field.colName; - dbField.type = field.type; - dbField.primary = field.primary; - dbField.nullable = field.nullable; - dbTable.fields.push_back(std::move(dbField)); - } - } - schemas.insert({ std::to_string(userId), schema }); + schemas.insert({ std::to_string(userId), dbSchema }); } + DistributedDB::CloudSyncConfig dbConfig; + dbConfig.maxUploadCount = config.maxNumber; + dbConfig.maxUploadSize = config.maxSize; + dbConfig.maxRetryConflictTimes = config.maxRetryConflictTimes; std::unique_lock lock(rwMutex_); if (delegate_ == nullptr) { return GeneralError::E_ALREADY_CLOSED; } delegate_->SetCloudDB(dbClouds_); delegate_->SetCloudDbSchema(std::move(schemas)); + delegate_->SetCloudSyncConfig(dbConfig); return GeneralError::E_OK; } @@ -293,12 +320,20 @@ KVDBGeneralStore::DBSyncCallback KVDBGeneralStore::GetDBSyncCompleteCB(DetailAsy }; } -DBStatus KVDBGeneralStore::CloudSync(const Devices &devices, DistributedDB::SyncMode &cloudSyncMode, int64_t wait) +DBStatus KVDBGeneralStore::CloudSync(const Devices &devices, int32_t mode, DetailAsync async, int64_t wait) { + auto syncMode = GeneralStore::GetSyncMode(static_cast(mode)); + if (syncMode < CLOUD_BEGIN || syncMode >= CLOUD_END) { + ZLOGE("Do not need to cloud sync! devices count:%{public}zu, the 1st:%{public}s, syncMode:%{public}d", + devices.size(), devices.empty() ? "null" : Anonymous::Change(*devices.begin()).c_str(), syncMode); + return DBStatus::DB_ERROR; + } DistributedDB::CloudSyncOption syncOption; syncOption.devices = devices; - syncOption.mode = cloudSyncMode; + syncOption.mode = DistributedDB::SyncMode(syncMode); syncOption.waitTime = wait; + syncOption.lockAction = DistributedDB::LockAction::NONE; + syncOption.merge = GeneralStore::GetHighMode(static_cast(mode)) == HighMode::AUTO_SYNC_MODE; if (storeInfo_.user == 0) { std::vector users; AccountDelegate::GetInstance()->QueryUsers(users); @@ -306,22 +341,24 @@ DBStatus KVDBGeneralStore::CloudSync(const Devices &devices, DistributedDB::Sync } else { syncOption.users.push_back(std::to_string(storeInfo_.user)); } - return delegate_->Sync(syncOption, GetDBProcessCB(nullptr)); + return delegate_->Sync(syncOption, GetDBProcessCB(async)); } int32_t KVDBGeneralStore::Sync(const Devices &devices, GenQuery &query, DetailAsync async, SyncParam &syncParm) { - auto syncMode = GeneralStore::GetSyncMode(syncParm.mode); std::shared_lock lock(rwMutex_); if (delegate_ == nullptr) { ZLOGE("store already closed! devices count:%{public}zu, the 1st:%{public}s, mode:%{public}d", devices.size(), devices.empty() ? "null" : Anonymous::Change(*devices.begin()).c_str(), syncParm.mode); return GeneralError::E_ALREADY_CLOSED; } - auto dbStatus = DistributedDB::OK; - auto dbMode = DistributedDB::SyncMode(syncMode); + DBStatus dbStatus; + auto syncMode = GeneralStore::GetSyncMode(syncParm.mode); if (syncMode > NEARBY_END && syncMode < CLOUD_END) { - dbStatus = CloudSync(devices, dbMode, syncParm.wait); + if (!enableCloud_) { + return GeneralError::E_NOT_SUPPORT; + } + dbStatus = CloudSync(devices, syncParm.mode, async, syncParm.wait); } else { if (devices.empty()) { ZLOGE("Devices is empty! mode:%{public}d", syncParm.mode); @@ -341,6 +378,7 @@ int32_t KVDBGeneralStore::Sync(const Devices &devices, GenQuery &query, DetailAs dbStatus = delegate_->UnSubscribeRemoteQuery(devices, GetDBSyncCompleteCB(std::move(async)), dbQuery, false); } else if (syncMode < NEARBY_END) { + auto dbMode = DistributedDB::SyncMode(syncMode); if (kvQuery->IsEmpty()) { dbStatus = delegate_->Sync(devices, dbMode, GetDBSyncCompleteCB(std::move(async)), false); } else { @@ -354,6 +392,45 @@ int32_t KVDBGeneralStore::Sync(const Devices &devices, GenQuery &query, DetailAs return ConvertStatus(dbStatus); } +void KVDBGeneralStore::SetEqualIdentifier(const std::string &appId, const std::string &storeId) +{ + std::vector sameAccountDevs {}; + std::vector defaultAccountDevs {}; + auto uuids = DMAdapter::ToUUID(DMAdapter::GetInstance().GetRemoteDevices()); + GetIdentifierParams(sameAccountDevs, uuids, IDENTICAL_ACCOUNT); + GetIdentifierParams(defaultAccountDevs, uuids, NO_ACCOUNT); + if (!sameAccountDevs.empty()) { + auto accountId = AccountDelegate::GetInstance()->GetUnencryptedAccountId(); + auto syncIdentifier = KvManager::GetKvStoreIdentifier(accountId, appId, storeId); + ZLOGI("same account set compatible identifier store:%{public}s, user:%{public}s, device:%{public}.10s", + Anonymous::Change(storeId).c_str(), Anonymous::Change(accountId).c_str(), + DistributedData::Serializable::Marshall(sameAccountDevs).c_str()); + delegate_->SetEqualIdentifier(syncIdentifier, sameAccountDevs); + } + if (!defaultAccountDevs.empty()) { + auto syncIdentifier = KvManager::GetKvStoreIdentifier(defaultAccountId, appId, storeId); + ZLOGI("no account set compatible identifier store:%{public}s, device:%{public}.10s", + Anonymous::Change(storeId).c_str(), + DistributedData::Serializable::Marshall(defaultAccountDevs).c_str()); + delegate_->SetEqualIdentifier(syncIdentifier, defaultAccountDevs); + } +} + +void KVDBGeneralStore::GetIdentifierParams(std::vector &devices, + const std::vector &uuids, int32_t authType) +{ + for (const auto &devId : uuids) { + if (DMAdapter::GetInstance().IsOHOSType(devId)) { + continue; + } + if (DMAdapter::GetInstance().GetAuthType(devId) != authType) { + continue; + } + devices.push_back(devId); + } + ZLOGI("devices size: %{public}zu", devices.size()); +} + std::shared_ptr KVDBGeneralStore::PreSharing(GenQuery &query) { return nullptr; @@ -464,6 +541,8 @@ KVDBGeneralStore::GenErr KVDBGeneralStore::ConvertStatus(DistributedDB::DBStatus return GenErr::E_RECODE_LIMIT_EXCEEDED; case DBStatus::CLOUD_ASSET_SPACE_INSUFFICIENT: return GenErr::E_NO_SPACE_FOR_ASSET; + case DBStatus::CLOUD_SYNC_TASK_MERGED: + return GenErr::E_SYNC_TASK_MERGED; default: ZLOGI("status:0x%{public}x", status); break; @@ -489,7 +568,20 @@ int32_t KVDBGeneralStore::UnregisterDetailProgressObserver() std::vector KVDBGeneralStore::GetWaterVersion(const std::string &deviceId) { - return {}; + std::shared_lock lock(rwMutex_); + if (delegate_ == nullptr) { + ZLOGE("store already closed! deviceId:%{public}s", Anonymous::Change(deviceId).c_str()); + return {}; + } + auto [status, versions] = delegate_->GetCloudVersion(deviceId); + if (status != DBStatus::OK || versions.empty()) { + return {}; + } + std::vector res; + for (auto &[_, version] : versions) { + res.push_back(std::move(version)); + } + return res; } void KVDBGeneralStore::InitWaterVersion(const StoreMetaData &meta) @@ -500,7 +592,9 @@ void KVDBGeneralStore::InitWaterVersion(const StoreMetaData &meta) if (!isDynamic && !isStatic) { return; } - // SetGenCloudVersionCallback + delegate_->SetGenCloudVersionCallback([info](auto &originVersion) { + return WaterVersionManager::GetInstance().GetWaterVersion(info.bundleName, info.storeId); + }); callback_ = [meta]() { auto event = std::make_unique(CloudEvent::CLOUD_SYNC_FINISHED, meta); EventCenter::GetInstance().PostEvent(std::move(event)); @@ -562,12 +656,12 @@ KVDBGeneralStore::DBProcessCB KVDBGeneralStore::GetDBProcessCB(DetailAsync async return; } DistributedData::GenDetails details; - bool isFinished = false; + bool downloadFinished = false; for (auto &[id, process] : processes) { auto &detail = details[id]; - isFinished |= process.process == FINISHED; detail.progress = process.process; detail.code = ConvertStatus(process.errCode); + detail.dbCode = DB_ERR_OFFSET + process.errCode; for (auto [key, value] : process.tableProcess) { auto &table = detail.details[key]; table.upload.total = value.upLoadInfo.total; @@ -578,14 +672,105 @@ KVDBGeneralStore::DBProcessCB KVDBGeneralStore::GetDBProcessCB(DetailAsync async table.download.success = value.downLoadInfo.successCount; table.download.failed = value.downLoadInfo.failCount; table.download.untreated = table.download.total - table.download.success - table.download.failed; + downloadFinished = downloadFinished || + (process.process == FINISHED && value.downLoadInfo.successCount > 0); } } if (async) { async(details); } - if (isFinished && callback) { + if (downloadFinished && callback) { callback(); } }; } -} // namespace OHOS::DistributedKv + +void KVDBGeneralStore::SetDBPushDataInterceptor(int32_t storeType) +{ + delegate_->SetPushDataInterceptor( + [this, storeType](DBInterceptedData &data, const std::string &sourceID, const std::string &targetID) { + int errCode = DBStatus::OK; + if (storeType != KvStoreType::DEVICE_COLLABORATION || DMAdapter::GetInstance().IsOHOSType(targetID)) { + return errCode; + } + if (targetID.empty()) { + ZLOGE("targetID empty"); + return static_cast(DBStatus::DB_ERROR); + } + auto entries = data.GetEntries(); + for (size_t i = 0; i < entries.size(); i++) { + if (entries[i].key.empty()) { + continue; + } + auto oriKey = entries[i].key; + auto newKey = GetNewKey(oriKey, sourceID); + errCode = data.ModifyKey(i, newKey); + if (errCode != DBStatus::OK) { + ZLOGE("ModifyKey err: %{public}d", errCode); + break; + } + } + return errCode; + } + ); +} + +void KVDBGeneralStore::SetDBReceiveDataInterceptor(int32_t storeType) +{ + delegate_->SetReceiveDataInterceptor( + [this, storeType](DBInterceptedData &data, const std::string &sourceID, const std::string &targetID) { + int errCode = DBStatus::OK; + if (storeType != KvStoreType::DEVICE_COLLABORATION || DMAdapter::GetInstance().IsOHOSType(sourceID)) { + return errCode; + } + if (sourceID.empty()) { + ZLOGE("targetID empty"); + return static_cast(DBStatus::DB_ERROR); + } + auto entries = data.GetEntries(); + for (size_t i = 0; i < entries.size(); i++) { + if (entries[i].key.empty()) { + continue; + } + + auto networkId = DMAdapter::GetInstance().ToNetworkID(sourceID); + auto encyptedUuid = DMAdapter::GetInstance().GetEncryptedUuidByNetworkId(networkId); + if (encyptedUuid.empty()) { + ZLOGE("get encyptedUuid failed"); + continue; + } + + auto oriKey = entries[i].key; + auto newKey = GetNewKey(oriKey, encyptedUuid); + errCode = data.ModifyKey(i, newKey); + if (errCode != DBStatus::OK) { + ZLOGE("ModifyKey err: %{public}d", errCode); + break; + } + } + return errCode; + } + ); +} + +std::vector KVDBGeneralStore::GetNewKey(std::vector &key, const std::string &uuid) +{ + uint32_t remoteLen = *(reinterpret_cast(&(*(key.end() - sizeof(uint32_t))))); + remoteLen = le32toh(remoteLen); + uint32_t uuidLen = uuid.size(); + + std::vector out; + std::vector oriKey(key.begin() + remoteLen, key.end() - UUID_WIDTH); + out.insert(out.end(), uuid.begin(), uuid.end()); + out.insert(out.end(), oriKey.begin(), oriKey.end()); + uuidLen = htole32(uuidLen); + uint8_t *buf = reinterpret_cast(&uuidLen); + out.insert(out.end(), buf, buf + sizeof(uuidLen)); + return out; +} + +void KVDBGeneralStore::SetConfig(const GeneralStore::StoreConfig &storeConfig) +{ + enableCloud_ = storeConfig.enableCloud_; +} +} // namespace OHOS::DistributedKv \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_general_store.h b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_general_store.h index e7517c2c..b9ad8360 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_general_store.h +++ b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_general_store.h @@ -43,7 +43,8 @@ public: explicit KVDBGeneralStore(const StoreMetaData &meta); ~KVDBGeneralStore(); - int32_t Bind(Database &database, const std::map &bindInfos) override; + int32_t Bind(Database &database, const std::map &bindInfos, + const CloudConfig &config) override; bool IsBound() override; bool IsValid(); int32_t Execute(const std::string &table, const std::string &sql) override; @@ -71,6 +72,8 @@ public: int32_t BindSnapshots(std::shared_ptr>> bindAssets) override; int32_t MergeMigratedData(const std::string &tableName, VBuckets &&values) override; std::vector GetWaterVersion(const std::string &deviceId) override; + void SetEqualIdentifier(const std::string &appId, const std::string &storeId) override; + void SetConfig(const StoreConfig &storeConfig) override; static DBPassword GetDBPassword(const StoreMetaData &data); static DBOption GetDBOption(const StoreMetaData &data, const DBPassword &password); @@ -83,10 +86,15 @@ private: using DBSyncCallback = std::function &status)>; using DBProcessCB = std::function &processes)>; static GenErr ConvertStatus(DBStatus status); + void SetDBPushDataInterceptor(int32_t storeType); + void SetDBReceiveDataInterceptor(int32_t storeType); + std::vector GetNewKey(std::vector &key, const std::string &uuid); DBSyncCallback GetDBSyncCompleteCB(DetailAsync async); DBProcessCB GetDBProcessCB(DetailAsync async); - DBStatus CloudSync(const Devices &devices, DistributedDB::SyncMode &cloudSyncMode, int64_t wait); + DBStatus CloudSync(const Devices &devices, int32_t mode, DetailAsync async, int64_t wait); void InitWaterVersion(const StoreMetaData &meta); + void GetIdentifierParams(std::vector &devices, + const std::vector &uuids, int32_t authType); class ObserverProxy : public DistributedDB::KvStoreObserver { public: using DBOrigin = DistributedDB::Origin; @@ -108,6 +116,7 @@ private: std::string storeId_; }; + static constexpr uint8_t META_COMPRESS_RATE = 10; ObserverProxy observer_; KvManager manager_; KvDelegate *delegate_ = nullptr; @@ -119,6 +128,11 @@ private: mutable std::shared_mutex rwMutex_; StoreInfo storeInfo_; std::function callback_; + + static constexpr int32_t NO_ACCOUNT = 0; + static constexpr int32_t IDENTICAL_ACCOUNT = 1; + static constexpr const char *defaultAccountId = "default"; + bool enableCloud_ = false; }; } // namespace OHOS::DistributedKv -#endif // OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_KVDB_GENERAL_STORE_H +#endif // OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_KVDB_GENERAL_STORE_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_notifier_proxy.cpp b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_notifier_proxy.cpp index 26c2418d..ce558c67 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_notifier_proxy.cpp +++ b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_notifier_proxy.cpp @@ -67,13 +67,23 @@ void KVDBNotifierProxy::SyncCompleted(const std::map &resul } } -void KVDBNotifierProxy::OnRemoteChange(const std::map &mask) +void KVDBNotifierProxy::SyncCompleted(uint64_t seqNum, ProgressDetail &&detail) +{ + MessageParcel reply; + int32_t status = + IPC_SEND(static_cast(KVDBNotifierCode::TRANS_CLOUD_SYNC_COMPLETED), reply, seqNum, detail); + if (status != SUCCESS) { + ZLOGE("status:%{public}d, sequenceId:%{public}" PRIu64, status, seqNum); + } +} + +void KVDBNotifierProxy::OnRemoteChange(const std::map &mask, int32_t dataType) { MessageParcel reply; int32_t status = IPC_SEND(static_cast( - KVDBNotifierCode::TRANS_ON_REMOTE_CHANGED), reply, mask); + KVDBNotifierCode::TRANS_ON_REMOTE_CHANGED), reply, mask, dataType); if (status != SUCCESS) { - ZLOGE("status:%{public}d, mask:%{public}zu", status, mask.size()); + ZLOGE("status:%{public}d, mask:%{public}zu, dataType:%{public}d", status, mask.size(), dataType); } } diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_notifier_proxy.h b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_notifier_proxy.h index 3e468c68..67101416 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_notifier_proxy.h +++ b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_notifier_proxy.h @@ -27,7 +27,8 @@ public: explicit KVDBNotifierProxy(const sptr &impl); ~KVDBNotifierProxy() = default; void SyncCompleted(const std::map &results, uint64_t sequenceId) override; - void OnRemoteChange(const std::map &mask) override; + void SyncCompleted(uint64_t seqNum, ProgressDetail &&detail) override; + void OnRemoteChange(const std::map &mask, int32_t dataType) override; void OnSwitchChange(const SwitchNotification ¬ification) override; private: diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_query.h b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_query.h index 927a6539..0640867d 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_query.h +++ b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_query.h @@ -25,10 +25,8 @@ namespace OHOS::DistributedKv { class KVDBQuery : public DistributedData::GenQuery { public: static constexpr uint64_t TYPE_ID = 0x20000002; - - explicit KVDBQuery(const std::string &query) + explicit KVDBQuery(const std::string &query) : query_(query) { - query_ = query; dbQuery_ = QueryHelper::StringToDbQuery(query, isSuccess_); } ~KVDBQuery() = default; diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp index b0849eaf..ee0f35f0 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp @@ -22,6 +22,7 @@ #include "account/account_delegate.h" #include "auto_sync_matrix.h" #include "backup_manager.h" +#include "bootstrap.h" #include "checker/checker_manager.h" #include "cloud/change_event.h" #include "cloud/cloud_server.h" @@ -35,6 +36,7 @@ #include "ipc_skeleton.h" #include "kvdb_general_store.h" #include "kvdb_query.h" +#include "kv_radar_reporter.h" #include "log_print.h" #include "matrix_event.h" #include "metadata/appid_meta_data.h" @@ -47,6 +49,7 @@ #include "utils/anonymous.h" #include "utils/constant.h" #include "utils/converter.h" +#include "water_version_manager.h" namespace OHOS::DistributedKv { using namespace OHOS::DistributedData; @@ -56,6 +59,7 @@ using system_clock = std::chrono::system_clock; using DMAdapter = DistributedData::DeviceManagerAdapter; using DumpManager = OHOS::DistributedData::DumpManager; using CommContext = OHOS::DistributedData::CommunicatorContext; +static constexpr const char *DEFAULT_USER_ID = "0"; __attribute__((used)) KVDBServiceImpl::Factory KVDBServiceImpl::factory_; KVDBServiceImpl::Factory::Factory() { @@ -84,69 +88,6 @@ KVDBServiceImpl::Factory::~Factory() KVDBServiceImpl::KVDBServiceImpl() { - EventCenter::GetInstance().Subscribe(DeviceMatrix::MATRIX_META_FINISHED, [this](const Event &event) { - auto &matrixEvent = static_cast(event); - auto deviceId = matrixEvent.GetDeviceId(); - auto refCount = matrixEvent.StealRefCount(); - std::vector metaData; - auto prefix = StoreMetaData::GetPrefix({ DMAdapter::GetInstance().GetLocalDevice().uuid }); - if (!MetaDataManager::GetInstance().LoadMeta(prefix, metaData)) { - ZLOGE("load meta failed!"); - return; - } - - uint16_t mask = matrixEvent.GetMatrixData().statics; - for (const auto &data : metaData) { - if (data.dataType != DataType::TYPE_STATICS) { - OldOnlineSync(data, deviceId, refCount, matrixEvent.GetMatrixData().dynamic); - continue; - } - auto code = DeviceMatrix::GetInstance().GetCode(data); - if ((code == DeviceMatrix::INVALID_MASK) || (mask & code) != code) { - OldOnlineSync(data, deviceId, refCount, matrixEvent.GetMatrixData().dynamic); - continue; - } - SyncInfo syncInfo; - syncInfo.mode = GetSyncMode(true, IsRemoteChange(data, deviceId)); - syncInfo.delay = 0; - syncInfo.devices = { deviceId }; - ZLOGI("[online] appId:%{public}s, storeId:%{public}s", data.bundleName.c_str(), - Anonymous::Change(data.storeId).c_str()); - KvStoreSyncManager::GetInstance()->AddSyncOperation(uintptr_t(data.tokenId), syncInfo.delay, - std::bind(&KVDBServiceImpl::DoSync, this, data, syncInfo, std::placeholders::_1, ACTION_SYNC), - std::bind(&KVDBServiceImpl::DoComplete, this, data, syncInfo, refCount, std::placeholders::_1)); - } - }); -} - -void KVDBServiceImpl::OldOnlineSync( - const StoreMetaData &data, const std::string &deviceId, RefCount refCount, uint16_t mask) -{ - StoreMetaDataLocal localMetaData; - MetaDataManager::GetInstance().LoadMeta(data.GetKeyLocal(), localMetaData, true); - if (!localMetaData.HasPolicy(PolicyType::IMMEDIATE_SYNC_ON_ONLINE)) { - return; - } - - auto code = DeviceMatrix::GetInstance().GetCode(data); - if ((mask & code) != code) { - return; - } - - auto policy = localMetaData.GetPolicy(PolicyType::IMMEDIATE_SYNC_ON_ONLINE); - SyncInfo syncInfo; - syncInfo.mode = PUSH_PULL; - syncInfo.delay = 0; - syncInfo.devices = { deviceId }; - if (policy.IsValueEffect()) { - syncInfo.delay = policy.valueUint; - } - ZLOGI("[online old] appId:%{public}s, storeId:%{public}s", data.bundleName.c_str(), - Anonymous::Change(data.storeId).c_str()); - auto delay = GetSyncDelayTime(syncInfo.delay, { data.storeId }); - KvStoreSyncManager::GetInstance()->AddSyncOperation(uintptr_t(data.tokenId), delay, - std::bind(&KVDBServiceImpl::DoSync, this, data, syncInfo, std::placeholders::_1, ACTION_SYNC), - std::bind(&KVDBServiceImpl::DoComplete, this, data, syncInfo, refCount, std::placeholders::_1)); } KVDBServiceImpl::~KVDBServiceImpl() @@ -157,8 +98,8 @@ KVDBServiceImpl::~KVDBServiceImpl() void KVDBServiceImpl::Init() { auto process = [this](const Event &event) { - auto &evt = static_cast(event); - auto &storeInfo = evt.GetStoreInfo(); + const auto &evt = static_cast(event); + const auto &storeInfo = evt.GetStoreInfo(); StoreMetaData meta; meta.storeId = storeInfo.storeName; meta.bundleName = storeInfo.bundleName; @@ -172,7 +113,7 @@ void KVDBServiceImpl::Init() } meta.user = "0"; StoreMetaDataLocal localMeta; - if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), localMeta, true) || !localMeta.isPublic || + if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKeyLocal(), localMeta, true) || !localMeta.isPublic || !MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta, true)) { ZLOGE("meta empty, not public store. bundleName:%{public}s, storeId:%{public}s, user = %{public}s", meta.bundleName.c_str(), meta.GetStoreAlias().c_str(), meta.user.c_str()); @@ -266,26 +207,40 @@ Status KVDBServiceImpl::Delete(const AppId &appId, const StoreId &storeId) return SUCCESS; } -Status KVDBServiceImpl::CloudSync(const AppId &appId, const StoreId &storeId) +Status KVDBServiceImpl::Close(const AppId &appId, const StoreId &storeId) { - if (CloudServer::GetInstance() == nullptr || !DMAdapter::GetInstance().IsNetworkAvailable()) { - return Status::CLOUD_DISABLED; - } StoreMetaData metaData = GetStoreMetaData(appId, storeId); - MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData); - DistributedData::StoreInfo storeInfo; - storeInfo.bundleName = appId.appId; - storeInfo.user = AccountDelegate::GetInstance()->GetUserByToken(IPCSkeleton::GetCallingTokenID()); - storeInfo.storeName = storeId; - auto mixMode = static_cast(GeneralStore::MixMode(GeneralStore::CLOUD_TIME_FIRST, - metaData.isAutoSync ? GeneralStore::AUTO_SYNC_MODE : GeneralStore::MANUAL_SYNC_MODE)); - auto info = ChangeEvent::EventInfo(mixMode, 0, metaData.isAutoSync, nullptr, nullptr); - auto evt = std::make_unique(std::move(storeInfo), std::move(info)); - EventCenter::GetInstance().PostEvent(std::move(evt)); + if (metaData.instanceId < 0) { + return ILLEGAL_STATE; + } + auto tokenId = IPCSkeleton::GetCallingTokenID(); + AutoCache::GetInstance().CloseStore(tokenId, storeId); + ZLOGD("appId:%{public}s storeId:%{public}s instanceId:%{public}d", appId.appId.c_str(), + Anonymous::Change(storeId.storeId).c_str(), metaData.instanceId); return SUCCESS; } -Status KVDBServiceImpl::Sync(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) +Status KVDBServiceImpl::CloudSync(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) +{ + StoreMetaData metaData = GetStoreMetaData(appId, storeId); + if (!MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData, true)) { + ZLOGE("invalid, appId:%{public}s storeId:%{public}s", + appId.appId.c_str(), Anonymous::Change(storeId.storeId).c_str()); + return Status::INVALID_ARGUMENT; + } + return DoCloudSync(metaData, syncInfo); +} + +void KVDBServiceImpl::OnAsyncComplete(uint32_t tokenId, uint64_t seqNum, ProgressDetail &&detail) +{ + ZLOGI("tokenId=%{public}x seqnum=%{public}" PRIu64, tokenId, seqNum); + auto [success, agent] = syncAgents_.Find(tokenId); + if (success && agent.notifier_ != nullptr) { + agent.notifier_->SyncCompleted(seqNum, std::move(detail)); + } +} + +Status KVDBServiceImpl::Sync(const AppId &appId, const StoreId &storeId, SyncInfo &syncInfo) { StoreMetaData metaData = GetStoreMetaData(appId, storeId); MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData); @@ -300,12 +255,16 @@ Status KVDBServiceImpl::Sync(const AppId &appId, const StoreId &storeId, const S return Status::SUCCESS; } } + syncInfo.syncId = ++syncId_; + RADAR_REPORT(STANDARD_DEVICE_SYNC, ADD_SYNC_TASK, RADAR_SUCCESS, BIZ_STATE, START, + SYNC_STORE_ID, Anonymous::Change(storeId.storeId), SYNC_APP_ID, appId.appId, CONCURRENT_ID, + std::to_string(syncInfo.syncId), DATA_TYPE, metaData.dataType, SYNC_TYPE, SYNC); return KvStoreSyncManager::GetInstance()->AddSyncOperation(uintptr_t(metaData.tokenId), delay, std::bind(&KVDBServiceImpl::DoSyncInOrder, this, metaData, syncInfo, std::placeholders::_1, ACTION_SYNC), std::bind(&KVDBServiceImpl::DoComplete, this, metaData, syncInfo, RefCount(), std::placeholders::_1)); } -Status KVDBServiceImpl::SyncExt(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) +Status KVDBServiceImpl::SyncExt(const AppId &appId, const StoreId &storeId, SyncInfo &syncInfo) { if (syncInfo.devices.empty()) { return Status::INVALID_ARGUMENT; @@ -319,14 +278,16 @@ Status KVDBServiceImpl::SyncExt(const AppId &appId, const StoreId &storeId, cons Anonymous::Change(syncInfo.devices[0]).c_str()); return Status::INVALID_ARGUMENT; } - - if (!IsRemoteChange(metaData, device)) { - ZLOGD("no change, do not need sync, appId:%{public}s storeId:%{public}s", - metaData.bundleName.c_str(), Anonymous::Change(metaData.storeId).c_str()); - DBResult dbResult = { {syncInfo.devices[0], DBStatus::OK} }; - DoComplete(metaData, syncInfo, RefCount(), std::move(dbResult)); - return SUCCESS; + if (DeviceMatrix::GetInstance().IsSupportMatrix() && + ((!DeviceMatrix::GetInstance().IsStatics(metaData) && !DeviceMatrix::GetInstance().IsDynamic(metaData)) || + !IsRemoteChange(metaData, device))) { + ZLOGD("no change, do not need sync, appId:%{public}s storeId:%{public}s", + metaData.bundleName.c_str(), Anonymous::Change(metaData.storeId).c_str()); + DBResult dbResult = { {syncInfo.devices[0], DBStatus::OK} }; + DoComplete(metaData, syncInfo, RefCount(), std::move(dbResult)); + return SUCCESS; } + syncInfo.syncId = ++syncId_; return KvStoreSyncManager::GetInstance()->AddSyncOperation(uintptr_t(metaData.tokenId), 0, std::bind(&KVDBServiceImpl::DoSyncInOrder, this, metaData, syncInfo, std::placeholders::_1, ACTION_SYNC), std::bind(&KVDBServiceImpl::DoComplete, this, metaData, syncInfo, RefCount(), std::placeholders::_1)); @@ -334,14 +295,36 @@ Status KVDBServiceImpl::SyncExt(const AppId &appId, const StoreId &storeId, cons Status KVDBServiceImpl::NotifyDataChange(const AppId &appId, const StoreId &storeId) { - CloudSync(appId, storeId); StoreMetaData meta = GetStoreMetaData(appId, storeId); if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta)) { ZLOGE("invalid, appId:%{public}s storeId:%{public}s", appId.appId.c_str(), Anonymous::Change(storeId.storeId).c_str()); return Status::INVALID_ARGUMENT; } - TryToSync(meta, true); + if (!DeviceMatrix::GetInstance().IsSupportMatrix()) { + if (meta.cloudAutoSync) { + DoCloudSync(meta, {}); + } + if (meta.isAutoSync) { + TryToSync(meta, true); + } + return SUCCESS; + } + if (DeviceMatrix::GetInstance().IsStatics(meta) || DeviceMatrix::GetInstance().IsDynamic(meta)) { + WaterVersionManager::GetInstance().GenerateWaterVersion(meta.bundleName, meta.storeId); + DeviceMatrix::GetInstance().OnChanged(meta); + if (meta.cloudAutoSync) { + DoCloudSync(meta, {}); + } + return SUCCESS; + } + if (meta.cloudAutoSync) { + DoCloudSync(meta, {}); + } + if (meta.isAutoSync) { + AutoSyncMatrix::GetInstance().OnChanged(meta); + TryToSync(meta); + } return SUCCESS; } @@ -358,7 +341,14 @@ void KVDBServiceImpl::TryToSync(const StoreMetaData &metaData, bool force) !DMAdapter::GetInstance().IsDeviceReady(device))) { continue; } + ZLOGI("[TryToSync] appId:%{public}s, storeId:%{public}s", metaData.bundleName.c_str(), + Anonymous::Change(metaData.storeId).c_str()); syncInfo.devices = { device }; + syncInfo.syncId = ++syncId_; + RADAR_REPORT(STANDARD_DEVICE_SYNC, ADD_SYNC_TASK, RADAR_SUCCESS, BIZ_STATE, START, + SYNC_STORE_ID, Anonymous::Change(metaData.storeId), SYNC_APP_ID, metaData.bundleName, + CONCURRENT_ID, std::to_string(syncInfo.syncId), DATA_TYPE, metaData.dataType, + SYNC_TYPE, REUSE_SOCKET_AUTO_SYNC); KvStoreSyncManager::GetInstance()->AddSyncOperation(uintptr_t(metaData.tokenId), 0, std::bind(&KVDBServiceImpl::DoSyncInOrder, this, metaData, syncInfo, std::placeholders::_1, ACTION_SYNC), std::bind(&KVDBServiceImpl::DoComplete, this, metaData, syncInfo, RefCount(), std::placeholders::_1)); @@ -386,7 +376,11 @@ Status KVDBServiceImpl::PutSwitch(const AppId &appId, const SwitchData &data) .switches = data.value, .switchesLen = data.length, }; + RADAR_REPORT(BROADCAST_DEVICE_SYNC, SEND_BROADCAST, RADAR_START, BIZ_STATE, START, + SYNC_APP_ID, appId.appId); DeviceMatrix::GetInstance().Broadcast(level); + RADAR_REPORT(BROADCAST_DEVICE_SYNC, SEND_BROADCAST, RADAR_SUCCESS, BIZ_STATE, END, + SYNC_APP_ID, appId.appId); } } ZLOGI("appId:%{public}s, exist:%{public}d, saved:%{public}d", appId.appId.c_str(), exist, newMeta != oldMeta); @@ -419,60 +413,77 @@ Status KVDBServiceImpl::RegServiceNotifier(const AppId &appId, sptr clientMask; - auto masks = DeviceMatrix::GetInstance().GetRemoteDynamicMask(); - for (const auto &[device, mask] : masks) { - auto networkId = DMAdapter::GetInstance().ToNetworkID(device); - if (networkId.empty()) { - continue; - } - bool changed = ((mask & code) == code); - clientMask.insert_or_assign(networkId, changed); - } - notifier->OnRemoteChange(std::move(clientMask)); return Status::SUCCESS; } void KVDBServiceImpl::RegisterMatrixChange() { - DeviceMatrix::GetInstance().RegRemoteChange([this](const std::string &device, uint16_t mask) { + if (!DeviceMatrix::GetInstance().IsSupportMatrix()) { + ZLOGD("not support matrix"); + return; + } + DeviceMatrix::GetInstance().RegRemoteChange([this](const std::string &device, std::pair mask) { auto networkId = DMAdapter::GetInstance().ToNetworkID(device); if (networkId.empty()) { return; } - syncAgents_.ForEachCopies([networkId, mask](const auto &key, auto &value) { - StoreMetaData meta; - meta.appId = value.appId_; - meta.tokenId = key; - meta.bundleName = value.appId_; - meta.dataType = DataType::TYPE_DYNAMICAL; - if (!DeviceMatrix::GetInstance().IsDynamic(meta)) { - return false; - } - uint16_t code = DeviceMatrix::GetInstance().GetCode(meta); - std::map clientMask; - bool changed = ((mask & code) == code); - if ((value.changed_ && changed) || (!value.changed_ && changed)) { - return false; - } - value.changed_ = changed; - clientMask.insert_or_assign(networkId, changed); - if (value.notifier_) { - value.notifier_->OnRemoteChange(std::move(clientMask)); - } + OnDynamicChange(mask); + OnStaticsChange(mask); + }); +} + +void KVDBServiceImpl::OnStaticsChange(std::pair mask) +{ + bool isChanged = false; + syncAgents_.ForEach([mask, &isChanged](const auto &key, auto &value) { + StoreMetaData meta; + meta.appId = value.appId_; + meta.tokenId = key; + meta.bundleName = value.appId_; + meta.dataType = DataType::TYPE_STATICS; + if (!DeviceMatrix::GetInstance().IsStatics(meta)) { return false; - }); + } + uint16_t code = DeviceMatrix::GetInstance().GetCode(meta); + std::map clientMask; + bool changed = ((mask.first & code) == code); + if ((value.staticsChanged_ && changed) || (!value.staticsChanged_ && !changed)) { + return false; + } + value.staticsChanged_ = changed; + isChanged = true; + return false; + }); + if (isChanged) { + DoCloudSync(true); + } +} + +void KVDBServiceImpl::OnDynamicChange(std::pair mask) +{ + bool isChanged = false; + syncAgents_.ForEach([mask, &isChanged](const auto &key, auto &value) { + StoreMetaData meta; + meta.appId = value.appId_; + meta.tokenId = key; + meta.bundleName = value.appId_; + meta.dataType = DataType::TYPE_DYNAMICAL; + if (!DeviceMatrix::GetInstance().IsDynamic(meta)) { + return false; + } + uint16_t code = DeviceMatrix::GetInstance().GetCode(meta); + std::map clientMask; + bool changed = ((mask.second & code) == code); + if ((value.dynamicChanged_ && changed) || (!value.dynamicChanged_ && !changed)) { + return false; + } + value.dynamicChanged_ = changed; + isChanged = true; + return false; }); + if (isChanged) { + DoCloudSync(false); + } } Status KVDBServiceImpl::UnregServiceNotifier(const AppId &appId) @@ -548,6 +559,25 @@ Status KVDBServiceImpl::UnsubscribeSwitchData(const AppId &appId) return SUCCESS; } +ProgressDetail KVDBServiceImpl::HandleGenDetails(const GenDetails &details) +{ + ProgressDetail progressDetail; + if (details.begin() == details.end()) { + return {}; + } + auto genDetail = details.begin()->second; + progressDetail.progress = genDetail.progress; + progressDetail.code = genDetail.code; + auto tableDetails = genDetail.details; + if (tableDetails.begin() == tableDetails.end()) { + return progressDetail; + } + auto genTableDetail = tableDetails.begin()->second; + auto &tableDetail = progressDetail.details; + Constant::Copy(&tableDetail, &genTableDetail); + return progressDetail; +} + Status KVDBServiceImpl::SetSyncParam(const AppId &appId, const StoreId &storeId, const KvSyncParam &syncParam) { if (syncParam.allowedDelayMs > 0 && syncParam.allowedDelayMs < KvStoreSyncManager::SYNC_MIN_DELAY_MS) { @@ -659,12 +689,10 @@ Status KVDBServiceImpl::Subscribe(const AppId &appId, const StoreId &storeId, sp if (agent.pid_ != IPCSkeleton::GetCallingPid()) { agent.ReInit(IPCSkeleton::GetCallingPid(), appId); } - if (agent.watcher_ == nullptr) { - isCreate = true; - agent.SetWatcher(std::make_shared()); - } - agent.SetObserver(iface_cast(observer->AsObject())); - agent.count_++; + isCreate = true; + auto watcher = std::make_shared(); + watcher->SetObserver(observer); + agent.watchers_[storeId.storeId].insert(watcher); return true; }); if (isCreate) { @@ -680,12 +708,19 @@ Status KVDBServiceImpl::Unsubscribe(const AppId &appId, const StoreId &storeId, Anonymous::Change(storeId.storeId).c_str(), tokenId); bool destroyed = false; syncAgents_.ComputeIfPresent(tokenId, [&appId, &storeId, &observer, &destroyed](auto &key, SyncAgent &agent) { - if (agent.count_ > 0) { - agent.count_--; + auto iter = agent.watchers_.find(storeId.storeId); + if (iter == agent.watchers_.end()) { + return true; } - if (agent.count_ == 0) { - destroyed = true; - agent.SetWatcher(nullptr); + for (auto watcher : iter->second) { + if (watcher->GetObserver() == observer) { + destroyed = true; + iter->second.erase(watcher); + break; + } + } + if (iter->second.size() == 0) { + agent.watchers_.erase(storeId.storeId); } return true; }); @@ -701,6 +736,35 @@ Status KVDBServiceImpl::GetBackupPassword(const AppId &appId, const StoreId &sto return (BackupManager::GetInstance().GetPassWord(metaData, password)) ? SUCCESS : ERROR; } +Status KVDBServiceImpl::SetConfig(const AppId &appId, const StoreId &storeId, const StoreConfig &storeConfig) +{ + StoreMetaData meta = GetStoreMetaData(appId, storeId); + auto isCreated = MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta, true); + if (!isCreated) { + return SUCCESS; + } + meta.enableCloud = storeConfig.cloudConfig.enableCloud; + meta.cloudAutoSync = storeConfig.cloudConfig.autoSync; + if (!MetaDataManager::GetInstance().SaveMeta(meta.GetKey(), meta, true)) { + return Status::ERROR; + } + StoreMetaData syncMeta; + if (MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), syncMeta)) { + syncMeta.enableCloud = storeConfig.cloudConfig.enableCloud; + syncMeta.cloudAutoSync = storeConfig.cloudConfig.autoSync; + if (!MetaDataManager::GetInstance().SaveMeta(syncMeta.GetKey(), syncMeta)) { + return Status::ERROR; + } + } + auto stores = AutoCache::GetInstance().GetStoresIfPresent(meta.tokenId, storeId); + for (auto store : stores) { + store->SetConfig({ storeConfig.cloudConfig.enableCloud }); + } + ZLOGI("appId:%{public}s storeId:%{public}s enable:%{public}d", appId.appId.c_str(), + Anonymous::Change(storeId.storeId).c_str(), storeConfig.cloudConfig.enableCloud); + return Status::SUCCESS; +} + Status KVDBServiceImpl::BeforeCreate(const AppId &appId, const StoreId &storeId, const Options &options) { ZLOGD("appId:%{public}s storeId:%{public}s to export data", appId.appId.c_str(), @@ -713,15 +777,23 @@ Status KVDBServiceImpl::BeforeCreate(const AppId &appId, const StoreId &storeId, if (!isCreated) { return SUCCESS; } + StoreMetaDataLocal oldLocal; + MetaDataManager::GetInstance().LoadMeta(meta.GetKeyLocal(), oldLocal, true); + // when user is 0, old store no "isPublic" attr, as well as new store's "isPublic" is true, do not intercept. if (old.storeType != meta.storeType || Constant::NotEqual(old.isEncrypt, meta.isEncrypt) || - old.area != meta.area || !options.persistent || old.dataType != meta.dataType) { - ZLOGE("meta appId:%{public}s storeId:%{public}s type:%{public}d->%{public}d encrypt:%{public}d->%{public}d " - "area:%{public}d->%{public}d persistent:%{public}d dataType:%{public}d->%{public}d", - appId.appId.c_str(), Anonymous::Change(storeId.storeId).c_str(), old.storeType, meta.storeType, - old.isEncrypt, meta.isEncrypt, old.area, meta.area, options.persistent, old.dataType, options.dataType); + old.area != meta.area || !options.persistent || + (Constant::NotEqual(oldLocal.isPublic, options.isPublic) && + (old.user != DEFAULT_USER_ID || !options.isPublic))) { + ZLOGE("meta appId:%{public}s storeId:%{public}s user:%{public}s type:%{public}d->%{public}d " + "encrypt:%{public}d->%{public}d " + "area:%{public}d->%{public}d persistent:%{public}d isPublic:%{public}d->%{public}d", + appId.appId.c_str(), Anonymous::Change(storeId.storeId).c_str(), old.user.c_str(), old.storeType, + meta.storeType, old.isEncrypt, meta.isEncrypt, old.area, meta.area, options.persistent, oldLocal.isPublic, + options.isPublic); return Status::STORE_META_CHANGED; } - if (executors_ != nullptr) { + + if (options.cloudConfig.enableCloud && (!isCreated || !meta.enableCloud) && executors_ != nullptr) { DistributedData::StoreInfo storeInfo; storeInfo.bundleName = appId.appId; storeInfo.instanceId = GetInstIndex(storeInfo.tokenId, appId); @@ -786,14 +858,18 @@ Status KVDBServiceImpl::AfterCreate(const AppId &appId, const StoreId &storeId, int32_t KVDBServiceImpl::OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &appId) { ZLOGI("pid:%{public}d uid:%{public}d appId:%{public}s", pid, uid, appId.c_str()); - syncAgents_.EraseIf([pid](auto &key, SyncAgent &agent) { + CheckerManager::StoreInfo info; + info.uid = uid; + info.tokenId = tokenId; + info.bundleName = appId; + syncAgents_.EraseIf([pid, &info](auto &key, SyncAgent &agent) { if (agent.pid_ != pid) { return false; } - if (agent.watcher_ != nullptr) { - agent.watcher_->ClearObservers(); - agent.ClearObservers(); + if (CheckerManager::GetInstance().IsSwitches(info)) { + MetaDataManager::GetInstance().Unsubscribe(SwitchesMetaData::GetPrefix({})); } + agent.watchers_.clear(); auto stores = AutoCache::GetInstance().GetStoresIfPresent(key); for (auto store : stores) { if (store != nullptr) { @@ -848,42 +924,6 @@ int32_t KVDBServiceImpl::OnUserChange(uint32_t code, const std::string &user, co int32_t KVDBServiceImpl::OnReady(const std::string &device) { - if (device == DeviceManagerAdapter::CLOUD_DEVICE_UUID) { - return SUCCESS; - } - std::vector metaData; - auto prefix = StoreMetaData::GetPrefix({ DMAdapter::GetInstance().GetLocalDevice().uuid }); - if (!MetaDataManager::GetInstance().LoadMeta(prefix, metaData)) { - ZLOGE("load meta failed!"); - return STORE_NOT_FOUND; - } - for (const auto &data : metaData) { - if (!data.isAutoSync) { - continue; - } - ZLOGI("[onReady] appId:%{public}s, storeId:%{public}s", - data.bundleName.c_str(), Anonymous::Change(data.storeId).c_str()); - auto code = DeviceMatrix::GetInstance().GetCode(data); - if (code == DeviceMatrix::INVALID_MASK) { - continue; - } - std::pair mask = { false, 0 }; - if (data.dataType == DataType::TYPE_STATICS) { - mask = DeviceMatrix::GetInstance().GetMask(device, DeviceMatrix::LevelType::STATICS); - } else { - mask = DeviceMatrix::GetInstance().GetMask(device); - } - if (mask.first && ((mask.second & code) != code)) { - continue; - } - SyncInfo syncInfo; - syncInfo.mode = SyncMode::PUSH; - syncInfo.devices = { device }; - auto delay = GetSyncDelayTime(syncInfo.delay, { data.storeId }); - KvStoreSyncManager::GetInstance()->AddSyncOperation(uintptr_t(data.tokenId), delay, - std::bind(&KVDBServiceImpl::DoSync, this, data, syncInfo, std::placeholders::_1, ACTION_SYNC), - std::bind(&KVDBServiceImpl::DoComplete, this, data, syncInfo, RefCount(), std::placeholders::_1)); - } return SUCCESS; } @@ -894,7 +934,6 @@ int32_t KVDBServiceImpl::OnSessionReady(const std::string &device) return SUCCESS; } - SyncOnSessionReady(device); auto stores = AutoSyncMatrix::GetInstance().GetChangedStore(device); for (const auto &store : stores) { ZLOGI("[OnSessionReady] appId:%{public}s, storeId:%{public}s", @@ -902,6 +941,10 @@ int32_t KVDBServiceImpl::OnSessionReady(const std::string &device) SyncInfo syncInfo; syncInfo.mode = SyncMode::PUSH; syncInfo.devices = { device }; + syncInfo.syncId = ++syncId_; + RADAR_REPORT(STANDARD_DEVICE_SYNC, ADD_SYNC_TASK, RADAR_SUCCESS, BIZ_STATE, START, + SYNC_STORE_ID, Anonymous::Change(store.storeId), SYNC_APP_ID, store.bundleName, + CONCURRENT_ID, std::to_string(syncInfo.syncId), SYNC_TYPE, AUTOSYNC); KvStoreSyncManager::GetInstance()->AddSyncOperation(uintptr_t(store.tokenId), 0, std::bind(&KVDBServiceImpl::DoSyncInOrder, this, store, syncInfo, std::placeholders::_1, ACTION_SYNC), std::bind(&KVDBServiceImpl::DoComplete, this, store, syncInfo, RefCount(), std::placeholders::_1)); @@ -909,34 +952,6 @@ int32_t KVDBServiceImpl::OnSessionReady(const std::string &device) return SUCCESS; } -void KVDBServiceImpl::SyncOnSessionReady(const std::string &device) -{ - auto local = DMAdapter::GetInstance().GetLocalDevice().uuid; - std::vector metas; - auto prefix = StoreMetaData::GetPrefix({ local }); - if (!MetaDataManager::GetInstance().LoadMeta(prefix, metas)) { - ZLOGE("load meta failed!"); - return; - } - for (const auto &meta : metas) { - if (!DeviceMatrix::GetInstance().IsStatics(meta) && !DeviceMatrix::GetInstance().IsDynamic(meta)) { - continue; - } - if (!IsRemoteChange(meta, device)) { - continue; - } - SyncInfo syncInfo; - syncInfo.mode = PULL; - syncInfo.delay = 0; - syncInfo.devices = { device }; - ZLOGI("[SyncOnSessionReady] appId:%{public}s, storeId:%{public}s", meta.bundleName.c_str(), - Anonymous::Change(meta.storeId).c_str()); - KvStoreSyncManager::GetInstance()->AddSyncOperation(uintptr_t(meta.tokenId), syncInfo.delay, - std::bind(&KVDBServiceImpl::DoSyncInOrder, this, meta, syncInfo, std::placeholders::_1, ACTION_SYNC), - std::bind(&KVDBServiceImpl::DoComplete, this, meta, syncInfo, RefCount(), std::placeholders::_1)); - } -} - bool KVDBServiceImpl::IsRemoteChange(const StoreMetaData &metaData, const std::string &device) { auto code = DeviceMatrix::GetInstance().GetCode(metaData); @@ -977,6 +992,8 @@ void KVDBServiceImpl::AddOptions(const Options &options, StoreMetaData &metaData metaData.account = AccountDelegate::GetInstance()->GetCurrentAccountId(); metaData.isNeedCompress = options.isNeedCompress; metaData.dataType = options.dataType; + metaData.enableCloud = options.cloudConfig.enableCloud; + metaData.cloudAutoSync = options.cloudConfig.autoSync; } void KVDBServiceImpl::SaveLocalMetaData(const Options &options, const StoreMetaData &metaData) @@ -1041,7 +1058,7 @@ int32_t KVDBServiceImpl::GetInstIndex(uint32_t tokenId, const AppId &appId) return tokenInfo.instIndex; } -KVDBServiceImpl::DBResult KVDBServiceImpl::HandleGenDetails(const GenDetails &details) +KVDBServiceImpl::DBResult KVDBServiceImpl::HandleGenBriefDetails(const GenDetails &details) { DBResult dbResults{}; for (const auto &[id, detail] : details) { @@ -1050,6 +1067,79 @@ KVDBServiceImpl::DBResult KVDBServiceImpl::HandleGenDetails(const GenDetails &de return dbResults; } +void KVDBServiceImpl::DoCloudSync(bool isStatic) +{ + if (isStatic) { + auto staticStores = CheckerManager::GetInstance().GetStaticStores(); + for (auto &staticStore : staticStores) { + AppId appId = { staticStore.bundleName }; + StoreId storeId = { staticStore.storeId }; + auto status = CloudSync(appId, storeId, {}); + if (status != SUCCESS) { + ZLOGW("cloud sync failed:%{public}d, appId:%{public}s storeId:%{public}s", status, + staticStore.bundleName.c_str(), Anonymous::Change(staticStore.storeId).c_str()); + } + } + return; + } + auto dynamicStores = CheckerManager::GetInstance().GetDynamicStores(); + for (auto &dynamicStore : dynamicStores) { + AppId appId = { dynamicStore.bundleName }; + StoreId storeId = { dynamicStore.storeId }; + auto status = CloudSync(appId, storeId, {}); + if (status != SUCCESS) { + ZLOGW("cloud sync failed:%{public}d, appId:%{public}s storeId:%{public}s", status, + dynamicStore.bundleName.c_str(), Anonymous::Change(dynamicStore.storeId).c_str()); + } + } +} + +Status KVDBServiceImpl::DoCloudSync(const StoreMetaData &meta, const SyncInfo &syncInfo) +{ + if (!meta.enableCloud) { + ZLOGE("appId:%{public}s storeId:%{public}s instanceId:%{public}d not supports cloud sync", meta.appId.c_str(), + Anonymous::Change(meta.storeId).c_str(), meta.instanceId); + return Status::NOT_SUPPORT; + } + auto instance = CloudServer::GetInstance(); + if (instance == nullptr) { + return Status::CLOUD_DISABLED; + } + if (!DMAdapter::GetInstance().IsNetworkAvailable()) { + return Status::NETWORK_ERROR; + } + std::vector users; + if (meta.user != StoreMetaData::ROOT_USER) { + users.push_back(std::atoi(meta.user.c_str())); + } else if (!AccountDelegate::GetInstance()->QueryForegroundUsers(users)) { + ZLOGE("appId:%{public}s storeId:%{public}s instanceId:%{public}d. no foreground user!", meta.appId.c_str(), + Anonymous::Change(meta.storeId).c_str(), meta.instanceId); + return Status::CLOUD_DISABLED; + } + bool res = false; + for (auto user : users) { + res = instance->IsSupportCloud(user) || res; + } + if (!res) { + return Status::CLOUD_DISABLED; + } + + DistributedData::StoreInfo storeInfo; + storeInfo.bundleName = meta.bundleName; + storeInfo.user = atoi(meta.user.c_str()); + storeInfo.tokenId = meta.tokenId; + storeInfo.storeName = meta.storeId; + GenAsync syncCallback = [tokenId = storeInfo.tokenId, seqId = syncInfo.seqId, this](const GenDetails &details) { + OnAsyncComplete(tokenId, seqId, HandleGenDetails(details)); + }; + auto mixMode = static_cast(GeneralStore::MixMode(GeneralStore::CLOUD_TIME_FIRST, + meta.isAutoSync ? GeneralStore::AUTO_SYNC_MODE : GeneralStore::MANUAL_SYNC_MODE)); + auto info = ChangeEvent::EventInfo(mixMode, 0, false, nullptr, syncCallback); + auto evt = std::make_unique(std::move(storeInfo), std::move(info)); + EventCenter::GetInstance().PostEvent(std::move(evt)); + return SUCCESS; +} + Status KVDBServiceImpl::DoSync(const StoreMetaData &meta, const SyncInfo &info, const SyncEnd &complete, int32_t type) { ZLOGD("seqId:0x%{public}" PRIx64 " type:%{public}d remote:%{public}zu appId:%{public}s storeId:%{public}s", @@ -1075,25 +1165,17 @@ Status KVDBServiceImpl::DoSyncInOrder( info.seqId, info.devices.size(), meta.bundleName.c_str(), Anonymous::Change(meta.storeId).c_str()); return Status::ERROR; } - bool isOnline = false; - bool isAfterMeta = false; - for (const auto &uuid : uuids) { - if (!DMAdapter::GetInstance().IsDeviceReady(uuid)) { - isOnline = true; - break; - } - auto metaData = meta; - metaData.deviceId = uuid; - CapMetaData capMeta; - auto capKey = CapMetaRow::GetKeyFor(uuid); - if (!MetaDataManager::GetInstance().LoadMeta(std::string(capKey.begin(), capKey.end()), capMeta) - || !MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData)) { - isAfterMeta = true; - } - } - if (!isOnline && isAfterMeta) { + if (IsNeedMetaSync(meta, uuids)) { + auto recv = DeviceMatrix::GetInstance().GetRecvLevel(uuids[0], + static_cast(DataType::TYPE_DYNAMICAL)); + RADAR_REPORT(STANDARD_DEVICE_SYNC, STANDARD_META_SYNC, RADAR_START, + SYNC_STORE_ID, Anonymous::Change(meta.storeId), SYNC_APP_ID, meta.bundleName, CONCURRENT_ID, + std::to_string(info.syncId), DATA_TYPE, meta.dataType, WATER_VERSION, recv.second); auto result = MetaDataManager::GetInstance().Sync( uuids, [this, meta, info, complete, type](const auto &results) { + RADAR_REPORT(STANDARD_DEVICE_SYNC, STANDARD_META_SYNC, RADAR_SUCCESS, + SYNC_STORE_ID, Anonymous::Change(meta.storeId), SYNC_APP_ID, meta.bundleName, CONCURRENT_ID, + std::to_string(info.syncId), DATA_TYPE, meta.dataType); auto ret = ProcessResult(results); if (ret.first.empty()) { DoComplete(meta, info, RefCount(), ret.second); @@ -1103,11 +1185,51 @@ Status KVDBServiceImpl::DoSyncInOrder( ZLOGD("data sync status:%{public}d appId:%{public}s, storeId:%{public}s", static_cast(status), meta.bundleName.c_str(), Anonymous::Change(meta.storeId).c_str()); }); + if (!result) { + RADAR_REPORT(STANDARD_DEVICE_SYNC, STANDARD_META_SYNC, RADAR_FAILED, ERROR_CODE, Status::ERROR, + BIZ_STATE, END, SYNC_STORE_ID, Anonymous::Change(meta.storeId), SYNC_APP_ID, meta.bundleName, + CONCURRENT_ID, std::to_string(info.syncId), DATA_TYPE, meta.dataType); + } return result ? Status::SUCCESS : Status::ERROR; } return DoSyncBegin(uuids, meta, info, complete, type); } +bool KVDBServiceImpl::IsNeedMetaSync(const StoreMetaData &meta, const std::vector &uuids) +{ + bool isAfterMeta = false; + for (const auto &uuid : uuids) { + auto metaData = meta; + metaData.deviceId = uuid; + CapMetaData capMeta; + auto capKey = CapMetaRow::GetKeyFor(uuid); + if (!MetaDataManager::GetInstance().LoadMeta(std::string(capKey.begin(), capKey.end()), capMeta) || + !MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), metaData)) { + isAfterMeta = true; + break; + } + auto [exist, mask] = DeviceMatrix::GetInstance().GetRemoteMask(uuid); + if ((mask & DeviceMatrix::META_STORE_MASK) == DeviceMatrix::META_STORE_MASK) { + isAfterMeta = true; + break; + } + } + return isAfterMeta; +} + +StoreMetaData KVDBServiceImpl::GetDistributedDataMeta(const std::string &deviceId) +{ + StoreMetaData meta; + meta.deviceId = deviceId; + meta.bundleName = Bootstrap::GetInstance().GetProcessLabel(); + meta.storeId = Bootstrap::GetInstance().GetMetaDBName(); + meta.user = DEFAULT_USER_ID; + if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta)) { + ZLOGE("Load meta fail, device: %{public}s", Anonymous::Change(deviceId).c_str()); + } + return meta; +} + KVDBServiceImpl::SyncResult KVDBServiceImpl::ProcessResult(const std::map &results) { std::map dbResults; @@ -1131,28 +1253,49 @@ Status KVDBServiceImpl::DoSyncBegin(const std::vector &devices, con return Status::INVALID_ARGUMENT; } auto watcher = GetWatchers(meta.tokenId, meta.storeId); + RADAR_REPORT(STANDARD_DEVICE_SYNC, OPEN_STORE, RADAR_START, SYNC_STORE_ID, Anonymous::Change(meta.storeId), + SYNC_APP_ID, meta.bundleName, CONCURRENT_ID, info.syncId, DATA_TYPE, meta.dataType); auto store = AutoCache::GetInstance().GetStore(meta, watcher); if (store == nullptr) { ZLOGE("GetStore failed! appId:%{public}s storeId:%{public}s dir:%{public}s", meta.bundleName.c_str(), Anonymous::Change(meta.storeId).c_str(), meta.dataDir.c_str()); + RADAR_REPORT(STANDARD_DEVICE_SYNC, OPEN_STORE, RADAR_FAILED, ERROR_CODE, Status::ERROR, BIZ_STATE, END, + SYNC_STORE_ID, Anonymous::Change(meta.storeId), SYNC_APP_ID, meta.bundleName, CONCURRENT_ID, + std::to_string(info.syncId), DATA_TYPE, meta.dataType); return Status::ERROR; } + RADAR_REPORT(STANDARD_DEVICE_SYNC, OPEN_STORE, RADAR_SUCCESS, SYNC_STORE_ID, Anonymous::Change(meta.storeId), + SYNC_APP_ID, meta.bundleName, CONCURRENT_ID, std::to_string(info.syncId), DATA_TYPE, meta.dataType); KVDBQuery query(info.query); if (!query.IsValidQuery()) { ZLOGE("failed DBQuery:%{public}s", Anonymous::Change(info.query).c_str()); return Status::INVALID_ARGUMENT; } auto mode = ConvertGeneralSyncMode(SyncMode(info.mode), SyncAction(type)); + if (GeneralStore::GetSyncMode(mode) < KVDBGeneralStore::NEARBY_END) { + store->SetEqualIdentifier(meta.appId, meta.storeId); + } SyncParam syncParam{}; syncParam.mode = mode; + RADAR_REPORT(STANDARD_DEVICE_SYNC, START_SYNC, RADAR_START, SYNC_STORE_ID, Anonymous::Change(meta.storeId), + SYNC_APP_ID, meta.bundleName, CONCURRENT_ID, std::to_string(info.syncId), DATA_TYPE, meta.dataType); auto ret = store->Sync( devices, query, [this, complete](const GenDetails &result) mutable { - auto deviceStatus = HandleGenDetails(result); + auto deviceStatus = HandleGenBriefDetails(result); complete(deviceStatus); }, syncParam); - return Status(ret); + auto status = Status(ret); + if (status != Status::SUCCESS) { + RADAR_REPORT(STANDARD_DEVICE_SYNC, START_SYNC, RADAR_FAILED, ERROR_CODE, status, BIZ_STATE, END, + SYNC_STORE_ID, Anonymous::Change(meta.storeId), SYNC_APP_ID, meta.bundleName, CONCURRENT_ID, + std::to_string(info.syncId), DATA_TYPE, meta.dataType); + } else { + RADAR_REPORT(STANDARD_DEVICE_SYNC, START_SYNC, RADAR_SUCCESS, SYNC_STORE_ID, Anonymous::Change(meta.storeId), + SYNC_APP_ID, meta.bundleName, CONCURRENT_ID, std::to_string(info.syncId), DATA_TYPE, meta.dataType); + } + return status; } Status KVDBServiceImpl::DoComplete(const StoreMetaData &meta, const SyncInfo &info, RefCount refCount, @@ -1160,6 +1303,9 @@ Status KVDBServiceImpl::DoComplete(const StoreMetaData &meta, const SyncInfo &in { ZLOGD("seqId:0x%{public}" PRIx64 " tokenId:0x%{public}x remote:%{public}zu", info.seqId, meta.tokenId, dbResult.size()); + RADAR_REPORT(STANDARD_DEVICE_SYNC, FINISH_SYNC, RADAR_SUCCESS, BIZ_STATE, END, + SYNC_STORE_ID, Anonymous::Change(meta.storeId), SYNC_APP_ID, meta.bundleName, CONCURRENT_ID, + std::to_string(info.syncId), DATA_TYPE, meta.dataType); std::map result; for (auto &[key, status] : dbResult) { result[key] = ConvertDbStatus(status); @@ -1330,50 +1476,28 @@ std::vector KVDBServiceImpl::ConvertDevices(const std::vectorsecond) { + watchers.insert(watcher); + } + } + return true; + }); + return watchers; } void KVDBServiceImpl::SyncAgent::ReInit(pid_t pid, const AppId &appId) { - ZLOGW("pid:%{public}d->%{public}d appId:%{public}s notifier:%{public}d observer:%{public}zu", pid, pid_, - appId_.appId.c_str(), notifier_ == nullptr, observers_.size()); + ZLOGW("pid:%{public}d->%{public}d appId:%{public}s notifier:%{public}d", pid, pid_, + appId_.appId.c_str(), notifier_ == nullptr); pid_ = pid; appId_ = appId; notifier_ = nullptr; delayTimes_.clear(); - count_ = 0; - watcher_ = nullptr; - observers_.clear(); -} - -void KVDBServiceImpl::SyncAgent::SetWatcher(std::shared_ptr watcher) -{ - if (watcher_ != watcher) { - watcher_ = watcher; - if (watcher_ != nullptr) { - watcher_->SetObservers(observers_); - } - } -} - -void KVDBServiceImpl::SyncAgent::SetObserver(sptr observer) -{ - observers_.insert(observer); - if (watcher_ != nullptr) { - watcher_->SetObservers(observers_); - } -} - -void KVDBServiceImpl::SyncAgent::ClearObservers() -{ - observers_.clear(); - if (watcher_ != nullptr) { - watcher_->ClearObservers(); - } + watchers_.clear(); } int32_t KVDBServiceImpl::OnBind(const BindInfo &bindInfo) diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.h b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.h index e63539b3..a43b2045 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.h +++ b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.h @@ -46,9 +46,10 @@ public: Status AfterCreate(const AppId &appId, const StoreId &storeId, const Options &options, const std::vector &password) override; Status Delete(const AppId &appId, const StoreId &storeId) override; - Status CloudSync(const AppId &appId, const StoreId &storeId) override; - Status Sync(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) override; - Status SyncExt(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) override; + Status Close(const AppId &appId, const StoreId &storeId) override; + Status CloudSync(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) override; + Status Sync(const AppId &appId, const StoreId &storeId, SyncInfo &syncInfo) override; + Status SyncExt(const AppId &appId, const StoreId &storeId, SyncInfo &syncInfo) override; Status RegServiceNotifier(const AppId &appId, sptr notifier) override; Status UnregServiceNotifier(const AppId &appId) override; Status SetSyncParam(const AppId &appId, const StoreId &storeId, const KvSyncParam &syncParam) override; @@ -67,6 +68,7 @@ public: Status GetSwitch(const AppId &appId, const std::string &networkId, SwitchData &data) override; Status SubscribeSwitchData(const AppId &appId) override; Status UnsubscribeSwitchData(const AppId &appId) override; + Status SetConfig(const AppId &appId, const StoreId &storeId, const StoreConfig &storeConfig) override; int32_t OnBind(const BindInfo &bindInfo) override; int32_t OnInitialize() override; int32_t OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &appId) override; @@ -96,17 +98,13 @@ private: struct SyncAgent { pid_t pid_ = 0; int32_t switchesObserverCount_ = 0; - bool changed_ = false; + bool staticsChanged_ = false; + bool dynamicChanged_ = false; AppId appId_; - int32_t count_ = 0; sptr notifier_; std::map delayTimes_; - std::shared_ptr watcher_; - std::set> observers_; + std::map>> watchers_; void ReInit(pid_t pid, const AppId &appId); - void SetObserver(sptr observer); - void SetWatcher(std::shared_ptr watcher); - void ClearObservers(); }; class Factory { public: @@ -119,8 +117,12 @@ private: void Init(); void AddOptions(const Options &options, StoreMetaData &metaData); StoreMetaData GetStoreMetaData(const AppId &appId, const StoreId &storeId); + StoreMetaData GetDistributedDataMeta(const std::string &deviceId); StrategyMeta GetStrategyMeta(const AppId &appId, const StoreId &storeId); int32_t GetInstIndex(uint32_t tokenId, const AppId &appId); + bool IsNeedMetaSync(const StoreMetaData &meta, const std::vector &uuids); + Status DoCloudSync(const StoreMetaData &meta, const SyncInfo &syncInfo); + void DoCloudSync(bool isStatic); Status DoSync(const StoreMetaData &meta, const SyncInfo &info, const SyncEnd &complete, int32_t type); Status DoSyncInOrder(const StoreMetaData &meta, const SyncInfo &info, const SyncEnd &complete, int32_t type); Status DoSyncBegin(const std::vector &devices, const StoreMetaData &meta, @@ -134,7 +136,9 @@ private: SyncMode GetSyncMode(bool local, bool remote) const; std::vector ConvertDevices(const std::vector &deviceIds) const; DistributedData::GeneralStore::SyncMode ConvertGeneralSyncMode(SyncMode syncMode, SyncAction syncAction) const; - DBResult HandleGenDetails(const DistributedData::GenDetails &details); + DBResult HandleGenBriefDetails(const DistributedData::GenDetails &details); + ProgressDetail HandleGenDetails(const DistributedData::GenDetails &details); + void OnAsyncComplete(uint32_t tokenId, uint64_t seqNum, ProgressDetail &&detail); DistributedData::AutoCache::Watchers GetWatchers(uint32_t tokenId, const std::string &storeId); using SyncResult = std::pair, std::map>; SyncResult ProcessResult(const std::map &results); @@ -144,12 +148,13 @@ private: void RegisterMatrixChange(); void DumpKvServiceInfo(int fd, std::map> ¶ms); void TryToSync(const StoreMetaData &metaData, bool force = false); - void SyncOnSessionReady(const std::string &device); - void OldOnlineSync(const StoreMetaData &data, const std::string &deviceId, RefCount refCount, uint16_t mask); + void OnStaticsChange(std::pair mask); + void OnDynamicChange(std::pair mask); bool IsRemoteChange(const StoreMetaData &metaData, const std::string &device); static Factory factory_; ConcurrentMap syncAgents_; std::shared_ptr executors_; + std::atomic_uint64_t syncId_ = 0; }; } // namespace OHOS::DistributedKv -#endif // OHOS_DISTRIBUTED_DATA_SERVICE_KVDB_SERVICE_IMPL_H +#endif // OHOS_DISTRIBUTED_DATA_SERVICE_KVDB_SERVICE_IMPL_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp index 9326922a..c224ccaa 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp +++ b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp @@ -16,10 +16,10 @@ #include "kvdb_service_stub.h" #include "ipc_skeleton.h" -#include "itypes_util.h" +#include "kv_types_util.h" #include "log_print.h" -#include "utils/constant.h" #include "utils/anonymous.h" +#include "utils/constant.h" namespace OHOS::DistributedKv { using namespace OHOS::DistributedData; const KVDBServiceStub::Handler @@ -44,10 +44,12 @@ const KVDBServiceStub::Handler &KVDBServiceStub::OnSyncExt, &KVDBServiceStub::OnCloudSync, &KVDBServiceStub::OnNotifyDataChange, + &KVDBServiceStub::OnSetConfig, &KVDBServiceStub::OnPutSwitch, &KVDBServiceStub::OnGetSwitch, &KVDBServiceStub::OnSubscribeSwitchData, &KVDBServiceStub::OnUnsubscribeSwitchData, + &KVDBServiceStub::OnClose, }; int KVDBServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply) @@ -173,6 +175,17 @@ int32_t KVDBServiceStub::OnDelete(const AppId &appId, const StoreId &storeId, Me return ERR_NONE; } +int32_t KVDBServiceStub::OnClose(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply) +{ + int32_t status = Close(appId, storeId); + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x appId:%{public}s storeId:%{public}s", status, appId.appId.c_str(), + Anonymous::Change(storeId.storeId).c_str()); + return IPC_STUB_WRITE_PARCEL_ERR; + } + return ERR_NONE; +} + int32_t KVDBServiceStub::OnSync(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply) { SyncInfo syncInfo; @@ -193,9 +206,16 @@ int32_t KVDBServiceStub::OnSync(const AppId &appId, const StoreId &storeId, Mess int32_t KVDBServiceStub::OnCloudSync( const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply) { - int32_t status = CloudSync(appId, storeId); + SyncInfo syncInfo; + if (!ITypesUtil::Unmarshal(data, syncInfo.seqId)) { + ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", appId.appId.c_str(), + Anonymous::Change(storeId.storeId).c_str()); + return IPC_STUB_INVALID_DATA_ERR; + } + int32_t status = CloudSync(appId, storeId, syncInfo); if (!ITypesUtil::Marshal(reply, status)) { - ZLOGE("Marshal status:0x%{public}x", status); + ZLOGE("Marshal status:0x%{public}x appId:%{public}s storeId:%{public}s", status, appId.appId.c_str(), + Anonymous::Change(storeId.storeId).c_str()); return IPC_STUB_WRITE_PARCEL_ERR; } return ERR_NONE; @@ -482,4 +502,21 @@ int32_t KVDBServiceStub::OnUnsubscribeSwitchData( } return ERR_NONE; } + +int32_t KVDBServiceStub::OnSetConfig(const AppId &appId, const StoreId &storeId, MessageParcel &data, + MessageParcel &reply) +{ + StoreConfig storeConfig; + if (!ITypesUtil::Unmarshal(data, storeConfig)) { + ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", appId.appId.c_str(), + Anonymous::Change(storeId.storeId).c_str()); + return IPC_STUB_INVALID_DATA_ERR; + } + int32_t status = SetConfig(appId, storeId, storeConfig); + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal status:0x%{public}x appId:%{public}s", status, appId.appId.c_str()); + return IPC_STUB_WRITE_PARCEL_ERR; + } + return ERR_NONE; +} } // namespace OHOS::DistributedKv diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_stub.h b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_stub.h index 672e43b1..71abe634 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_stub.h +++ b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_stub.h @@ -21,7 +21,7 @@ #include "kvdb_service.h" #include "feature/feature_system.h" namespace OHOS::DistributedKv { -class API_EXPORT KVDBServiceStub : public KVDBService, public DistributedData::FeatureSystem::Feature { +class KVDBServiceStub : public KVDBService, public DistributedData::FeatureSystem::Feature { public: int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply) override; @@ -33,6 +33,7 @@ private: int32_t OnBeforeCreate(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); int32_t OnAfterCreate(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); int32_t OnDelete(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); + int32_t OnClose(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); int32_t OnSync(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); int32_t OnCloudSync(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); int32_t OnRegServiceNotifier( @@ -53,10 +54,11 @@ private: int32_t OnNotifyDataChange(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); int32_t OnPutSwitch(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); int32_t OnGetSwitch(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); - int32_t OnSubscribeSwitchData( - const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); - int32_t OnUnsubscribeSwitchData( - const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); + int32_t OnSubscribeSwitchData(const AppId &appId, const StoreId &storeId, MessageParcel &data, + MessageParcel &reply); + int32_t OnUnsubscribeSwitchData(const AppId &appId, const StoreId &storeId, MessageParcel &data, + MessageParcel &reply); + int32_t OnSetConfig(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply); static const Handler HANDLERS[static_cast(KVDBServiceInterfaceCode::TRANS_BUTT)]; bool CheckPermission(uint32_t code, const StoreInfo &storeInfo); diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_watcher.cpp b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_watcher.cpp index 231caae3..f98da5f5 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_watcher.cpp +++ b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_watcher.cpp @@ -33,8 +33,8 @@ int32_t KVDBWatcher::OnChange(const Origin &origin, const PRIFields &primaryFiel auto store = origin.store; auto changeData = values.find(store); if (changeData != values.end()) { - auto observers = GetObservers(); - if (observers.empty()) { + auto observer = GetObserver(); + if (observer == nullptr) { return E_NOT_INIT; } std::vector keys[OP_BUTT]{}; @@ -44,9 +44,7 @@ int32_t KVDBWatcher::OnChange(const Origin &origin, const PRIFields &primaryFiel DataOrigin dataOrigin; dataOrigin.id = origin.id; dataOrigin.store = origin.store; - for (auto &observer : observers) { - observer->OnChange(dataOrigin, std::move(keys)); - } + observer->OnChange(dataOrigin, std::move(keys)); } return E_OK; } @@ -56,37 +54,29 @@ int32_t KVDBWatcher::OnChange(const Origin &origin, const Fields &fields, Change auto store = origin.store; auto changeData = datas.find(store); if (changeData != datas.end()) { - auto observers = GetObservers(); - if (observers.empty()) { + auto observer = GetObserver(); + if (observer == nullptr) { return E_NOT_INIT; } auto inserts = ConvertToEntries(changeData->second[OP_INSERT]); auto updates = ConvertToEntries(changeData->second[OP_UPDATE]); auto deletes = ConvertToEntries(changeData->second[OP_DELETE]); ChangeNotification change(std::move(inserts), std::move(updates), std::move(deletes), {}, false); - for (auto &observer : observers) { - observer->OnChange(change); - } + observer->OnChange(change); } return E_OK; } -std::set> KVDBWatcher::GetObservers() const +sptr KVDBWatcher::GetObserver() const { std::shared_lock lock(mutex_); - return observers_; -} - -void KVDBWatcher::SetObservers(std::set> observers) -{ - std::unique_lock lock(mutex_); - observers_ = std::move(observers); + return observer_; } -void KVDBWatcher::ClearObservers() +void KVDBWatcher::SetObserver(sptr observer) { std::unique_lock lock(mutex_); - observers_.clear(); + observer_ = std::move(observer); } std::vector KVDBWatcher::ConvertToEntries(const std::vector &values) diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_watcher.h b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_watcher.h index 407ced50..932ab262 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_watcher.h +++ b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_watcher.h @@ -29,15 +29,14 @@ public: KVDBWatcher(); int32_t OnChange(const Origin &origin, const PRIFields &primaryFields, ChangeInfo &&values) override; int32_t OnChange(const Origin &origin, const GeneralWatcher::Fields &fields, ChangeData &&datas) override; - std::set> GetObservers() const; - void SetObservers(std::set> observers); - void ClearObservers(); + sptr GetObserver() const; + void SetObserver(sptr observer); private: std::vector ConvertToEntries(const std::vector &values); std::vector ConvertToKeys(const std::vector &values); mutable std::shared_mutex mutex_; - std::set> observers_; + sptr observer_; }; } // namespace OHOS::DistributedKv #endif // OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_KVDB_WATCHER_H diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/user_delegate.cpp b/datamgr_service/services/distributeddataservice/service/kvdb/user_delegate.cpp index 2c6a5c95..a40202e3 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/user_delegate.cpp +++ b/datamgr_service/services/distributeddataservice/service/kvdb/user_delegate.cpp @@ -153,7 +153,11 @@ void UserDelegate::Init(const std::shared_ptr& executors) MetaDataManager::GetInstance().Subscribe( UserMetaRow::KEY_PREFIX, [this](const std::string &key, const std::string &value, int32_t flag) -> auto { UserMetaData metaData; - UserMetaData::Unmarshall(value, metaData); + if (value.empty()) { + MetaDataManager::GetInstance().LoadMeta(key, metaData); + } else { + UserMetaData::Unmarshall(value, metaData); + } ZLOGD("flag:%{public}d, value:%{public}s", flag, Anonymous::Change(metaData.deviceId).c_str()); if (metaData.deviceId == GetLocalDeviceId()) { ZLOGD("ignore local device user meta change"); @@ -207,4 +211,4 @@ std::string UserDelegate::LocalUserObserver::Name() { return "user_delegate"; } -} // namespace OHOS::DistributedData +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/matrix/include/device_matrix.h b/datamgr_service/services/distributeddataservice/service/matrix/include/device_matrix.h index 75748278..4fd6bc5c 100644 --- a/datamgr_service/services/distributeddataservice/service/matrix/include/device_matrix.h +++ b/datamgr_service/services/distributeddataservice/service/matrix/include/device_matrix.h @@ -46,10 +46,10 @@ public: DYNAMIC, BUTT, }; - enum ChangeType : int32_t { - CHANGE_LOCAL = 0, - CHANGE_REMOTE, - CHANGE_ALL, + enum ChangeType : uint32_t { + CHANGE_LOCAL = 0x1, + CHANGE_REMOTE = 0x2, + CHANGE_ALL = 0x3, CHANGE_BUTT }; struct DataLevel { @@ -59,7 +59,7 @@ public: uint16_t switchesLen = INVALID_LENGTH; bool IsValid() const; }; - + static DeviceMatrix &GetInstance(); bool Initialize(uint32_t token, std::string storeId); void Online(const std::string &device, RefCount refCount = {}); @@ -72,25 +72,25 @@ public: LevelType type = LevelType::DYNAMIC, ChangeType changeType = ChangeType::CHANGE_ALL); void OnExchanged(const std::string &device, const StoreMetaData &metaData, ChangeType type = ChangeType::CHANGE_ALL); + void UpdateLevel(const std::string &device, uint16_t level, LevelType type, bool isConsistent = false); void Clear(); - void RegRemoteChange(std::function observer); + void RegRemoteChange(std::function)> observer); void SetExecutor(std::shared_ptr executors); uint16_t GetCode(const StoreMetaData &metaData); std::pair GetMask(const std::string &device, LevelType type = LevelType::DYNAMIC); std::pair GetRemoteMask(const std::string &device, LevelType type = LevelType::DYNAMIC); - std::pair GetRecvLevel(const std::string &device, LevelType type = LevelType::DYNAMIC); - std::pair GetConsLevel(const std::string &device, LevelType type = LevelType::DYNAMIC); + std::pair GetRecvLevel(const std::string &device, LevelType type); + std::pair GetConsLevel(const std::string &device, LevelType type); std::pair IsConsistent(const std::string &device); - std::pair GetMatrixMeta(const std::string &device, bool IsConsistent = false); + std::pair GetMatrixMeta(const std::string &device, bool isConsistent = false); std::map GetRemoteDynamicMask(); bool IsDynamic(const StoreMetaData &metaData); bool IsStatics(const StoreMetaData &metaData); - bool IsSupportBroadcast(); + bool IsSupportMatrix(); private: static constexpr uint32_t RESET_MASK_DELAY = 10; // min static constexpr uint32_t CURRENT_VERSION = 3; - static constexpr uint16_t OLD_MASK = 0x000E; static constexpr uint16_t CURRENT_DYNAMIC_MASK = 0x0006; static constexpr uint16_t CURRENT_STATICS_MASK = 0x0003; static constexpr size_t MAX_DEVICES = 64; @@ -122,7 +122,7 @@ private: return data &= 0xFFF0; } struct Mask { - uint16_t dynamic = META_STORE_MASK | OLD_MASK; // META_STORE_MASK | CURRENT_DYNAMIC_MASK + uint16_t dynamic = META_STORE_MASK | CURRENT_DYNAMIC_MASK; uint16_t statics = CURRENT_STATICS_MASK; void SetDynamicMask(uint16_t mask); void SetStaticsMask(uint16_t mask); @@ -141,7 +141,7 @@ private: MatrixMetaData GetMatrixInfo(const std::string &device); static inline uint16_t ConvertIndex(uint16_t code); - MatrixEvent::MatrixData lastest_; + MatrixEvent::MatrixData lasts_; std::mutex taskMutex_; std::shared_ptr executors_; TaskId task_ = ExecutorPool::INVALID_TASK_ID; @@ -153,11 +153,10 @@ private: std::map onLines_; std::map offLines_; std::map remotes_; - std::vector dynamicApps_ = { "distributed_device_profile_service", "bundle_manager_service", - "dtbhardware_manager_service" }; - std::vector staticsApps_ = { "distributed_device_profile_service", "dtbhardware_manager_service" }; - std::function observer_; - LRUBucket matrixs_{ MAX_DEVICES }; + std::vector dynamicApps_; + std::vector staticsApps_; + std::function)> observer_; + LRUBucket matrices_{ MAX_DEVICES }; LRUBucket versions_{ MAX_DEVICES }; }; } // namespace OHOS::DistributedData diff --git a/datamgr_service/services/distributeddataservice/service/matrix/src/auto_sync_matrix.cpp b/datamgr_service/services/distributeddataservice/service/matrix/src/auto_sync_matrix.cpp index 42d07555..c9986722 100644 --- a/datamgr_service/services/distributeddataservice/service/matrix/src/auto_sync_matrix.cpp +++ b/datamgr_service/services/distributeddataservice/service/matrix/src/auto_sync_matrix.cpp @@ -19,12 +19,14 @@ #include "bootstrap.h" #include "checker/checker_manager.h" #include "device_matrix.h" +#include "device_manager_adapter.h" #include "log_print.h" #include "metadata/meta_data_manager.h" #include "utils/anonymous.h" #include "utils/converter.h" namespace OHOS::DistributedData { +using DMAdapter = DeviceManagerAdapter; AutoSyncMatrix &AutoSyncMatrix::GetInstance() { static AutoSyncMatrix instance; @@ -33,11 +35,14 @@ AutoSyncMatrix &AutoSyncMatrix::GetInstance() AutoSyncMatrix::AutoSyncMatrix() { - MetaDataManager::GetInstance().Subscribe(StoreMetaData::GetPrefix({}), - [this](const std::string &, const std::string &meta, int32_t action) -> bool { + auto deviceId = DMAdapter::GetInstance().GetLocalDevice().uuid; + MetaDataManager::GetInstance().Subscribe(StoreMetaData::GetPrefix({ deviceId }), + [this](const std::string &key, const std::string &meta, int32_t action) -> bool { StoreMetaData metaData; - if (!StoreMetaData::Unmarshall(meta, metaData)) { - return true; + if (meta.empty()) { + MetaDataManager::GetInstance().LoadMeta(key, metaData); + } else { + StoreMetaData::Unmarshall(meta, metaData); } if (!IsAutoSync(metaData)) { return true; @@ -68,8 +73,9 @@ AutoSyncMatrix::~AutoSyncMatrix() void AutoSyncMatrix::Initialize() { + auto deviceId = DMAdapter::GetInstance().GetLocalDevice().uuid; std::vector metas; - if (!MetaDataManager::GetInstance().LoadMeta(StoreMetaData::GetPrefix({}), metas)) { + if (!MetaDataManager::GetInstance().LoadMeta(StoreMetaData::GetPrefix({ deviceId }), metas)) { ZLOGE("load meta failed."); return; } @@ -95,6 +101,10 @@ bool AutoSyncMatrix::IsAutoSync(const StoreMetaData &meta) void AutoSyncMatrix::AddStore(const StoreMetaData &meta) { std::lock_guard lock(mutex_); + auto it = std::find(metas_.begin(), metas_.end(), meta); + if (it != metas_.end()) { + return; + } metas_.emplace_back(std::move(meta)); size_t pos = metas_.size() - 1; for (auto &[device, mask] : onlines_) { @@ -116,7 +126,7 @@ void AutoSyncMatrix::DelStore(const StoreMetaData &meta) metas_.erase(it); break; } - size_t pos = it - metas_.begin(); + size_t pos = static_cast(it - metas_.begin()); if (pos == metas_.size()) { return; } @@ -130,6 +140,10 @@ void AutoSyncMatrix::DelStore(const StoreMetaData &meta) void AutoSyncMatrix::Mask::Delete(size_t pos) { + if (pos >= MAX_SIZE) { + ZLOGE("pos:%{public}zu exceeds maximum value:%{public}d", pos, MAX_SIZE); + return; + } std::bitset tmp; for (size_t i = 0; i < pos; i++) { tmp.set(i); @@ -142,11 +156,19 @@ void AutoSyncMatrix::Mask::Delete(size_t pos) void AutoSyncMatrix::Mask::Set(size_t pos) { + if (pos >= MAX_SIZE) { + ZLOGE("pos:%{public}zu exceeds maximum value:%{public}d", pos, MAX_SIZE); + return; + } data.set(pos); } void AutoSyncMatrix::Mask::Init(size_t size) { + if (size >= MAX_SIZE) { + ZLOGE("pos:%{public}zu exceeds maximum value:%{public}d", size, MAX_SIZE); + return; + } for (size_t i = 0; i < size; i++) { data.set(i); } @@ -154,6 +176,10 @@ void AutoSyncMatrix::Mask::Init(size_t size) void AutoSyncMatrix::Mask::Reset(size_t pos) { + if (pos >= MAX_SIZE) { + ZLOGE("pos:%{public}zu exceeds maximum value:%{public}d", pos, MAX_SIZE); + return; + } data.reset(pos); } @@ -184,7 +210,7 @@ void AutoSyncMatrix::Online(const std::string &device) } onlines_.insert_or_assign(device, mask); } - + void AutoSyncMatrix::Offline(const std::string &device) { if (device.empty()) { @@ -208,7 +234,7 @@ void AutoSyncMatrix::OnChanged(const StoreMetaData &metaData) if (it == metas_.end()) { return; } - size_t pos = it - metas_.begin(); + size_t pos = static_cast(it - metas_.begin()); for (auto &[device, mask] : onlines_) { mask.Set(pos); } @@ -216,7 +242,7 @@ void AutoSyncMatrix::OnChanged(const StoreMetaData &metaData) mask.Set(pos); } } - + void AutoSyncMatrix::OnExchanged(const std::string &device, const StoreMetaData &metaData) { std::lock_guard lock(mutex_); @@ -224,7 +250,7 @@ void AutoSyncMatrix::OnExchanged(const std::string &device, const StoreMetaData if (it == metas_.end()) { return; } - size_t pos = it - metas_.begin(); + size_t pos = static_cast(it - metas_.begin()); auto iter = onlines_.find(device); if (iter != onlines_.end()) { iter->second.Reset(pos); @@ -258,4 +284,4 @@ std::vector AutoSyncMatrix::GetChangedStore(const std::string &de } return result; } -} // namespace OHOS::DistributedData +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/matrix/src/device_matrix.cpp b/datamgr_service/services/distributeddataservice/service/matrix/src/device_matrix.cpp index edb0cf1e..da5c1ba5 100644 --- a/datamgr_service/services/distributeddataservice/service/matrix/src/device_matrix.cpp +++ b/datamgr_service/services/distributeddataservice/service/matrix/src/device_matrix.cpp @@ -16,6 +16,7 @@ #include "device_matrix.h" #include "bootstrap.h" +#include "checker/checker_manager.h" #include "communication_provider.h" #include "device_manager_adapter.h" #include "eventcenter/event_center.h" @@ -52,16 +53,20 @@ DeviceMatrix::DeviceMatrix() if (metaData.origin == MatrixMetaData::Origin::REMOTE_CONSISTENT) { return true; } - matrixs_.Set(deviceId, metaData); + matrices_.Set(deviceId, metaData); return true; }, true); MetaDataManager::GetInstance().Subscribe(MatrixMetaData::GetPrefix({}), - [this](const std::string &, const std::string &meta, int32_t action) { + [this](const std::string &key, const std::string &meta, int32_t action) { if (action != MetaDataManager::INSERT && action != MetaDataManager::UPDATE) { return true; } MatrixMetaData metaData; - MatrixMetaData::Unmarshall(meta, metaData); + if (meta.empty()) { + MetaDataManager::GetInstance().LoadMeta(key, metaData); + } else { + MatrixMetaData::Unmarshall(meta, metaData); + } auto deviceId = std::move(metaData.deviceId); versions_.Set(deviceId, metaData); ZLOGI("Matrix ver:%{public}u device:%{public}s", @@ -77,7 +82,19 @@ DeviceMatrix::~DeviceMatrix() bool DeviceMatrix::Initialize(uint32_t token, std::string storeId) { - auto pipe = Bootstrap::GetInstance().GetProcessLabel() + "-" + "default"; + auto stores = CheckerManager::GetInstance().GetDynamicStores(); + dynamicApps_.clear(); + auto metaName = Bootstrap::GetInstance().GetProcessLabel(); + dynamicApps_.push_back(std::move(metaName)); + for (auto &store : stores) { + dynamicApps_.push_back(std::move(store.bundleName)); + } + stores = CheckerManager::GetInstance().GetStaticStores(); + staticsApps_.clear(); + for (auto &store : stores) { + staticsApps_.push_back(std::move(store.bundleName)); + } + auto pipe = metaName + "-" + "default"; auto status = Commu::GetInstance().Broadcast( { pipe }, { INVALID_LEVEL, INVALID_LEVEL, INVALID_VALUE, INVALID_LENGTH }); isSupportBroadcast_ = (status != DistributedKv::Status::NOT_SUPPORT_BROADCAST); @@ -109,49 +126,34 @@ bool DeviceMatrix::Initialize(uint32_t token, std::string storeId) void DeviceMatrix::Online(const std::string &device, RefCount refCount) { Mask mask; - EventCenter::Defer defer; - { - std::lock_guard lockGuard(mutex_); - auto it = offLines_.find(device); - if (it != offLines_.end()) { - mask = it->second; - offLines_.erase(it); - } else { - UpdateMask(mask); - } - onLines_.insert_or_assign(device, mask); - } - auto [dynamic, statics] = IsConsistent(device); - if ((dynamic && statics) || (Low(mask.statics) == 0 && Low(mask.dynamic) == 0)) { - ZLOGI("dynamic:%{public}d statics:%{public}d dynamic mask:0x%{public}08x statics mask:0x%{public}08x", - dynamic, statics, Low(mask.dynamic), Low(mask.statics)); - return; - } - if (dynamic) { - mask.dynamic = ResetMask(mask.dynamic); - } - if (statics) { - mask.statics = ResetMask(mask.statics); + std::lock_guard lockGuard(mutex_); + auto it = offLines_.find(device); + if (it != offLines_.end()) { + mask = it->second; + offLines_.erase(it); + } else { + UpdateMask(mask); } - MatrixEvent::MatrixData matrixData; - matrixData.statics = mask.statics; - matrixData.dynamic = mask.dynamic; - auto evt = std::make_unique(MATRIX_ONLINE, device, matrixData); - evt->SetRefCount(std::move(refCount)); - EventCenter::GetInstance().PostEvent(std::move(evt)); + onLines_.insert_or_assign(device, mask); } std::pair DeviceMatrix::IsConsistent(const std::string &device) { std::pair isConsistent = { false, false }; - auto [dynamicSaved, dynamicRecvLevel] = GetRecvLevel(device); - auto [dynamicExist, dynamicConsLevel] = GetConsLevel(device); - isConsistent.first = (dynamicSaved && dynamicExist && - (dynamicRecvLevel <= dynamicConsLevel) && (dynamicRecvLevel != INVALID_MASK)); + auto [dynamicSaved, dynamicRecvLevel] = GetRecvLevel(device, LevelType::DYNAMIC); + auto [dynamicExist, dynamicConsLevel] = GetConsLevel(device, LevelType::DYNAMIC); + ZLOGI("device:%{public}s, dynamicSaved:%{public}d, dynamicRecvLevel:%{public}d, dynamicExist:%{public}d, " + "dynamicConsLevel:%{public}d", + Anonymous::Change(device).c_str(), dynamicSaved, dynamicRecvLevel, dynamicExist, dynamicConsLevel); + isConsistent.first = + (dynamicSaved && dynamicExist && (dynamicRecvLevel <= dynamicConsLevel) && (dynamicRecvLevel != INVALID_MASK)); auto [staticsSaved, staticsRecvLevel] = GetRecvLevel(device, LevelType::STATICS); auto [staticsExist, staticsConsLevel] = GetConsLevel(device, LevelType::STATICS); - isConsistent.second = (staticsSaved && staticsExist && - (staticsRecvLevel <= staticsConsLevel) && (staticsRecvLevel != INVALID_MASK)); + ZLOGI("device:%{public}s, staticsSaved:%{public}d, staticsRecvLevel:%{public}d, staticsExist:%{public}d, " + "staticsConsLevel:%{public}d", + Anonymous::Change(device).c_str(), staticsSaved, staticsRecvLevel, staticsExist, staticsConsLevel); + isConsistent.second = + (staticsSaved && staticsExist && (staticsRecvLevel <= staticsConsLevel) && (staticsRecvLevel != INVALID_MASK)); return isConsistent; } @@ -214,7 +216,7 @@ std::pair DeviceMatrix::OnBroadcast(const std::string &devic remotes_.insert_or_assign(device, mask); } if (observer_) { - observer_(device, mask.dynamic); + observer_(device, { mask.statics, mask.dynamic }); } return { mask.dynamic, mask.statics }; } @@ -241,7 +243,7 @@ uint16_t DeviceMatrix::ConvertDynamic(const MatrixMetaData &meta, uint16_t mask) const auto &app = meta.dynamicInfo[index]; for (size_t i = 0; i < dynamicApps_.size(); i++) { if (dynamicApps_[i] == app) { - result |= SetMask(i + 1); + result |= SetMask(i); break; } } @@ -303,10 +305,25 @@ void DeviceMatrix::UpdateRemoteMeta(const std::string &device, Mask &mask) if (High(newMeta.dynamic) < High(oldMeta.dynamic)) { newMeta.dynamic &= 0x000F; newMeta.dynamic |= High(oldMeta.dynamic); + } else if ((High(newMeta.dynamic) - High(oldMeta.dynamic)) > 1) { + newMeta.dynamic |= 0x000F; + mask.dynamic |= 0x000F; } if (High(newMeta.statics) < High(oldMeta.statics)) { newMeta.statics &= 0x000F; newMeta.statics |= High(oldMeta.statics); + } else if ((High(newMeta.statics) - High(oldMeta.statics)) > 1) { + newMeta.statics |= 0x000F; + mask.statics |= 0x000F; + } + } else { + if (High(newMeta.dynamic) != 0x0010) { + newMeta.dynamic |= 0x000F; + mask.dynamic |= 0x000F; + } + if (High(newMeta.statics) != 0x0010) { + newMeta.statics |= 0x000F; + mask.statics |= 0x000F; } } MetaDataManager::GetInstance().SaveMeta(newMeta.GetKey(), newMeta, true); @@ -341,24 +358,24 @@ void DeviceMatrix::Broadcast(const DataLevel &dataLevel) .switchesLen = dataLevel.switchesLen, }; std::lock_guard lock(taskMutex_); - if (!lastest_.IsValid()) { + if (!lasts_.IsValid()) { EventCenter::GetInstance().PostEvent(std::make_unique(MATRIX_BROADCAST, "", matrix)); return; } - matrix.dynamic |= Low(lastest_.dynamic); - matrix.statics |= Low(lastest_.statics); - if (High(matrix.dynamic) != INVALID_HIGH && High(lastest_.dynamic)!= INVALID_HIGH && - High(matrix.dynamic) < High(lastest_.dynamic)) { + matrix.dynamic |= Low(lasts_.dynamic); + matrix.statics |= Low(lasts_.statics); + if (High(matrix.dynamic) != INVALID_HIGH && High(lasts_.dynamic)!= INVALID_HIGH && + High(matrix.dynamic) < High(lasts_.dynamic)) { matrix.dynamic &= 0x000F; matrix.dynamic |= High(matrix.dynamic); } - if (High(matrix.statics) != INVALID_HIGH && High(lastest_.statics)!= INVALID_HIGH && - High(matrix.statics) < High(lastest_.statics)) { + if (High(matrix.statics) != INVALID_HIGH && High(lasts_.statics)!= INVALID_HIGH && + High(matrix.statics) < High(lasts_.statics)) { matrix.statics &= 0x000F; matrix.statics |= High(matrix.statics); } EventCenter::GetInstance().PostEvent(std::make_unique(MATRIX_BROADCAST, "", matrix)); - lastest_ = matrix; + lasts_ = matrix; auto executor = executors_; if (executor != nullptr && task_ != ExecutorPool::INVALID_TASK_ID) { task_ = executor->Reset(task_, std::chrono::minutes(RESET_MASK_DELAY)); @@ -371,7 +388,7 @@ void DeviceMatrix::OnChanged(uint16_t code, LevelType type) return; } uint16_t low = Low(code); - uint16_t codes[LevelType::BUTT] = { 0 }; + uint16_t codes[LevelType::BUTT] = { 0, 0 }; codes[type] |= low; EventCenter::Defer defer; { @@ -404,7 +421,7 @@ void DeviceMatrix::OnChanged(uint16_t code, LevelType type) } EventCenter::GetInstance().PostEvent(std::make_unique(MATRIX_BROADCAST, "", matrixData)); std::lock_guard lock(taskMutex_); - lastest_ = matrixData; + lasts_ = matrixData; auto executor = executors_; if (executor != nullptr) { if (task_ != ExecutorPool::INVALID_TASK_ID) { @@ -440,14 +457,16 @@ void DeviceMatrix::OnChanged(const StoreMetaData &metaData) void DeviceMatrix::OnExchanged(const std::string &device, uint16_t code, LevelType type, ChangeType changeType) { - if (type < LevelType::STATICS || type > LevelType::DYNAMIC) { + if (device.empty() || type < LevelType::STATICS || type > LevelType::DYNAMIC) { + ZLOGE("Invalid args.device:%{public}s, code:%{public}d, type:%{public}d", Anonymous::Change(device).c_str(), + code, type); return; } uint16_t low = Low(code); uint16_t codes[LevelType::BUTT] = { 0 }; codes[type] |= low; std::lock_guard lockGuard(mutex_); - if (changeType == ChangeType::CHANGE_LOCAL || changeType == ChangeType::CHANGE_ALL) { + if ((changeType & CHANGE_LOCAL) == CHANGE_LOCAL) { auto it = onLines_.find(device); if (it != onLines_.end()) { it->second.statics &= ~codes[LevelType::STATICS]; @@ -459,17 +478,17 @@ void DeviceMatrix::OnExchanged(const std::string &device, uint16_t code, LevelTy it->second.dynamic &= ~codes[LevelType::DYNAMIC]; } } - if (changeType == ChangeType::CHANGE_LOCAL) { - return; - } - auto it = remotes_.find(device); - if (it != remotes_.end()) { + if ((changeType & CHANGE_REMOTE) == CHANGE_REMOTE) { + auto it = remotes_.find(device); + if (it == remotes_.end()) { + return; + } it->second.statics &= ~codes[LevelType::STATICS]; it->second.dynamic &= ~codes[LevelType::DYNAMIC]; - } - UpdateConsistentMeta(device, it->second); - if (observer_) { - observer_(device, it->second.dynamic); + UpdateConsistentMeta(device, it->second); + if (observer_) { + observer_(device, { it->second.statics, it->second.dynamic }); + } } } @@ -532,7 +551,7 @@ uint16_t DeviceMatrix::GetCode(const StoreMetaData &metaData) if (metaData.dataType == LevelType::DYNAMIC) { for (size_t i = 0; i < dynamicApps_.size(); i++) { if (dynamicApps_[i] == metaData.appId) { - return SetMask(i + 1); + return SetMask(i); } } } @@ -580,7 +599,7 @@ std::map DeviceMatrix::GetRemoteDynamicMask() std::map masks; std::lock_guard lockGuard(mutex_); for (const auto &[device, mask] : remotes_) { - masks.insert_or_assign(device, mask.dynamic); + masks.insert_or_assign(device, Low(mask.dynamic)); } return masks; } @@ -621,8 +640,8 @@ std::pair DeviceMatrix::GetConsLevel(const std::string &device, void DeviceMatrix::Clear() { - matrixs_.ResetCapacity(0); - matrixs_.ResetCapacity(MAX_DEVICES); + matrices_.ResetCapacity(0); + matrices_.ResetCapacity(MAX_DEVICES); versions_.ResetCapacity(0); versions_.ResetCapacity(MAX_DEVICES); std::lock_guard lockGuard(mutex_); @@ -631,27 +650,55 @@ void DeviceMatrix::Clear() remotes_.clear(); } -std::pair DeviceMatrix::GetMatrixMeta(const std::string &device, bool IsConsistent) +std::pair DeviceMatrix::GetMatrixMeta(const std::string &device, bool isConsistent) { MatrixMetaData meta; - if (!IsConsistent && matrixs_.Get(device, meta)) { + if (!isConsistent && matrices_.Get(device, meta)) { return { true, meta }; } meta.deviceId = device; std::string key; - if (IsConsistent) { + if (isConsistent) { key = meta.GetConsistentKey(); } else { key = meta.GetKey(); } auto success = MetaDataManager::GetInstance().LoadMeta(key, meta, true); - if (success && !IsConsistent) { + if (success && !isConsistent) { meta.deviceId = ""; - matrixs_.Set(device, meta); + matrices_.Set(device, meta); } return { success, meta }; } +void DeviceMatrix::UpdateLevel(const std::string &device, uint16_t level, DeviceMatrix::LevelType type, + bool isConsistent) +{ + if (device.empty() || type < 0 || type >= LevelType::BUTT) { + ZLOGE("Invalid args.device:%{public}s, level:%{public}d, type:%{public}d", Anonymous::Change(device).c_str(), + level, type); + return; + } + auto [exist, meta] = GetMatrixMeta(device, isConsistent); + if (!exist) { + if (device == DMAdapter::GetInstance().GetLocalDevice().uuid) { + meta.origin = Origin::LOCAL; + } else { + meta.origin = isConsistent ? Origin::REMOTE_CONSISTENT : Origin::REMOTE_RECEIVED; + } + meta.dynamicInfo = dynamicApps_; + meta.staticsInfo = staticsApps_; + } + meta.deviceId = device; + meta.dynamic = type == DYNAMIC ? Merge(level, meta.dynamic) : meta.dynamic; + meta.statics = type == STATICS ? Merge(level, meta.statics) : meta.statics; + MetaDataManager::GetInstance().SaveMeta(isConsistent ? meta.GetConsistentKey() : meta.GetKey(), meta, true); + if (!isConsistent) { + meta.deviceId = ""; + matrices_.Set(device, meta); + } +} + MatrixMetaData DeviceMatrix::GetMatrixInfo(const std::string &device) { MatrixMetaData meta; @@ -666,7 +713,7 @@ MatrixMetaData DeviceMatrix::GetMatrixInfo(const std::string &device) return meta; } -void DeviceMatrix::RegRemoteChange(std::function observer) +void DeviceMatrix::RegRemoteChange(std::function)> observer) { if (observer_) { ZLOGD("duplicate register"); @@ -705,7 +752,7 @@ DeviceMatrix::Task DeviceMatrix::GenResetTask() MatrixEvent::MatrixData matrixData; { std::lock_guard lock(taskMutex_); - matrixData = lastest_; + matrixData = lasts_; task_ = ExecutorPool::INVALID_TASK_ID; } matrixData.dynamic = ResetMask(matrixData.dynamic); @@ -720,8 +767,8 @@ bool DeviceMatrix::DataLevel::IsValid() const switches == INVALID_VALUE && switchesLen == INVALID_LENGTH); } -bool DeviceMatrix::IsSupportBroadcast() +bool DeviceMatrix::IsSupportMatrix() { return isSupportBroadcast_; } -} // namespace OHOS::DistributedData +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/object/object_asset_loader.cpp b/datamgr_service/services/distributeddataservice/service/object/object_asset_loader.cpp index 7921667e..acafa07b 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_asset_loader.cpp +++ b/datamgr_service/services/distributeddataservice/service/object/object_asset_loader.cpp @@ -20,7 +20,8 @@ #include "log_print.h" #include "object_common.h" #include "utils/anonymous.h" - +#include "object_radar_reporter.h" +#include "distributed_file_daemon_manager.h" namespace OHOS::DistributedObject { using namespace OHOS::FileManagement::CloudSync; ObjectAssetLoader *ObjectAssetLoader::GetInstance() @@ -66,14 +67,14 @@ bool ObjectAssetLoader::Transfer(const int32_t userId, const std::string& bundle void ObjectAssetLoader::TransferAssetsAsync(const int32_t userId, const std::string& bundleName, const std::string& deviceId, const std::vector& assets, const TransferFunc& callback) { + RADAR_REPORT(ObjectStore::CREATE, ObjectStore::TRANSFER, ObjectStore::IDLE); if (executors_ == nullptr) { ZLOGE("executors is null, bundleName: %{public}s, deviceId: %{public}s, userId: %{public}d", bundleName.c_str(), DistributedData::Anonymous::Change(deviceId).c_str(), userId); callback(false); return; } - TransferTask task; - task.callback = callback; + TransferTask task = { .callback = callback }; DistributedData::Assets downloadAssets; for (auto& asset : assets) { if (IsDownloaded(asset)) { @@ -85,8 +86,7 @@ void ObjectAssetLoader::TransferAssetsAsync(const int32_t userId, const std::str if (task.downloadAssets.empty()) { callback(true); } - taskSeq_++; - tasks_.ComputeIfAbsent(taskSeq_, [task](const uint32_t key) { + tasks_.ComputeIfAbsent(++taskSeq_, [task](const uint32_t key) { return task; }); executors_->Execute([this, userId, bundleName, deviceId, downloadAssets]() { @@ -124,6 +124,9 @@ void ObjectAssetLoader::FinishTask(const std::string& uri, bool result) if (task.downloadAssets.size() == 0 && task.callback != nullptr) { task.callback(result); finishedTasks.emplace_back(seq); + if (result) { + RADAR_REPORT(ObjectStore::CREATE, ObjectStore::TRANSFER, ObjectStore::RADAR_SUCCESS); + } } return false; }); @@ -164,4 +167,33 @@ bool ObjectAssetLoader::IsDownloaded(const DistributedData::Asset& asset) } return false; } + +int32_t ObjectAssetLoader::PushAsset(int32_t userId, const sptr &assetObj, + const sptr &sendCallback) +{ + RADAR_REPORT(ObjectStore::SAVE, ObjectStore::PUSH_ASSETS, ObjectStore::IDLE); + ZLOGI("PushAsset start, asset size:%{public}zu, bundleName:%{public}s, sessionId:%{public}s", + assetObj->uris_.size(), assetObj->dstBundleName_.c_str(), assetObj->sessionId_.c_str()); + auto status = Storage::DistributedFile::DistributedFileDaemonManager::GetInstance().PushAsset(userId, assetObj, + sendCallback); + if (status != OBJECT_SUCCESS) { + ZLOGE("PushAsset err status: %{public}d, asset size:%{public}zu, bundleName:%{public}s, sessionId:%{public}s", + status, assetObj->uris_.size(), assetObj->dstBundleName_.c_str(), assetObj->sessionId_.c_str()); + RADAR_REPORT(ObjectStore::SAVE, ObjectStore::PUSH_ASSETS, ObjectStore::RADAR_FAILED, + ObjectStore::ERROR_CODE, status); + } + return status; +} + +int32_t ObjectAssetsSendListener::OnSendResult(const sptr &assetObj, int32_t result) +{ + ZLOGI("OnSendResult, status:%{public}d, asset size:%{public}zu", result, assetObj->uris_.size()); + if (result == OBJECT_SUCCESS) { + RADAR_REPORT(ObjectStore::SAVE, ObjectStore::PUSH_ASSETS, ObjectStore::RADAR_SUCCESS); + } else { + RADAR_REPORT(ObjectStore::SAVE, ObjectStore::PUSH_ASSETS, ObjectStore::RADAR_FAILED, + ObjectStore::ERROR_CODE, result); + } + return result; +} } // namespace OHOS::DistributedObject \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/object/object_asset_loader.h b/datamgr_service/services/distributeddataservice/service/object/object_asset_loader.h index b21c906b..44d3f8ab 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_asset_loader.h +++ b/datamgr_service/services/distributeddataservice/service/object/object_asset_loader.h @@ -21,9 +21,10 @@ #include "store/general_value.h" #include "concurrent_map.h" #include +#include "asset/asset_send_callback_stub.h" namespace OHOS { namespace DistributedObject { - +using AssetObj = Storage::DistributedFile::AssetObj; using TransferFunc = std::function; struct TransferTask { TransferTask() = default; @@ -31,6 +32,13 @@ struct TransferTask { TransferFunc callback; }; +class ObjectAssetsSendListener : public Storage::DistributedFile::AssetSendCallbackStub { +public: + ObjectAssetsSendListener() =default; + ~ObjectAssetsSendListener() = default; + int32_t OnSendResult(const sptr &assetObj, int32_t result) override; +}; + class ObjectAssetLoader { public: static ObjectAssetLoader *GetInstance(); @@ -39,6 +47,8 @@ public: const DistributedData::Asset& asset); void TransferAssetsAsync(const int32_t userId, const std::string& bundleName, const std::string& deviceId, const std::vector& assets, const TransferFunc& callback); + int32_t PushAsset(int32_t userId, const sptr &assetObj, + const sptr &sendCallback); private: ObjectAssetLoader() = default; ~ObjectAssetLoader() = default; diff --git a/datamgr_service/services/distributeddataservice/service/object/object_asset_machine.cpp b/datamgr_service/services/distributeddataservice/service/object/object_asset_machine.cpp index 02038280..ce67d4df 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_asset_machine.cpp +++ b/datamgr_service/services/distributeddataservice/service/object/object_asset_machine.cpp @@ -27,6 +27,7 @@ #include "object_asset_loader.h" #include "snapshot/bind_event.h" #include "store/auto_cache.h" +#include "utils/anonymous.h" namespace OHOS { namespace DistributedObject { @@ -257,7 +258,8 @@ static void MergeAssetData(VBucket& record, const Asset& newAsset, const AssetBi if (value.index() == TYPE_INDEX) { auto* asset = Traits::get_if(&value); if (asset->name != newAsset.name) { - ZLOGD("Asset not same, old uri: %{public}s, new uri: %{public}s", asset->uri.c_str(), newAsset.uri.c_str()); + ZLOGD("Asset not same, old uri: %{public}s, new uri: %{public}s", + Anonymous::Change(asset->uri, true).c_str(), Anonymous::Change(newAsset.uri, true).c_str()); return; } } diff --git a/datamgr_service/services/distributeddataservice/service/object/object_callback_proxy.cpp b/datamgr_service/services/distributeddataservice/service/object/object_callback_proxy.cpp index 0eb7942b..7e4c649a 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_callback_proxy.cpp +++ b/datamgr_service/services/distributeddataservice/service/object/object_callback_proxy.cpp @@ -80,7 +80,7 @@ void ObjectRevokeSaveCallbackProxy::Completed(int32_t status) } } -void ObjectRetrieveCallbackProxy::Completed(const std::map> &results) +void ObjectRetrieveCallbackProxy::Completed(const std::map> &results, bool allReady) { MessageParcel data; MessageParcel reply; @@ -88,7 +88,7 @@ void ObjectRetrieveCallbackProxy::Completed(const std::map> &results) +void ObjectChangeCallbackProxy::Completed(const std::map> &results, bool allReady) { MessageParcel data; MessageParcel reply; @@ -107,7 +107,7 @@ void ObjectChangeCallbackProxy::Completed(const std::map &impl); ~ObjectRetrieveCallbackProxy() = default; - void Completed(const std::map> &results) override; + void Completed(const std::map> &results, bool allReady) override; private: static inline BrokerDelegator delegator_; @@ -75,7 +75,7 @@ class ObjectChangeCallbackProxy : public IRemoteProxy &impl); ~ObjectChangeCallbackProxy() = default; - void Completed(const std::map> &results) override; + void Completed(const std::map> &results, bool allReady) override; private: static inline BrokerDelegator delegator_; diff --git a/datamgr_service/services/distributeddataservice/service/object/object_data_listener.cpp b/datamgr_service/services/distributeddataservice/service/object/object_data_listener.cpp index 406d016a..4bd3c3d5 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_data_listener.cpp +++ b/datamgr_service/services/distributeddataservice/service/object/object_data_listener.cpp @@ -18,7 +18,6 @@ #include "object_data_listener.h" #include "log_print.h" #include "object_manager.h" - namespace OHOS { namespace DistributedObject { ObjectDataListener::ObjectDataListener() @@ -31,7 +30,6 @@ ObjectDataListener::~ObjectDataListener() void ObjectDataListener::OnChange(const DistributedDB::KvStoreChangedData &data) { - ZLOGD("ObjectDataListener::OnChange start"); const auto &insertedDatas = data.GetEntriesInserted(); const auto &updatedDatas = data.GetEntriesUpdated(); std::map> changedData {}; @@ -45,5 +43,24 @@ void ObjectDataListener::OnChange(const DistributedDB::KvStoreChangedData &data) } DistributedObject::ObjectStoreManager::GetInstance()->NotifyChange(changedData); } + +int32_t ObjectAssetsRecvListener::OnStart(const std::string &srcNetworkId, const std::string &dstNetworkId, + const std::string &sessionId, const std::string &dstBundleName) +{ + auto objectKey = dstBundleName + sessionId; + ZLOGI("OnStart, objectKey:%{public}s", objectKey.c_str()); + ObjectStoreManager::GetInstance()->NotifyAssetsStart(objectKey, srcNetworkId); + return OBJECT_SUCCESS; +} + +int32_t ObjectAssetsRecvListener::OnFinished(const std::string &srcNetworkId, const sptr &assetObj, + int32_t result) +{ + auto objectKey = assetObj->dstBundleName_+assetObj->sessionId_; + ZLOGI("OnFinished, status:%{public}d objectKey:%{public}s, asset size:%{public}zu", result, objectKey.c_str(), + assetObj->uris_.size()); + ObjectStoreManager::GetInstance()->NotifyAssetsReady(objectKey, srcNetworkId); + return OBJECT_SUCCESS; +} } // namespace DistributedObject } // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/service/object/object_data_listener.h b/datamgr_service/services/distributeddataservice/service/object/object_data_listener.h index c3fb17d7..0ee568c6 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_data_listener.h +++ b/datamgr_service/services/distributeddataservice/service/object/object_data_listener.h @@ -17,9 +17,10 @@ #define DISTRIBUTEDDATAMGR_OBJECT_DATA_LISTENER_H #include "kv_store_observer.h" - +#include "asset/asset_recv_callback_stub.h" namespace OHOS { namespace DistributedObject { +using AssetObj = Storage::DistributedFile::AssetObj; class ObjectDataListener : public DistributedDB::KvStoreObserver { public: ObjectDataListener(); @@ -27,6 +28,17 @@ public: // Database change callback void OnChange(const DistributedDB::KvStoreChangedData &data) override; }; + +class ObjectAssetsRecvListener : public Storage::DistributedFile::AssetRecvCallbackStub { +public: + ObjectAssetsRecvListener() =default; + ~ObjectAssetsRecvListener() =default; + int32_t OnStart(const std::string &srcNetworkId, + const std::string &dstNetworkId, const std::string &sessionId, + const std::string &dstBundleName) override; + int32_t OnFinished(const std::string &srcNetworkId, + const sptr &assetObj, int32_t result) override; +}; } // namespace DistributedObject } // namespace OHOS #endif // DISTRIBUTEDDATAMGR_OBJECT_DATA_LISTENER_H diff --git a/datamgr_service/services/distributeddataservice/service/object/object_manager.cpp b/datamgr_service/services/distributeddataservice/service/object/object_manager.cpp index 58ab8c86..c4c231e2 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_manager.cpp +++ b/datamgr_service/services/distributeddataservice/service/object/object_manager.cpp @@ -12,29 +12,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #define LOG_TAG "ObjectStoreManager" -#include #include "object_manager.h" -#include "ipc_skeleton.h" +#include +#include +#include + #include "accesstoken_kit.h" -#include "ipc_skeleton.h" -#include "bootstrap.h" +#include "account/account_delegate.h" #include "block_data.h" +#include "bootstrap.h" #include "checker/checker_manager.h" +#include "common/bytes.h" +#include "common/string_utils.h" #include "datetime_ex.h" +#include "distributed_file_daemon_manager.h" +#include "ipc_skeleton.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" -#include "common/bytes.h" -#include "common/string_utils.h" -#include +#include "object_radar_reporter.h" namespace OHOS { namespace DistributedObject { @@ -46,7 +46,29 @@ using OHOS::DistributedKv::AccountDelegate; using Account = OHOS::DistributedKv::AccountDelegate; using AccessTokenKit = Security::AccessToken::AccessTokenKit; using ValueProxy = OHOS::DistributedData::ValueProxy; -ObjectStoreManager::ObjectStoreManager() {} +using DistributedFileDaemonManager = Storage::DistributedFile::DistributedFileDaemonManager; +ObjectStoreManager::ObjectStoreManager() +{ + ZLOGI("ObjectStoreManager construct"); + RegisterAssetsLister(); +} + +ObjectStoreManager::~ObjectStoreManager() +{ + ZLOGI("ObjectStoreManager destroy"); + if (objectAssetsSendListener_ != nullptr) { + delete objectAssetsSendListener_; + objectAssetsSendListener_ = nullptr; + } + if (objectAssetsRecvListener_ != nullptr) { + auto status = DistributedFileDaemonManager::GetInstance().UnRegisterAssetCallback(objectAssetsRecvListener_); + if (status != DistributedDB::DBStatus::OK) { + ZLOGE("UnRegister assetsRecvListener err %{public}d", status); + } + delete objectAssetsRecvListener_; + objectAssetsRecvListener_ = nullptr; + } +} DistributedDB::KvStoreNbDelegate *ObjectStoreManager::OpenObjectKvStore() { @@ -78,6 +100,22 @@ DistributedDB::KvStoreNbDelegate *ObjectStoreManager::OpenObjectKvStore() return store; } +bool ObjectStoreManager::RegisterAssetsLister() +{ + if (objectAssetsSendListener_ == nullptr) { + objectAssetsSendListener_ = new ObjectAssetsSendListener(); + } + if (objectAssetsRecvListener_ == nullptr) { + objectAssetsRecvListener_ = new ObjectAssetsRecvListener(); + } + auto status = DistributedFileDaemonManager::GetInstance().RegisterAssetCallback(objectAssetsRecvListener_); + if (status != DistributedDB::DBStatus::OK) { + ZLOGE("Register assetsRecvListener err %{public}d", status); + return false; + } + return true; +} + void ObjectStoreManager::ProcessSyncCallback(const std::map &results, const std::string &appId, const std::string &sessionId, const std::string &deviceId) { @@ -112,6 +150,8 @@ int32_t ObjectStoreManager::Save(const std::string &appId, const std::string &se if (result != OBJECT_SUCCESS) { ZLOGE("Open failed, errCode = %{public}d", result); proxy->Completed(std::map()); + RADAR_REPORT(ObjectStore::SAVE, ObjectStore::SAVE_TO_STORE, ObjectStore::RADAR_FAILED, + ObjectStore::ERROR_CODE, ObjectStore::GETKV_FAILED, ObjectStore::BIZ_STATE, ObjectStore::FINISHED); return STORE_NOT_OPEN; } @@ -134,11 +174,36 @@ int32_t ObjectStoreManager::Save(const std::string &appId, const std::string &se if (result != OBJECT_SUCCESS) { ZLOGE("sync failed, errCode = %{public}d", result); proxy->Completed(std::map()); + RADAR_REPORT(ObjectStore::SAVE, ObjectStore::SAVE_TO_STORE, ObjectStore::RADAR_FAILED, + ObjectStore::ERROR_CODE, result, ObjectStore::BIZ_STATE, ObjectStore::FINISHED); } + result = PushAssets(std::stoi(GetCurrentUser()), appId, sessionId, data, deviceId); Close(); return result; } +int32_t ObjectStoreManager::PushAssets(int32_t userId, const std::string &appId, const std::string &sessionId, + const std::map> &data, const std::string &deviceId) +{ + Assets assets = GetAssetsFromDBRecords(data); + if (assets.empty() || data.find(ObjectStore::FIELDS_PREFIX + ObjectStore::DEVICEID_KEY) == data.end()) { + return OBJECT_SUCCESS; + } + sptr assetObj = new AssetObj(); + assetObj->dstBundleName_ = appId; + assetObj->srcBundleName_ = appId; + assetObj->dstNetworkId_ = deviceId; + assetObj->sessionId_ = sessionId; + for (const auto& asset : assets) { + assetObj->uris_.push_back(asset.uri); + } + if (objectAssetsSendListener_ == nullptr) { + objectAssetsSendListener_ = new ObjectAssetsSendListener(); + } + auto status = ObjectAssetLoader::GetInstance()->PushAsset(userId, assetObj, objectAssetsSendListener_); + return status; +} + int32_t ObjectStoreManager::RevokeSave( const std::string &appId, const std::string &sessionId, sptr callback) { @@ -186,39 +251,43 @@ int32_t ObjectStoreManager::Retrieve( int32_t result = Open(); if (result != OBJECT_SUCCESS) { ZLOGE("Open failed, errCode = %{public}d", result); - proxy->Completed(std::map>()); - return STORE_NOT_OPEN; + proxy->Completed(std::map>(), false); + return ObjectStore::GETKV_FAILED; } - std::map> results{}; int32_t status = RetrieveFromStore(bundleName, sessionId, results); if (status != OBJECT_SUCCESS) { - ZLOGE("Retrieve failed, status = %{public}d", status); + ZLOGI("Retrieve failed, status = %{public}d", status); Close(); - proxy->Completed(std::map>()); + proxy->Completed(std::map>(), false); return status; } + bool allReady = false; + Assets assets = GetAssetsFromDBRecords(results); + if (assets.empty() || results.find(ObjectStore::FIELDS_PREFIX + ObjectStore::DEVICEID_KEY) == results.end()) { + allReady = true; + } else { + auto objectKey = bundleName + sessionId; + restoreStatus_.ComputeIfAbsent( + objectKey, [](const std::string& key) -> auto { + return RestoreStatus::NONE; + }); + if (restoreStatus_[objectKey] == RestoreStatus::ALL_READY) { + allReady = true; + } + } // delete local data status = RevokeSaveToStore(GetPrefixWithoutDeviceId(bundleName, sessionId)); if (status != OBJECT_SUCCESS) { ZLOGE("revoke save failed, status = %{public}d", status); Close(); - proxy->Completed(std::map>()); + proxy->Completed(std::map>(), false); return status; } Close(); - Assets assets = GetAssetsFromDBRecords(results); - if (assets.empty() || results.find(ObjectStore::FIELDS_PREFIX + ObjectStore::DEVICEID_KEY) == results.end()) { - proxy->Completed(results); - return status; - } - int32_t userId = DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(tokenId); - std::string deviceId; - ObjectStore::StringUtils::BytesToStrWithType( - results.find(ObjectStore::FIELDS_PREFIX + ObjectStore::DEVICEID_KEY)->second, deviceId); - ObjectAssetLoader::GetInstance()->TransferAssetsAsync(userId, bundleName, deviceId, assets, [=](bool success) { - proxy->Completed(results); - }); + proxy->Completed(results, allReady); + RADAR_REPORT(ObjectStore::CREATE, ObjectStore::RESTORE, ObjectStore::RADAR_SUCCESS, ObjectStore::BIZ_STATE, + ObjectStore::FINISHED); return status; } @@ -329,41 +398,102 @@ void ObjectStoreManager::UnregisterRemoteCallback(const std::string &bundleName, void ObjectStoreManager::NotifyChange(std::map> &changedData) { - ZLOGD("ObjectStoreManager::NotifyChange start"); - SaveUserToMeta(); + ZLOGI("OnChange start, size:%{public}zu", changedData.size()); + std::map> changedAssets = GetAssetsFromStore(changedData); std::map>> data; + bool hasAsset = false; for (const auto &item : changedData) { - std::string prefix = GetBundleName(item.first) + GetSessionId(item.first); - std::string propertyName = GetPropertyName(item.first); + std::vector splitKeys = SplitEntryKey(item.first); + if (splitKeys.empty()) { + continue; + } + std::string prefix = splitKeys[BUNDLE_NAME_INDEX] + splitKeys[SESSION_ID_INDEX]; + std::string propertyName = splitKeys[PROPERTY_NAME_INDEX]; data[prefix].insert_or_assign(propertyName, item.second); + if (IsAssetKey(propertyName)) { + hasAsset = true; + } } - std::function callback = [this, data](bool success) { + if (!hasAsset) { callbacks_.ForEach([this, &data](uint32_t tokenId, const CallbackInfo& value) { - DoNotify(tokenId, value, data); + DoNotify(tokenId, value, data, true); // no asset, data ready means all ready return false; }); - }; - std::map> changedAssets = GetAssetsFromStore(changedData); - if (changedAssets.empty()) { - callback(true); + return; } - const int32_t userId = std::stoi(GetCurrentUser()); - for (const auto& assetsOfBundle : changedAssets) { - std::string bundleName = assetsOfBundle.first; - for (const auto& assetsOfDevice : assetsOfBundle.second) { - std::string deviceId = assetsOfDevice.first; - Assets assets = assetsOfDevice.second; - ObjectAssetLoader::GetInstance()->TransferAssetsAsync(userId, bundleName, deviceId, assets, callback); + NotifyDataChanged(data); + SaveUserToMeta(); +} + +void ObjectStoreManager::NotifyDataChanged(std::map>>& data) +{ + for (auto const& [objectKey, results] : data) { + restoreStatus_.ComputeIfAbsent( + objectKey, [](const std::string& key) -> auto { + return RestoreStatus::NONE; + }); + if (restoreStatus_[objectKey] == RestoreStatus::ASSETS_READY) { + restoreStatus_[objectKey] = RestoreStatus::ALL_READY; + callbacks_.ForEach([this, &data](uint32_t tokenId, const CallbackInfo& value) { + DoNotify(tokenId, value, data, true); + return false; + }); + } else { + restoreStatus_[objectKey] = RestoreStatus::DATA_READY; + callbacks_.ForEach([this, &data](uint32_t tokenId, const CallbackInfo& value) { + DoNotify(tokenId, value, data, false); + return false; + }); + WaitAssets(objectKey); } } } +int32_t ObjectStoreManager::WaitAssets(const std::string& objectKey) +{ + auto taskId = executors_->Schedule(std::chrono::seconds(WAIT_TIME), [this, objectKey]() { + ZLOGE("wait assets finisehd timeout, objectKey:%{public}s", objectKey.c_str()); + NotifyAssetsReady(objectKey); + }); + + objectTimer_.ComputeIfAbsent( + objectKey, [taskId](const std::string& key) -> auto { + return taskId; + }); + return OBJECT_SUCCESS; +} + +void ObjectStoreManager::NotifyAssetsReady(const std::string& objectKey, const std::string& srcNetworkId) +{ + restoreStatus_.ComputeIfAbsent( + objectKey, [](const std::string& key) -> auto { + return RestoreStatus::NONE; + }); + if (restoreStatus_[objectKey] == RestoreStatus::DATA_READY) { + restoreStatus_[objectKey] = RestoreStatus::ALL_READY; + callbacks_.ForEach([this, objectKey](uint32_t tokenId, const CallbackInfo& value) { + DoNotifyAssetsReady(tokenId, value, objectKey, true); + return false; + }); + } else { + restoreStatus_[objectKey] = RestoreStatus::ASSETS_READY; + } +} + +void ObjectStoreManager::NotifyAssetsStart(const std::string& objectKey, const std::string& srcNetworkId) +{ + restoreStatus_.ComputeIfAbsent( + objectKey, [](const std::string& key) -> auto { + return RestoreStatus::NONE; + }); +} + std::map> ObjectStoreManager::GetAssetsFromStore( const std::map>& changedData) { std::set assetKeyPrefix; for (const auto& item : changedData) { - if (isAssetKey(GetPropertyName(item.first))) { + if (IsAssetKey(GetPropertyName(item.first))) { assetKeyPrefix.insert(item.first.substr(0, item.first.find_last_of(ObjectStore::ASSET_DOT))); } } @@ -380,12 +510,14 @@ std::map> ObjectStoreManager::GetAsse std::string key(entry.key.begin(), entry.key.end()); result[GetPropertyName(key)] = entry.value; }); - if (!isAssetComplete(result, GetPropertyName(keyPrefix))) { + std::vector splitKeys = SplitEntryKey(keyPrefix); + if (splitKeys.empty() || !IsAssetComplete(result, splitKeys[PROPERTY_NAME_INDEX])) { continue; } - std::string networkId = GetNetworkId(keyPrefix); - for (const auto& [key, value] : result) { - results[GetBundleName(keyPrefix)][networkId][key] = value; + std::string bundleName = splitKeys[BUNDLE_NAME_INDEX]; + std::string networkId = DmAdaper::GetInstance().ToNetworkID(splitKeys[SOURCE_DEVICE_UDID_INDEX]); + for (const auto &[key, value] : result) { + results[bundleName][networkId][key] = value; } } std::map> changedAssets{}; @@ -400,12 +532,12 @@ std::map> ObjectStoreManager::GetAsse return changedAssets; } -bool ObjectStoreManager::isAssetKey(const std::string& key) +bool ObjectStoreManager::IsAssetKey(const std::string& key) { return key.find(ObjectStore::ASSET_DOT) != std::string::npos; } -bool ObjectStoreManager::isAssetComplete(const std::map>& result, +bool ObjectStoreManager::IsAssetComplete(const std::map>& result, const std::string& assetPrefix) { if (result.find(assetPrefix + ObjectStore::NAME_SUFFIX) == result.end() || @@ -425,7 +557,7 @@ Assets ObjectStoreManager::GetAssetsFromDBRecords(const std::map assetKey; for (const auto& [key, value] : result) { std::string assetPrefix = key.substr(0, key.find(ObjectStore::ASSET_DOT)); - if (!isAssetKey(key) || assetKey.find(assetPrefix) != assetKey.end() || + if (!IsAssetKey(key) || assetKey.find(assetPrefix) != assetKey.end() || result.find(assetPrefix + ObjectStore::NAME_SUFFIX) == result.end() || result.find(assetPrefix + ObjectStore::URI_SUFFIX) == result.end()) { continue; @@ -459,14 +591,36 @@ Assets ObjectStoreManager::GetAssetsFromDBRecords(const std::map>>& data) + const std::map>>& data, bool allReady) { for (const auto& observer : value.observers_) { auto it = data.find(observer.first); if (it == data.end()) { continue; } - observer.second->Completed((*it).second); + observer.second->Completed((*it).second, allReady); + if (allReady) { + restoreStatus_.Erase(observer.first); + } + } +} + +void ObjectStoreManager::DoNotifyAssetsReady(uint32_t tokenId, const CallbackInfo& value, + const std::string& objectKey, bool allReady) +{ + for (const auto& observer : value.observers_) { + if (objectKey != observer.first) { + continue; + } + observer.second->Completed(std::map>(), allReady); + if (allReady) { + restoreStatus_.Erase(objectKey); + } + auto [has, taskId] = objectTimer_.Find(objectKey); + if (has) { + executors_->Remove(taskId); + objectTimer_.Erase(objectKey); + } } } @@ -561,9 +715,14 @@ void ObjectStoreManager::ProcessOldEntry(const std::string &appId) std::string deleteKey; for (auto &item : entries) { std::string key(item.key.begin(), item.key.end()); - std::string id = GetSessionId(key); + std::vector splitKeys = SplitEntryKey(key); + if (splitKeys.empty()) { + continue; + } + std::string id = splitKeys[SESSION_ID_INDEX]; if (sessionIds.count(id) == 0) { - sessionIds[id] = GetTime(key); + char *end = nullptr; + sessionIds[id] = strtol(splitKeys[TIME_INDEX].c_str(), &end, DECIMAL_BASE); } if (oldestTime == 0 || oldestTime > sessionIds[id]) { oldestTime = sessionIds[id]; @@ -598,6 +757,8 @@ int32_t ObjectStoreManager::SaveToStore(const std::string &appId, const std::str auto status = delegate_->PutBatch(entries); if (status != DistributedDB::DBStatus::OK) { ZLOGE("putBatch fail %{public}d", status); + RADAR_REPORT(ObjectStore::SAVE, ObjectStore::SAVE_TO_STORE, ObjectStore::RADAR_FAILED, + ObjectStore::ERROR_CODE, status, ObjectStore::BIZ_STATE, ObjectStore::FINISHED); } return status; } @@ -685,6 +846,10 @@ int32_t ObjectStoreManager::RetrieveFromStore( std::vector entries; std::string prefix = GetPrefixWithoutDeviceId(appId, sessionId); auto status = delegate_->GetEntries(std::vector(prefix.begin(), prefix.end()), entries); + if (status == DistributedDB::DBStatus::NOT_FOUND) { + ZLOGW("key not found, status = %{public}d", status); + return KEY_NOT_FOUND; + } if (status != DistributedDB::DBStatus::OK) { ZLOGE("GetEntries failed, status = %{public}d", status); return DB_ERROR; @@ -697,19 +862,59 @@ int32_t ObjectStoreManager::RetrieveFromStore( return OBJECT_SUCCESS; } -void ObjectStoreManager::ProcessKeyByIndex(std::string &key, uint8_t index) +std::vector ObjectStoreManager::SplitEntryKey(const std::string &key) { - std::size_t pos; - uint8_t i = 0; - do { - pos = key.find(SEPERATOR); - if (pos == std::string::npos) { - return; - } - key.erase(0, pos + 1); - i++; - } while (i < index); + std::smatch match; + std::regex timeRegex(TIME_REGEX); + if (!std::regex_search(key, match, timeRegex)) { + ZLOGE("Format error, key.size = %{public}zu", key.size()); + return {}; + } + size_t timePos = match.position(); + std::string fromTime = key.substr(timePos + 1); + std::string beforeTime = key.substr(0, timePos); + + size_t targetDevicePos = beforeTime.find_last_of(SEPERATOR); + if (targetDevicePos == std::string::npos) { + ZLOGE("Format error, key.size = %{public}zu", key.size()); + return {}; + } + std::string targetDevice = beforeTime.substr(targetDevicePos + 1); + std::string beforeTargetDevice = beforeTime.substr(0, targetDevicePos); + + size_t sourceDeviceUdidPos = beforeTargetDevice.find_last_of(SEPERATOR); + if (sourceDeviceUdidPos == std::string::npos) { + ZLOGE("Format error, key.size = %{public}zu", key.size()); + return {}; + } + std::string sourceDeviceUdid = beforeTargetDevice.substr(sourceDeviceUdidPos + 1); + std::string beforeSourceDeviceUdid = beforeTargetDevice.substr(0, sourceDeviceUdidPos); + + size_t sessionIdPos = beforeSourceDeviceUdid.find_last_of(SEPERATOR); + if (sessionIdPos == std::string::npos) { + ZLOGE("Format error, key.size = %{public}zu", key.size()); + return {}; + } + std::string sessionId = beforeSourceDeviceUdid.substr(sessionIdPos + 1); + std::string bundleName = beforeSourceDeviceUdid.substr(0, sessionIdPos); + + size_t propertyNamePos = fromTime.find_first_of(SEPERATOR); + if (propertyNamePos == std::string::npos) { + ZLOGE("Format error, key.size = %{public}zu", key.size()); + return {}; + } + std::string propertyName = fromTime.substr(propertyNamePos + 1); + std::string time = fromTime.substr(0, propertyNamePos); + + return { bundleName, sessionId, sourceDeviceUdid, targetDevice, time, propertyName }; +} + +std::string ObjectStoreManager::GetPropertyName(const std::string &key) +{ + std::vector splitKeys = SplitEntryKey(key); + return splitKeys.empty() ? "" : splitKeys[PROPERTY_NAME_INDEX]; } + std::string ObjectStoreManager::GetCurrentUser() { std::vector users; @@ -739,69 +944,11 @@ void ObjectStoreManager::SaveUserToMeta() } } -std::string ObjectStoreManager::GetPropertyName(const std::string &key) -{ - std::string result = key; - ProcessKeyByIndex(result, 5); // property name is after 5 '_' - return result; -} - -std::string ObjectStoreManager::GetSessionId(const std::string &key) -{ - std::string result = key; - ProcessKeyByIndex(result, 1); // sessionId is after 1 '_' - auto pos = result.find(SEPERATOR); - if (pos == std::string::npos) { - return result; - } - result.erase(pos); - return result; -} - -int64_t ObjectStoreManager::GetTime(const std::string &key) -{ - std::string result = key; - std::size_t pos; - int8_t i = 0; - do { - pos = result.find(SEPERATOR); - result.erase(0, pos + 1); - i++; - } while (pos != std::string::npos && i < 4); // time is after 4 '_' - pos = result.find(SEPERATOR); - result.erase(pos); - char *end = nullptr; - return std::strtol(result.c_str(), &end, DECIMAL_BASE); -} - void ObjectStoreManager::CloseAfterMinute() { executors_->Schedule(std::chrono::minutes(INTERVAL), std::bind(&ObjectStoreManager::Close, this)); } -std::string ObjectStoreManager::GetBundleName(const std::string &key) -{ - std::size_t pos = key.find(SEPERATOR); - if (pos == std::string::npos) { - return std::string(); - } - std::string result = key; - result.erase(pos); - return result; -} - -std::string ObjectStoreManager::GetNetworkId(const std::string& key) -{ - std::stringstream keyStream(key); - std::string sourceDeviceUdId; - for (int i = 0; getline(keyStream, sourceDeviceUdId, *SEPERATOR); i++) { - if (i == SOURCE_DEVICE_ID_INDEX) { - return DmAdaper::GetInstance().ToNetworkID(sourceDeviceUdId); - } - } - return {}; -} - void ObjectStoreManager::SetThreadPool(std::shared_ptr executors) { executors_ = executors; diff --git a/datamgr_service/services/distributeddataservice/service/object/object_manager.h b/datamgr_service/services/distributeddataservice/service/object/object_manager.h index 9d3f44f7..8ff416a5 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_manager.h +++ b/datamgr_service/services/distributeddataservice/service/object/object_manager.h @@ -12,7 +12,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #ifndef DISTRIBUTEDDATAMGR_OBJECT_MANAGER_H #define DISTRIBUTEDDATAMGR_OBJECT_MANAGER_H @@ -20,17 +19,17 @@ #include "concurrent_map.h" #include "device_manager_adapter.h" -#include "object_callback.h" -#include "object_callback_proxy.h" #include "kv_store_delegate_manager.h" #include "kvstore_sync_callback.h" +#include "object_asset_loader.h" +#include "object_callback.h" +#include "object_callback_proxy.h" #include "object_common.h" #include "object_data_listener.h" -#include "types.h" #include "object_snapshot.h" #include "object_types.h" +#include "types.h" #include "value_proxy.h" - namespace OHOS { namespace DistributedObject { using SyncCallBack = std::function &results)>; @@ -64,7 +63,17 @@ class ObjectStoreManager { public: using DmAdaper = OHOS::DistributedData::DeviceManagerAdapter; using UriToSnapshot = std::shared_ptr>>; + + enum RestoreStatus : int32_t { + NONE = 0, + DATA_READY, + ASSETS_READY, + ALL_READY, + STATUS_BUTT + }; + ObjectStoreManager(); + ~ObjectStoreManager(); static ObjectStoreManager *GetInstance() { static ObjectStoreManager *manager = new ObjectStoreManager(); @@ -86,6 +95,8 @@ public: void UnregisterRemoteCallback(const std::string &bundleName, pid_t pid, uint32_t tokenId, const std::string &sessionId = ""); void NotifyChange(std::map> &changedData); + void NotifyAssetsReady(const std::string& objectKey, const std::string& srcNetworkId = ""); + void NotifyAssetsStart(const std::string& objectKey, const std::string& srcNetworkId = ""); void CloseAfterMinute(); int32_t Open(); void SetThreadPool(std::shared_ptr executors); @@ -97,12 +108,19 @@ public: void DeleteSnapshot(const std::string &bundleName, const std::string &sessionId); private: constexpr static const char *SEPERATOR = "_"; + constexpr static const char *TIME_REGEX = "_\\d{10}_p_"; + constexpr static int BUNDLE_NAME_INDEX = 0; + constexpr static int SESSION_ID_INDEX = 1; + constexpr static int SOURCE_DEVICE_UDID_INDEX = 2; + constexpr static int TIME_INDEX = 4; + constexpr static int PROPERTY_NAME_INDEX = 5; constexpr static const char *LOCAL_DEVICE = "local"; constexpr static const char *USERID = "USERID"; constexpr static int8_t MAX_OBJECT_SIZE_PER_APP = 16; constexpr static int8_t DECIMAL_BASE = 10; - constexpr static int8_t SOURCE_DEVICE_ID_INDEX = 2; constexpr static int WAIT_TIME = 60; + static constexpr size_t TIME_TASK_NUM = 1; + static constexpr int64_t INTERVAL = 1; struct CallbackInfo { pid_t pid; std::map> observers_; @@ -125,25 +143,27 @@ private: int32_t RetrieveFromStore( const std::string &appId, const std::string &sessionId, std::map> &results); void SyncCompleted(const std::map &results, uint64_t sequenceId); - void ProcessKeyByIndex(std::string &key, uint8_t index); + std::vector SplitEntryKey(const std::string &key); std::string GetPropertyName(const std::string &key); - std::string GetSessionId(const std::string &key); - std::string GetBundleName(const std::string &key); - std::string GetNetworkId(const std::string& key); - int64_t GetTime(const std::string &key); void ProcessOldEntry(const std::string &appId); void ProcessSyncCallback(const std::map &results, const std::string &appId, const std::string &sessionId, const std::string &deviceId); void SaveUserToMeta(); std::string GetCurrentUser(); void DoNotify(uint32_t tokenId, const CallbackInfo& value, - const std::map>>& data); + const std::map>>& data, bool allReady); + void DoNotifyAssetsReady(uint32_t tokenId, const CallbackInfo& value, const std::string& objectKey, bool allReady); std::map> GetAssetsFromStore( const std::map>& changedData); - static bool isAssetKey(const std::string& key); - static bool isAssetComplete(const std::map>& result, + static bool IsAssetKey(const std::string& key); + static bool IsAssetComplete(const std::map>& result, const std::string& assetPrefix); Assets GetAssetsFromDBRecords(const std::map>& result); + bool RegisterAssetsLister(); + void NotifyDataChanged(std::map>>& data); + int32_t PushAssets(int32_t userId, const std::string &appId, const std::string &sessionId, + const std::map> &data, const std::string &deviceId); + int32_t WaitAssets(const std::string& objectKey); inline std::string GetPropertyPrefix(const std::string &appId, const std::string &sessionId) { return appId + SEPERATOR + sessionId + SEPERATOR + DmAdaper::GetInstance().GetLocalDevice().udid + SEPERATOR; @@ -168,17 +188,19 @@ private: DistributedDB::KvStoreDelegateManager *kvStoreDelegateManager_ = nullptr; DistributedDB::KvStoreNbDelegate *delegate_ = nullptr; ObjectDataListener *objectDataListener_ = nullptr; + sptr objectAssetsRecvListener_ = nullptr; + sptr objectAssetsSendListener_ = nullptr; uint32_t syncCount_ = 0; std::string userId_; std::atomic isSyncing_ = false; ConcurrentMap callbacks_; - 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 + ConcurrentMap restoreStatus_; // key:bundleName+sessionId + ConcurrentMap objectTimer_; // key:bundleName+sessionId }; } // 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 a780f7c2..4b225813 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/object/object_service_impl.cpp @@ -31,10 +31,10 @@ #include "metadata/meta_data_manager.h" #include "metadata/store_meta_data.h" #include "object_asset_loader.h" -#include "permission/permission_validator.h" #include "snapshot/bind_event.h" #include "store/auto_cache.h" #include "utils/anonymous.h" +#include "object_radar_reporter.h" namespace OHOS::DistributedObject { using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; @@ -63,19 +63,18 @@ int32_t ObjectServiceImpl::ObjectStoreSave(const std::string &bundleName, const sptr callback) { ZLOGI("begin."); + RADAR_REPORT(ObjectStore::SAVE, ObjectStore::SAVE_TO_STORE, ObjectStore::IDLE); uint32_t tokenId = IPCSkeleton::GetCallingTokenID(); int32_t status = IsBundleNameEqualTokenId(bundleName, sessionId, tokenId); if (status != OBJECT_SUCCESS) { return status; } - if (!DistributedKv::PermissionValidator::GetInstance().CheckSyncPermission(tokenId)) { - ZLOGE("object save permission denied"); - return OBJECT_PERMISSION_DENIED; - } status = ObjectStoreManager::GetInstance()->Save(bundleName, sessionId, data, deviceId, callback); if (status != OBJECT_SUCCESS) { ZLOGE("save fail %{public}d", status); } + RADAR_REPORT(ObjectStore::SAVE, ObjectStore::SAVE_TO_STORE, ObjectStore::RADAR_SUCCESS, ObjectStore::BIZ_STATE, + ObjectStore::FINISHED); return status; } @@ -177,10 +176,6 @@ int32_t ObjectServiceImpl::ObjectStoreRevokeSave( if (status != OBJECT_SUCCESS) { return status; } - if (!DistributedKv::PermissionValidator::GetInstance().CheckSyncPermission(tokenId)) { - ZLOGE("object revoke save permission denied"); - return OBJECT_PERMISSION_DENIED; - } status = ObjectStoreManager::GetInstance()->RevokeSave(bundleName, sessionId, callback); if (status != OBJECT_SUCCESS) { ZLOGE("revoke save fail %{public}d", status); @@ -198,13 +193,11 @@ int32_t ObjectServiceImpl::ObjectStoreRetrieve( if (status != OBJECT_SUCCESS) { return status; } - if (!DistributedKv::PermissionValidator::GetInstance().CheckSyncPermission(tokenId)) { - ZLOGE("object retrieve permission denied"); - return OBJECT_PERMISSION_DENIED; - } status = ObjectStoreManager::GetInstance()->Retrieve(bundleName, sessionId, callback, tokenId); if (status != OBJECT_SUCCESS) { ZLOGE("retrieve fail %{public}d", status); + RADAR_REPORT(ObjectStore::CREATE, ObjectStore::RESTORE, ObjectStore::RADAR_FAILED, + ObjectStore::ERROR_CODE, status, ObjectStore::BIZ_STATE, ObjectStore::FINISHED); return status; } return OBJECT_SUCCESS; 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 ae213fd8..60cf85ae 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_service_impl.h +++ b/datamgr_service/services/distributeddataservice/service/object/object_service_impl.h @@ -20,10 +20,9 @@ #include "object_manager.h" #include "object_service_stub.h" #include "visibility.h" -#include "object_data_listener.h" namespace OHOS::DistributedObject { -class API_EXPORT ObjectServiceImpl : public ObjectServiceStub { +class ObjectServiceImpl : public ObjectServiceStub { public: using Handler = std::function> &)>; ObjectServiceImpl(); diff --git a/datamgr_service/services/distributeddataservice/service/object/object_snapshot.cpp b/datamgr_service/services/distributeddataservice/service/object/object_snapshot.cpp index cc01ee69..29c7fc87 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_snapshot.cpp +++ b/datamgr_service/services/distributeddataservice/service/object/object_snapshot.cpp @@ -20,8 +20,9 @@ #include "log_print.h" #include "snapshot/bind_event.h" #include "store/general_store.h" +#include "utils/anonymous.h" namespace OHOS::DistributedObject { - +using namespace OHOS::DistributedData; int32_t ObjectSnapshot::Upload(Asset& asset) { if (!IsBoundAsset(asset)) { @@ -84,7 +85,7 @@ int32_t ObjectSnapshot::BindAsset(const Asset& asset, const DistributedData::Ass const StoreInfo& storeInfo) { if (IsBoundAsset(asset)) { - ZLOGD("Asset is bound. asset.uri:%{public}s :", asset.uri.c_str()); + ZLOGD("Asset is bound. asset.uri:%{public}s :", Anonymous::Change(asset.uri, true).c_str()); return E_OK; } changedAssets_[asset.uri] = ChangedAssetInfo(asset, bindInfo, storeInfo); diff --git a/datamgr_service/services/distributeddataservice/service/permission/src/permit_delegate.cpp b/datamgr_service/services/distributeddataservice/service/permission/src/permit_delegate.cpp index 5e59276f..6e9e9cb4 100644 --- a/datamgr_service/services/distributeddataservice/service/permission/src/permit_delegate.cpp +++ b/datamgr_service/services/distributeddataservice/service/permission/src/permit_delegate.cpp @@ -69,7 +69,7 @@ void PermitDelegate::Init() bool PermitDelegate::SyncActivate(const ActiveParam ¶m) { ZLOGD("user:%{public}s, app:%{public}s, store:%{public}s, instanceId:%{public}d", - param.userId.c_str(), param.appId.c_str(), param.storeId.c_str(), param.instanceId); + param.userId.c_str(), param.appId.c_str(), Anonymous::Change(param.storeId).c_str(), param.instanceId); if (param.instanceId != 0) { return false; } 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 aa8ed88e..cc1bfb6e 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.cpp @@ -25,6 +25,8 @@ #include "cloud/cloud_store_types.h" #include "cloud/schema_meta.h" #include "cloud_service.h" +#include "commonevent/data_sync_event.h" +#include "communicator/device_manager_adapter.h" #include "crypto_manager.h" #include "device_manager_adapter.h" #include "eventcenter/event_center.h" @@ -55,6 +57,32 @@ using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; constexpr const char *INSERT = "INSERT INTO "; constexpr const char *REPLACE = "REPLACE INTO "; constexpr const char *VALUES = " VALUES "; +constexpr const LockAction LOCK_ACTION = static_cast(static_cast(LockAction::INSERT) | + static_cast(LockAction::UPDATE) | static_cast(LockAction::DELETE) | + static_cast(LockAction::DOWNLOAD)); +constexpr uint32_t CLOUD_SYNC_FLAG = 1; +constexpr uint32_t SEARCHABLE_FLAG = 2; + +static DBSchema GetDBSchema(const Database &database) +{ + DBSchema schema; + schema.tables.resize(database.tables.size()); + for (size_t i = 0; i < database.tables.size(); i++) { + const Table &table = database.tables[i]; + DBTable &dbTable = schema.tables[i]; + dbTable.name = table.name; + dbTable.sharedTableName = table.sharedTableName; + for (auto &field : table.fields) { + DBField dbField; + dbField.colName = field.colName; + dbField.type = field.type; + dbField.primary = field.primary; + dbField.nullable = field.nullable; + dbTable.fields.push_back(std::move(dbField)); + } + } + return schema; +} RdbGeneralStore::RdbGeneralStore(const StoreMetaData &meta) : manager_(meta.appId, meta.user, meta.instanceId) { @@ -91,6 +119,10 @@ RdbGeneralStore::RdbGeneralStore(const StoreMetaData &meta) : manager_(meta.appI storeInfo_.storeName = meta.storeId; storeInfo_.instanceId = meta.instanceId; storeInfo_.user = std::stoi(meta.user); + storeInfo_.deviceId = DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid; + if (meta.isSearchable) { + syncNotifyFlag_ |= SEARCHABLE_FLAG; + } if (delegate_ != nullptr && meta.isManualClean) { PragmaData data = @@ -120,7 +152,8 @@ int32_t RdbGeneralStore::BindSnapshots(std::shared_ptr &bindInfos) +int32_t RdbGeneralStore::Bind(Database &database, const std::map &bindInfos, + const CloudConfig &config) { if (bindInfos.empty()) { return GeneralError::E_OK; @@ -147,22 +180,11 @@ int32_t RdbGeneralStore::Bind(Database &database, const std::map(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++) { - const Table &table = database.tables[i]; - DBTable &dbTable = schema.tables[i]; - dbTable.name = table.name; - dbTable.sharedTableName = table.sharedTableName; - for (auto &field : table.fields) { - DBField dbField; - dbField.colName = field.colName; - dbField.type = field.type; - dbField.primary = field.primary; - dbField.nullable = field.nullable; - dbTable.fields.push_back(std::move(dbField)); - } - } + DistributedDB::CloudSyncConfig dbConfig; + dbConfig.maxUploadCount = config.maxNumber; + dbConfig.maxUploadSize = config.maxSize; + dbConfig.maxRetryConflictTimes = config.maxRetryConflictTimes; + DBSchema schema = GetDBSchema(database); std::unique_lock lock(rwMutex_); if (delegate_ == nullptr) { ZLOGE("database:%{public}s already closed!", Anonymous::Change(database.name).c_str()); @@ -171,6 +193,9 @@ int32_t RdbGeneralStore::Bind(Database &database, const std::mapSetCloudDB(rdbCloud_); delegate_->SetIAssetLoader(rdbLoader_); delegate_->SetCloudDbSchema(std::move(schema)); + delegate_->SetCloudSyncConfig(dbConfig); + + syncNotifyFlag_ |= CLOUD_SYNC_FLAG; return GeneralError::E_OK; } @@ -461,13 +486,14 @@ int32_t RdbGeneralStore::Sync(const Devices &devices, GenQuery &query, DetailAsy } auto highMode = GetHighMode(static_cast(syncParam.mode)); auto status = (syncMode < NEARBY_END) - ? delegate_->Sync(devices, dbMode, dbQuery, GetDBBriefCB(std::move(async)), syncParam.wait != 0) - : (syncMode > NEARBY_END && syncMode < CLOUD_END) ? delegate_->Sync( - { devices, dbMode, dbQuery, syncParam.wait, (isPriority || highMode == MANUAL_SYNC_MODE), - syncParam.isCompensation, {}, highMode == AUTO_SYNC_MODE }, - GetDBProcessCB(std::move(async), highMode)) - : DistributedDB::INVALID_ARGS; - return status == DistributedDB::OK ? GeneralError::E_OK : GeneralError::E_ERROR; + ? delegate_->Sync(devices, dbMode, dbQuery, GetDBBriefCB(std::move(async), syncMode), syncParam.wait != 0) + : (syncMode > NEARBY_END && syncMode < CLOUD_END) + ? delegate_->Sync({ devices, dbMode, dbQuery, syncParam.wait, (isPriority || highMode == MANUAL_SYNC_MODE), + syncParam.isCompensation, {}, highMode == AUTO_SYNC_MODE, LOCK_ACTION }, + GetDBProcessCB(std::move(async), syncMode, highMode)) + : DistributedDB::INVALID_ARGS; + OnSyncStart(storeInfo_, syncNotifyFlag_, syncMode, status); + return status; } std::shared_ptr RdbGeneralStore::PreSharing(GenQuery &query) @@ -610,17 +636,21 @@ int32_t RdbGeneralStore::Unwatch(int32_t origin, Watcher &watcher) return GeneralError::E_OK; } -RdbGeneralStore::DBBriefCB RdbGeneralStore::GetDBBriefCB(DetailAsync async) +RdbGeneralStore::DBBriefCB RdbGeneralStore::GetDBBriefCB(DetailAsync async, uint32_t syncMode) { if (!async) { - return [](auto &) {}; + return [storeInfo = storeInfo_, flag = syncNotifyFlag_, syncMode](auto &) { + RdbGeneralStore::OnSyncFinish(storeInfo, flag, syncMode); + }; } - return [async = std::move(async)](const std::map> &result) { + return [async = std::move(async), storeInfo = storeInfo_, flag = syncNotifyFlag_, syncMode]( + const std::map> &result) { DistributedData::GenDetails details; for (auto &[key, tables] : result) { auto &value = details[key]; value.progress = FINISHED; value.code = GeneralError::E_OK; + RdbGeneralStore::OnSyncFinish(storeInfo, flag, syncMode); for (auto &table : tables) { if (table.status != DBStatus::OK) { value.code = GeneralError::E_ERROR; @@ -631,18 +661,25 @@ RdbGeneralStore::DBBriefCB RdbGeneralStore::GetDBBriefCB(DetailAsync async) }; } -RdbGeneralStore::DBProcessCB RdbGeneralStore::GetDBProcessCB(DetailAsync async, uint32_t highMode) +RdbGeneralStore::DBProcessCB RdbGeneralStore::GetDBProcessCB(DetailAsync async, uint32_t syncMode, uint32_t highMode) { if (!async && (highMode == MANUAL_SYNC_MODE || !async_)) { - return [](auto &) {}; + return [storeInfo = storeInfo_, flag = syncNotifyFlag_, syncMode](auto &) { + RdbGeneralStore::OnSyncFinish(storeInfo, flag, syncMode); + }; } - return [async, autoAsync = async_, highMode](const std::map &processes) { + return [async, autoAsync = async_, highMode, storeInfo = storeInfo_, flag = syncNotifyFlag_, syncMode]( + const std::map &processes) { DistributedData::GenDetails details; for (auto &[id, process] : processes) { auto &detail = details[id]; detail.progress = process.process; detail.code = ConvertStatus(process.errCode); + detail.dbCode = DB_ERR_OFFSET + process.errCode; + if (process.process == FINISHED) { + RdbGeneralStore::OnSyncFinish(storeInfo, flag, syncMode); + } for (auto [key, value] : process.tableProcess) { auto &table = detail.details[key]; table.upload.total = value.upLoadInfo.total; @@ -774,6 +811,8 @@ RdbGeneralStore::GenErr RdbGeneralStore::ConvertStatus(DistributedDB::DBStatus s return GenErr::E_NO_SPACE_FOR_ASSET; case DBStatus::BUSY: return GenErr::E_BUSY; + case DBStatus::CLOUD_SYNC_TASK_MERGED: + return GenErr::E_SYNC_TASK_MERGED; default: ZLOGI("status:0x%{public}x", status); break; @@ -816,6 +855,31 @@ std::vector RdbGeneralStore::GetWaterVersion(const std::string &dev return {}; } +void RdbGeneralStore::OnSyncStart(const StoreInfo &storeInfo, uint32_t flag, uint32_t syncMode, int status) +{ + uint32_t requiredFlag = (CLOUD_SYNC_FLAG | SEARCHABLE_FLAG); + if (requiredFlag != (requiredFlag & flag)) { + return; + } + if (status != GeneralError::E_OK) { + return; + } + StoreInfo info = storeInfo; + auto evt = std::make_unique(std::move(info), syncMode, DataSyncEvent::DataSyncStatus::START); + EventCenter::GetInstance().PostEvent(std::move(evt)); +} + +void RdbGeneralStore::OnSyncFinish(const StoreInfo &storeInfo, uint32_t flag, uint32_t syncMode) +{ + uint32_t requiredFlag = (CLOUD_SYNC_FLAG | SEARCHABLE_FLAG); + if (requiredFlag != (requiredFlag & flag)) { + return; + } + StoreInfo info = storeInfo; + auto evt = std::make_unique(std::move(info), syncMode, DataSyncEvent::DataSyncStatus::FINISH); + EventCenter::GetInstance().PostEvent(std::move(evt)); +} + void RdbGeneralStore::ObserverProxy::OnChange(const DBChangedIF &data) { if (!HasWatcher()) { diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.h b/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.h index 85ddb9a2..567177c0 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.h @@ -47,7 +47,11 @@ public: explicit RdbGeneralStore(const StoreMetaData &meta); ~RdbGeneralStore(); - int32_t Bind(Database &database, const std::map &bindInfos) override; + + static void OnSyncStart(const DistributedData::StoreInfo &storeInfo, uint32_t flag, uint32_t syncMode, int status); + static void OnSyncFinish(const DistributedData::StoreInfo &storeInfo, uint32_t flag, uint32_t syncMode); + int32_t Bind(Database &database, const std::map &bindInfos, + const CloudConfig &config) override; bool IsBound() override; bool IsValid(); int32_t Execute(const std::string &table, const std::string &sql) override; @@ -110,8 +114,8 @@ private: Watcher *watcher_ = nullptr; std::string storeId_; }; - DBBriefCB GetDBBriefCB(DetailAsync async); - DBProcessCB GetDBProcessCB(DetailAsync async, uint32_t highMode = AUTO_SYNC_MODE); + DBBriefCB GetDBBriefCB(DetailAsync async, uint32_t syncMode); + DBProcessCB GetDBProcessCB(DetailAsync async, uint32_t syncMode, uint32_t highMode = AUTO_SYNC_MODE); std::shared_ptr RemoteQuery(const std::string &device, const DistributedDB::RemoteCondition &remoteCondition); std::string BuildSql(const std::string& table, const std::string& statement, @@ -139,6 +143,7 @@ private: DistributedDB::DBStatus lastError_ = DistributedDB::DBStatus::OK; static constexpr uint32_t PRINT_ERROR_CNT = 150; uint32_t lastErrCnt_ = 0; + uint32_t syncNotifyFlag_ = 0; }; } // 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 c50aaa5b..8fd00e9c 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 @@ -358,6 +358,10 @@ int RdbResultSetImpl::GetRow(NativeRdb::RowEntity& rowEntity) int RdbResultSetImpl::GetSize(int col, size_t& size) { + std::shared_lock lock(mutex_); + if (resultSet_ == nullptr) { + return NativeRdb::E_ALREADY_CLOSED; + } auto [errCode, value] = GetValue(col); if (errCode != NativeRdb::E_OK) { return errCode; 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 02772239..aead0cfb 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 @@ -241,16 +241,6 @@ int32_t RdbResultSetStub::OnGetSize(MessageParcel &data, MessageParcel &reply) return 0; } -int32_t RdbResultSetStub::OnIsClosed(MessageParcel &data, MessageParcel &reply) -{ - bool isClosed = resultSet_->IsClosed(); - if (!ITypesUtil::Marshal(reply, isClosed)) { - ZLOGE("Write isClosed failed, isClosed:%{public}d.", isClosed); - return -1; - } - return 0; -} - int32_t RdbResultSetStub::OnClose(MessageParcel &data, MessageParcel &reply) { int status = resultSet_->Close(); 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 694e01d6..4c2d6210 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 @@ -45,7 +45,6 @@ private: int32_t OnIsAtLastRow(MessageParcel &data, MessageParcel &reply); int32_t OnGet(MessageParcel &data, MessageParcel &reply); int32_t OnGetSize(MessageParcel &data, MessageParcel &reply); - int32_t OnIsClosed(MessageParcel &data, MessageParcel &reply); int32_t OnClose(MessageParcel &data, MessageParcel &reply); static bool CheckInterfaceToken(MessageParcel &data); 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 2f95f342..4b3a16c7 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.cpp @@ -18,6 +18,7 @@ #include "account/account_delegate.h" #include "checker/checker_manager.h" #include "abs_rdb_predicates.h" +#include "changeevent/remote_change_event.h" #include "cloud/change_event.h" #include "cloud/cloud_share_event.h" #include "cloud/make_query_event.h" @@ -30,6 +31,7 @@ #include "ipc_skeleton.h" #include "log_print.h" #include "metadata/appid_meta_data.h" +#include "metadata/auto_launch_meta_data.h" #include "metadata/meta_data_manager.h" #include "metadata/store_meta_data.h" #include "rdb_watcher.h" @@ -44,6 +46,7 @@ #include "cloud/schema_meta.h" #include "rdb_general_store.h" #include "rdb_result_set_impl.h" +#include "xcollie.h" using OHOS::DistributedKv::AccountDelegate; using OHOS::DistributedData::CheckerManager; using OHOS::DistributedData::MetaDataManager; @@ -100,6 +103,10 @@ RdbServiceImpl::RdbServiceImpl() meta.GetStoreAlias().c_str()); return; } + if (meta.storeType < StoreMetaData::STORE_RELATIONAL_BEGIN || + meta.storeType > StoreMetaData::STORE_RELATIONAL_END) { + return; + } auto watchers = GetWatchers(meta.tokenId, meta.storeId); auto store = AutoCache::GetInstance().GetStore(meta, watchers); if (store == nullptr) { @@ -221,6 +228,7 @@ std::string RdbServiceImpl::ObtainDistributedTableName(const std::string &device int32_t RdbServiceImpl::InitNotifier(const RdbSyncerParam ¶m, const sptr notifier) { + XCollie xcollie(__FUNCTION__, HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY); if (!CheckAccess(param.bundleName_, "")) { ZLOGE("bundleName:%{public}s. Permission error", param.bundleName_.c_str()); return RDB_ERROR; @@ -596,6 +604,7 @@ int32_t RdbServiceImpl::UnregisterAutoSyncCallback(const RdbSyncerParam& param, int32_t RdbServiceImpl::Delete(const RdbSyncerParam ¶m) { + XCollie xcollie(__FUNCTION__, HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY); auto tokenId = IPCSkeleton::GetCallingTokenID(); AutoCache::GetInstance().CloseStore(tokenId, RemoveSuffix(param.storeName_)); RdbSyncerParam tmpParam = param; @@ -657,6 +666,7 @@ std::pair> RdbServiceImpl::AllocResource(StoreI int32_t RdbServiceImpl::BeforeOpen(RdbSyncerParam ¶m) { + XCollie xcollie(__FUNCTION__, HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY); auto meta = GetStoreMetaData(param); auto isCreated = MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta, true); @@ -682,6 +692,7 @@ void RdbServiceImpl::SetReturnParam(StoreMetaData &metadata, RdbSyncerParam &par int32_t RdbServiceImpl::AfterOpen(const RdbSyncerParam ¶m) { + XCollie xcollie(__FUNCTION__, HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY); 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()); @@ -697,6 +708,15 @@ int32_t RdbServiceImpl::AfterOpen(const RdbSyncerParam ¶m) meta.bundleName.c_str(), meta.GetStoreAlias().c_str(), old.storeType, meta.storeType, old.isEncrypt, meta.isEncrypt, old.area, meta.area); MetaDataManager::GetInstance().SaveMeta(meta.GetKey(), meta, true); + AutoLaunchMetaData launchData; + if (!MetaDataManager::GetInstance().LoadMeta(meta.GetAutoLaunchKey(), launchData, true)) { + RemoteChangeEvent::DataInfo info; + info.bundleName = meta.bundleName; + info.deviceId = meta.deviceId; + info.userId = meta.user; + auto evt = std::make_unique(RemoteChangeEvent::RDB_META_SAVE, std::move(info)); + EventCenter::GetInstance().PostEvent(std::move(evt)); + } } AppIDMetaData appIdMeta; appIdMeta.bundleName = meta.bundleName; @@ -716,7 +736,6 @@ int32_t RdbServiceImpl::AfterOpen(const RdbSyncerParam ¶m) return RDB_ERROR; } } - GetCloudSchema(param); return RDB_OK; } @@ -973,6 +992,7 @@ RdbServiceImpl::~RdbServiceImpl() int32_t RdbServiceImpl::NotifyDataChange(const RdbSyncerParam ¶m, const RdbChangedData &rdbChangedData) { + XCollie xcollie(__FUNCTION__, HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY); 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()); @@ -1012,4 +1032,4 @@ int32_t RdbServiceImpl::Enable(const RdbSyncerParam& param) AutoCache::GetInstance().Enable(tokenId, storeId); return E_OK; } -} // namespace OHOS::DistributedRdb +} // namespace OHOS::DistributedRdb \ No newline at end of file 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 503521e0..344bf3bf 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.h @@ -37,7 +37,7 @@ #include "snapshot/bind_event.h" namespace OHOS::DistributedRdb { -class API_EXPORT RdbServiceImpl : public RdbServiceStub { +class RdbServiceImpl : public RdbServiceStub { public: using StoreMetaData = OHOS::DistributedData::StoreMetaData; using SecretKeyMetaData = DistributedData::SecretKeyMetaData; @@ -154,7 +154,7 @@ private: std::shared_ptr GetStore(const RdbSyncerParam& param); - void OnAsyncComplete(uint32_t tokenId, uint32_t seqNum, Details&& result); + void OnAsyncComplete(uint32_t tokenId, uint32_t seqNum, Details &&result); StoreMetaData GetStoreMetaData(const RdbSyncerParam ¶m); @@ -184,4 +184,4 @@ private: std::shared_ptr executors_; }; } // namespace OHOS::DistributedRdb -#endif +#endif \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/BUILD.gn b/datamgr_service/services/distributeddataservice/service/test/BUILD.gn index 1f223dc0..5aac474e 100644 --- a/datamgr_service/services/distributeddataservice/service/test/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/test/BUILD.gn @@ -22,18 +22,32 @@ config("module_private_config") { include_dirs = [ "//foundation/distributedhardware/device_manager/interfaces/inner_kits/native_cpp/include", - "../bootstrap/include/", - "../config/include/", - "../crypto/include/", - "../directory/include/", - "../kvdb/", - "../matrix/include/", - "../common/", - "../rdb/", - "../object/", - "../../framework/include/", + "${data_service_path}/adapter/include", + "${data_service_path}/app/src", + "${data_service_path}/framework/include", + "${data_service_path}/service/bootstrap/include/", + "${data_service_path}/service/backup/include/", + "${data_service_path}/service/cloud/", + "${data_service_path}/service/config/include/", + "${data_service_path}/service/common/", + "${data_service_path}/service/crypto/include", + "${data_service_path}/service/directory/include/", + "${data_service_path}/service/data_share/common", + "${data_service_path}/service/data_share/data", + "${data_service_path}/service/data_share/strategies", + "${data_service_path}/service/data_share/subscriber_managers", + "${data_service_path}/service/data_share", + "${data_service_path}/service/matrix/include/", + "${data_service_path}/service/kvdb", + "${data_service_path}/service/object/", + "${data_service_path}/service/permission/include", + "${data_service_path}/service/rdb/", + "${data_service_path}/service/test/mock", + "${data_service_path}/service/waterversion", "${dataobject_path}/interfaces/innerkits", "${dataobject_path}/frameworks/innerkitsimpl/include", + "${relational_store_path}/interfaces/inner_api/cloud_data/include", + "${relational_store_path}/interfaces/inner_api/common_type/include", ] defines = [ @@ -43,32 +57,76 @@ config("module_private_config") { } ohos_unittest("CloudDataTest") { + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } module_out_path = module_output_path sources = [ + "${data_service_path}/service/backup/src/backup_manager.cpp", + "${data_service_path}/service/bootstrap/src/bootstrap.cpp", + "${data_service_path}/service/cloud/cloud_service_impl.cpp", + "${data_service_path}/service/cloud/cloud_service_stub.cpp", + "${data_service_path}/service/cloud/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/cloud/sync_strategies/network_sync_strategy.cpp", + "${data_service_path}/service/common/common_types_utils.cpp", + "${data_service_path}/service/common/value_proxy.cpp", + "${data_service_path}/service/common/xcollie.cpp", + "${data_service_path}/service/config/src/config_factory.cpp", + "${data_service_path}/service/config/src/model/backup_config.cpp", + "${data_service_path}/service/config/src/model/checker_config.cpp", + "${data_service_path}/service/config/src/model/cloud_config.cpp", + "${data_service_path}/service/config/src/model/component_config.cpp", + "${data_service_path}/service/config/src/model/directory_config.cpp", + "${data_service_path}/service/config/src/model/global_config.cpp", + "${data_service_path}/service/config/src/model/network_config.cpp", + "${data_service_path}/service/config/src/model/protocol_config.cpp", + "${data_service_path}/service/crypto/src/crypto_manager.cpp", + "${data_service_path}/service/matrix/src/device_matrix.cpp", + "${data_service_path}/service/matrix/src/matrix_event.cpp", + "${data_service_path}/service/rdb/cache_cursor.cpp", + "${data_service_path}/service/rdb/rdb_asset_loader.cpp", + "${data_service_path}/service/rdb/rdb_cloud.cpp", + "${data_service_path}/service/rdb/rdb_cloud_data_translate.cpp", + "${data_service_path}/service/rdb/rdb_cursor.cpp", + "${data_service_path}/service/rdb/rdb_general_store.cpp", + "${data_service_path}/service/rdb/rdb_notifier_proxy.cpp", + "${data_service_path}/service/rdb/rdb_query.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/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/test/mock/checker_mock.cpp", + "${data_service_path}/service/waterversion/water_version_manager.cpp", "cloud_data_test.cpp", - "mock/db_change_data_mock.cpp", - "mock/db_store_mock.cpp", ] - include_dirs = - [ "../../../../../relational_store/interfaces/inner_api/rdb/include" ] - configs = [ ":module_private_config" ] external_deps = [ "ability_base:base", "ability_base:want", + "access_token:libaccesstoken_sdk", + "access_token:libtoken_setproc", + "access_token:libtokenid_sdk", "c_utils:utils", + "hicollie:libhicollie", "hilog:libhilog", + "huks:libhukssdk", "ipc:ipc_core", "kv_store:distributeddata_inner", + "kv_store:distributeddb", + "relational_store:native_rdb", ] deps = [ - "${kv_store_distributeddb_path}:distributeddb", "../../adapter:distributeddata_adapter", "../../framework:distributeddatasvcfwk", - "../../service:distributeddatasvc", + "mock:distributeddata_mock_static", "//third_party/googletest:gtest_main", ] } @@ -86,13 +144,14 @@ ohos_unittest("CloudTest") { "hilog:libhilog", "ipc:ipc_core", "kv_store:distributeddata_inner", + "kv_store:distributeddb", ] deps = [ - "${kv_store_distributeddb_path}:distributeddb", "../../adapter:distributeddata_adapter", "../../framework:distributeddatasvcfwk", "../../service:distributeddatasvc", + "mock:distributeddata_mock_static", "//third_party/googletest:gtest_main", ] } @@ -208,6 +267,7 @@ ohos_unittest("DeviceMatrixTest") { module_out_path = module_output_path sources = [ "device_matrix_test.cpp", + "mock/checker_mock.cpp", "mock/db_change_data_mock.cpp", "mock/db_store_mock.cpp", ] @@ -225,9 +285,9 @@ ohos_unittest("DeviceMatrixTest") { ] deps = [ - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter:distributeddata_adapter", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/framework:distributeddatasvcfwk", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/service:distributeddatasvc", + "${data_service_path}/adapter:distributeddata_adapter", + "${data_service_path}/framework:distributeddatasvcfwk", + "${data_service_path}/service:distributeddatasvc", "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb:distributeddb", "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata:distributeddata_inner", "//third_party/googletest:gtest_main", @@ -259,6 +319,7 @@ ohos_unittest("AutoSyncMatrixTest") { "c_utils:utils", "dataclassification:data_transit_mgr", "hilog:libhilog", + "hisysevent:libhisysevent", "ipc:ipc_core", "kv_store:distributeddata_inner", ] @@ -279,6 +340,7 @@ ohos_unittest("KVDBGeneralStoreTest") { "../kvdb/kvdb_general_store.cpp", "../rdb/rdb_cloud.cpp", "../rdb/rdb_query.cpp", + "../waterversion/water_version_manager.cpp", "kvdb_general_store_test.cpp", "mock/db_change_data_mock.cpp", "mock/db_store_mock.cpp", @@ -334,6 +396,13 @@ ohos_unittest("RdbResultSetImplTest") { configs = [ ":module_private_config" ] + cflags = [ + "-Dprivate=public", + "-Dprotected=public", + "-Wno-multichar", + "-Wno-c99-designator", + ] + external_deps = [ "ability_base:base", "ability_base:want", @@ -354,20 +423,44 @@ ohos_unittest("RdbResultSetImplTest") { ] } -ohos_unittest("CacheCursorTest") { +ohos_unittest("RdbServiceTest") { module_out_path = module_output_path sources = [ + "${data_service_path}/service/common/value_proxy.cpp", "${data_service_path}/service/rdb/cache_cursor.cpp", + "${data_service_path}/service/rdb/rdb_asset_loader.cpp", + "${data_service_path}/service/rdb/rdb_cloud.cpp", + "${data_service_path}/service/rdb/rdb_cloud_data_translate.cpp", + "${data_service_path}/service/rdb/rdb_cursor.cpp", + "${data_service_path}/service/rdb/rdb_general_store.cpp", + "${data_service_path}/service/rdb/rdb_notifier_proxy.cpp", + "${data_service_path}/service/rdb/rdb_query.cpp", + "${data_service_path}/service/rdb/rdb_result_set_impl.cpp", + "${data_service_path}/service/rdb/rdb_result_set_stub.cpp", "cache_cursor_test.cpp", + "rdb_asset_loader_test.cpp", + "rdb_cloud_test.cpp", + "rdb_cursor_test.cpp", + "rdb_general_store_test.cpp", + "rdb_query_test.cpp", + "rdb_result_set_stub_test.cpp", ] include_dirs = [ - "${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" ] + cflags = [ + "-Dprivate=public", + "-Dprotected=public", + "-Wno-multichar", + "-Wno-c99-designator", + ] + external_deps = [ "ability_base:base", "ability_base:want", @@ -376,13 +469,17 @@ ohos_unittest("CacheCursorTest") { "c_utils:utils", "hilog:libhilog", "ipc:ipc_core", + "kv_store:distributeddata_inner", + "kv_store:distributeddb", ] deps = [ "${data_service_path}/adapter:distributeddata_adapter", "${data_service_path}/adapter/utils:distributeddata_utils_static", "${data_service_path}/framework:distributeddatasvcfwk", + "${data_service_path}/service:distributeddatasvc", "${kv_store_distributeddb_path}:distributeddb", + "${relational_store_inner_api_path}:native_rdb_static", "//third_party/googletest:gtest_main", ] } @@ -396,6 +493,7 @@ ohos_unittest("ObjectAssetMachineTest") { ] include_dirs = [ + "${dataobject_path}/frameworks/innerkitsimpl/include/common", "${dataobject_path}/interfaces/innerkits", "${relational_store_path}/interfaces/inner_api/common_type/include", ] @@ -405,7 +503,9 @@ ohos_unittest("ObjectAssetMachineTest") { external_deps = [ "c_utils:utils", "dfs_service:cloudsync_asset_kit_inner", + "dfs_service:distributed_file_daemon_kit_inner", "hilog:libhilog", + "hisysevent:libhisysevent", "ipc:ipc_core", "kv_store:distributeddata_inner", ] @@ -425,6 +525,12 @@ ohos_unittest("MetaDataTest") { "meta_data_test.cpp", ] + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + include_dirs = [ "${data_service_path}/app/src", "${data_service_path}/service/kvdb", @@ -443,6 +549,7 @@ ohos_unittest("MetaDataTest") { "c_utils:utils", "dataclassification:data_transit_mgr", "hilog:libhilog", + "hisysevent:libhisysevent", "ipc:ipc_core", "kv_store:distributeddata_inner", ] @@ -486,6 +593,7 @@ ohos_unittest("UdmfRunTimeStoreTest") { "dataclassification:data_transit_mgr", "dsoftbus:softbus_client", "hilog:libhilog", + "hisysevent:libhisysevent", "image_framework:image", "ipc:ipc_core", "kv_store:distributeddata_inner", @@ -524,6 +632,7 @@ ohos_unittest("WaterVersionManagerTest") { "${data_service_path}/service/config/src/model/network_config.cpp", "${data_service_path}/service/config/src/model/protocol_config.cpp", "${data_service_path}/service/waterversion/water_version_manager.cpp", + "mock/checker_mock.cpp", "mock/db_change_data_mock.cpp", "mock/db_store_mock.cpp", "water_version_manager_test.cpp", @@ -560,6 +669,7 @@ ohos_unittest("WaterVersionManagerTest") { "device_auth:deviceauth_sdk", "device_manager:devicemanagersdk", "dfs_service:cloudsync_asset_kit_inner", + "dfs_service:distributed_file_daemon_kit_inner", "dsoftbus:softbus_client", "hilog:libhilog", "ipc:ipc_core", @@ -580,17 +690,6 @@ ohos_unittest("DataShareServiceImplTest") { module_out_path = module_output_path include_dirs = [ - "${data_service_path}/adapter/include", - "${data_service_path}/app/src", - "${data_service_path}/framework/include", - "${data_service_path}/service/crypto/include", - "${data_service_path}/service/data_share/common", - "${data_service_path}/service/data_share/data", - "${data_service_path}/service/data_share/strategies", - "${data_service_path}/service/data_share/subscriber_managers", - "${data_service_path}/service/data_share", - "${data_service_path}/service/kvdb", - "${data_service_path}/service/permission/include", "${datashare_path}/frameworks/native/common/include", "${datashare_path}/interfaces/inner_api/common/include", "${datashare_path}/interfaces/inner_api/consumer/include", @@ -598,6 +697,7 @@ ohos_unittest("DataShareServiceImplTest") { ] sources = [ + "${data_service_path}/service/common/xcollie.cpp", "${data_service_path}/service/crypto/src/crypto_manager.cpp", "${data_service_path}/service/data_share/common/app_connect_manager.cpp", "${data_service_path}/service/data_share/common/base64_utils.cpp", @@ -639,6 +739,7 @@ ohos_unittest("DataShareServiceImplTest") { "${data_service_path}/service/data_share/strategies/template_strategy.cpp", "${data_service_path}/service/data_share/subscriber_managers/published_data_subscriber_manager.cpp", "${data_service_path}/service/data_share/subscriber_managers/rdb_subscriber_manager.cpp", + "${data_service_path}/service/data_share/sys_event_subscriber.cpp", "${data_service_path}/service/kvdb/user_delegate.cpp", "${data_service_path}/service/permission/src/permit_delegate.cpp", "data_share_profile_config_test.cpp", @@ -675,7 +776,9 @@ ohos_unittest("DataShareServiceImplTest") { "common_event_service:cesfwk_innerkits", "data_share:datashare_common", "device_manager:devicemanagersdk", + "hicollie:libhicollie", "hilog:libhilog", + "hisysevent:libhisysevent", "huks:libhukssdk", "ipc:ipc_core", "kv_store:distributeddb", @@ -722,6 +825,7 @@ ohos_unittest("KvdbServiceImplTest") { "c_utils:utils", "dataclassification:data_transit_mgr", "hilog:libhilog", + "hisysevent:libhisysevent", "ipc:ipc_core", "kv_store:distributeddata_inner", ] @@ -758,6 +862,7 @@ group("unittest") { ":MetaDataTest", ":ObjectAssetMachineTest", ":RdbResultSetImplTest", + ":RdbServiceTest", ":UdmfRunTimeStoreTest", ":ValueProxyTest", ":WaterVersionManagerTest", diff --git a/datamgr_service/services/distributeddataservice/service/test/auto_sync_matrix_test.cpp b/datamgr_service/services/distributeddataservice/service/test/auto_sync_matrix_test.cpp index 445802a7..adc50222 100644 --- a/datamgr_service/services/distributeddataservice/service/test/auto_sync_matrix_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/auto_sync_matrix_test.cpp @@ -57,6 +57,7 @@ void AutoSyncMatrixTest::SetUpTestCase(void) Bootstrap::GetInstance().LoadComponents(); Bootstrap::GetInstance().LoadDirectory(); Bootstrap::GetInstance().LoadCheckers(); + DMAdapter::GetInstance().Init(executors); DistributedKv::KvStoreMetaManager::GetInstance().BindExecutor(executors); DistributedKv::KvStoreMetaManager::GetInstance().InitMetaParameter(); DistributedKv::KvStoreMetaManager::GetInstance().InitMetaListener(); @@ -203,5 +204,27 @@ HWTEST_F(AutoSyncMatrixTest, AutoSyncMatrixOnExchanged, TestSize.Level0) auto metas4 = AutoSyncMatrix::GetInstance().GetChangedStore(TEST_DEVICE); ASSERT_GE(metas4.size(), metas1.size()); } + +/** +* @tc.name: AutoSyncMatrixDeleteMeta +* @tc.desc: auto sync matrix on delete Meta. +* @tc.type: FUNC +* @tc.require: +* @tc.author: zuojiangjiang +*/ +HWTEST_F(AutoSyncMatrixTest, AutoSyncMatrixDeleteMeta, TestSize.Level0) +{ + AutoSyncMatrix::GetInstance().Online(TEST_DEVICE); + AutoSyncMatrix::GetInstance().OnChanged(metaData_); + auto metas1 = AutoSyncMatrix::GetInstance().GetChangedStore(TEST_DEVICE); + ASSERT_GE(metas1.size(), 0); + MetaDataManager::GetInstance().DelMeta(metaData_.GetKey()); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + auto metas2 = AutoSyncMatrix::GetInstance().GetChangedStore(TEST_DEVICE); + ASSERT_GE(metas2.size(), metas1.size() -1); + for (auto meta : metas2) { + ASSERT_NE(metaData_.GetKey(), meta.GetKey()); + } +} } // namespace DistributedDataTest } // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/cache_cursor_test.cpp b/datamgr_service/services/distributeddataservice/service/test/cache_cursor_test.cpp index 65b26147..ac8efd48 100644 --- a/datamgr_service/services/distributeddataservice/service/test/cache_cursor_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/cache_cursor_test.cpp @@ -1,28 +1,32 @@ /* -* Copyright (c) 2023 Huawei Device Co., Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #define LOG_TAG "CacheCursorTest" -#include -#include "log_print.h" + #include "cache_cursor.h" +#include "gtest/gtest.h" +#include "log_print.h" +#include "store/cursor.h" #include "store/general_value.h" + +using namespace OHOS; +using namespace testing; using namespace testing::ext; -using namespace OHOS::DistributedData; using namespace OHOS::DistributedRdb; - +using namespace OHOS::DistributedData; namespace OHOS::Test { -namespace DistributedDataTest { +namespace DistributedRDBTest { static constexpr int MAX_DATA_NUM = 100; static constexpr int AGE = 25; static constexpr const char *NAME = "tony"; @@ -30,19 +34,18 @@ static constexpr const char *PHONENUMBER = "10086"; class CacheCursorTest : public testing::Test { public: static void SetUpTestCase(void); - static void TearDownTestCase(void); - void SetUp(); - void TearDown(); + static void TearDownTestCase(void){}; + void SetUp(){}; + void TearDown(){}; static std::shared_ptr GetCursor(); protected: CacheCursorTest(); - void InitData(); static std::shared_ptr cursor_; }; std::shared_ptr CacheCursorTest::cursor_ = nullptr; -CacheCursorTest::CacheCursorTest() { } +CacheCursorTest::CacheCursorTest() {} std::shared_ptr CacheCursorTest::GetCursor() { @@ -61,44 +64,51 @@ void CacheCursorTest::SetUpTestCase(void) records.push_back(record); } cursor_ = std::make_shared(std::move(records)); -} - -void CacheCursorTest::TearDownTestCase() {} - -void CacheCursorTest::SetUp() {} - -void CacheCursorTest::TearDown() {} +}; -HWTEST_F(CacheCursorTest, CacheCursorTest_001, TestSize.Level0) +/** +* @tc.name: CacheCursorTest001 +* @tc.desc: RdbCacheCursor function test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(CacheCursorTest, CacheCursorTest001, TestSize.Level1) { auto cursor = CacheCursorTest::GetCursor(); - ASSERT_NE(cursor, nullptr); - std::vector expectedNames {"age", "identifier", "name", "phoneNumber"}; + EXPECT_NE(cursor, nullptr); + std::vector expectedNames = {"age", "identifier", "name", "phoneNumber"}; std::vector names; - auto err = cursor->GetColumnNames(names); + auto result = cursor->GetColumnNames(names); + EXPECT_EQ(result, GeneralError::E_OK); EXPECT_EQ(names, expectedNames); + std::string colName; - err = cursor->GetColumnName(4, colName); + auto err = cursor->GetColumnName(4, colName); + EXPECT_EQ(err, GeneralError::E_INVALID_ARGS); + err = cursor->GetColumnName(-1, colName); EXPECT_EQ(err, GeneralError::E_INVALID_ARGS); + err = cursor->GetColumnName(1, colName); + EXPECT_EQ(err, GeneralError::E_OK); int type = cursor->GetColumnType(0); EXPECT_EQ(type, 1); type = cursor->GetColumnType(4); EXPECT_EQ(type, -1); + type = cursor->GetColumnType(-1); + EXPECT_EQ(type, -1); int count = cursor->GetCount(); - EXPECT_EQ(count, 100); + EXPECT_EQ(count, MAX_DATA_NUM); err = cursor->MoveToFirst(); EXPECT_EQ(err, GeneralError::E_OK); err = cursor->MoveToNext(); EXPECT_EQ(err, GeneralError::E_OK); - for (int i = 2; i < count; i++) { err = cursor->MoveToNext(); } - EXPECT_EQ(err, GeneralError::E_OK); err = cursor->MoveToNext(); EXPECT_EQ(err, GeneralError::E_ERROR); @@ -106,10 +116,50 @@ HWTEST_F(CacheCursorTest, CacheCursorTest_001, TestSize.Level0) EXPECT_EQ(err, GeneralError::E_NOT_SUPPORT); } -HWTEST_F(CacheCursorTest, CacheCursorTest_002, TestSize.Level0) +/** +* @tc.name: UnCacheCursorTest001 +* @tc.desc: RdbCacheCursor function error test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(CacheCursorTest, UnCacheCursorTest001, TestSize.Level1) +{ + auto cursor = CacheCursorTest::GetCursor(); + EXPECT_NE(cursor, nullptr); + std::vector expectedNames = {"age", "identifier", "name", "phoneNumber"}; + std::vector names; + auto result = cursor->GetColumnNames(names); + EXPECT_EQ(result, GeneralError::E_OK); + EXPECT_EQ(names, expectedNames); + + std::string colName; + auto err = cursor->GetColumnName(4, colName); + EXPECT_EQ(err, GeneralError::E_INVALID_ARGS); + err = cursor->GetColumnName(-1, colName); + EXPECT_EQ(err, GeneralError::E_INVALID_ARGS); + err = cursor->GetColumnName(1, colName); + EXPECT_EQ(err, GeneralError::E_OK); + + int type = cursor->GetColumnType(0); + EXPECT_EQ(type, 1); + type = cursor->GetColumnType(4); + EXPECT_EQ(type, -1); + type = cursor->GetColumnType(-1); + EXPECT_EQ(type, -1); +} + +/** +* @tc.name: CacheCursorTest002 +* @tc.desc: RdbCacheCursor function test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(CacheCursorTest, CacheCursorTest002, TestSize.Level0) { auto cursor = CacheCursorTest::GetCursor(); - ASSERT_NE(cursor, nullptr); + EXPECT_NE(cursor, nullptr); auto err = cursor->MoveToFirst(); DistributedData::VBucket data; @@ -119,12 +169,12 @@ HWTEST_F(CacheCursorTest, CacheCursorTest_002, TestSize.Level0) int64_t identifier = *std::get_if(&data["identifier"]); EXPECT_EQ(identifier, 0); std::string name = *std::get_if(&data["name"]); - EXPECT_EQ(name, "Tony"); + EXPECT_EQ(name, "tony"); int64_t age = *std::get_if(&data["age"]); EXPECT_EQ(age, 25); std::string phoneNumber = *std::get_if(&data["phoneNumber"]); EXPECT_EQ(phoneNumber, "10086"); - + while (err == GeneralError::E_OK) { cursor->GetRow(data); err = cursor->MoveToNext(); @@ -140,7 +190,7 @@ HWTEST_F(CacheCursorTest, CacheCursorTest_002, TestSize.Level0) err = cursor->Get("name", value); name = *std::get_if(&value); - EXPECT_EQ(name, "Tony"); + EXPECT_EQ(name, "tony"); bool ret = cursor->IsEnd(); EXPECT_EQ(ret, false); @@ -148,5 +198,62 @@ HWTEST_F(CacheCursorTest, CacheCursorTest_002, TestSize.Level0) err = cursor->Close(); EXPECT_EQ(err, GeneralError::E_OK); } + +/** +* @tc.name: UnCacheCursorTest002 +* @tc.desc: RdbCacheCursor function error test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(CacheCursorTest, UnCacheCursorTest002, TestSize.Level0) +{ + auto cursor = CacheCursorTest::GetCursor(); + EXPECT_NE(cursor, nullptr); + auto err = cursor->MoveToFirst(); + + DistributedData::VBucket data; + err = cursor->GetEntry(data); + EXPECT_EQ(err, GeneralError::E_OK); + + int64_t identifier = *std::get_if(&data["identifier"]); + EXPECT_EQ(identifier, 0); + std::string name = *std::get_if(&data["name"]); + EXPECT_EQ(name, "tony"); + int64_t age = *std::get_if(&data["age"]); + EXPECT_EQ(age, 25); + std::string phoneNumber = *std::get_if(&data["phoneNumber"]); + EXPECT_EQ(phoneNumber, "10086"); + + while (err == GeneralError::E_OK) { + cursor->GetRow(data); + err = cursor->MoveToNext(); + } + + identifier = *std::get_if(&data["identifier"]); + EXPECT_EQ(identifier, 99); + + DistributedData::Value value; + err = cursor->Get(-1, value); + EXPECT_EQ(err, GeneralError::E_INVALID_ARGS); + err = cursor->Get(4, value); + EXPECT_EQ(err, GeneralError::E_INVALID_ARGS); + err = cursor->Get(0, value); + age = *std::get_if(&value); + EXPECT_EQ(age, 25); + + err = cursor->Get("name", value); + name = *std::get_if(&value); + EXPECT_EQ(name, "tony"); + + err = cursor->Get("err", value); + EXPECT_EQ(err, GeneralError::E_INVALID_ARGS); + + bool ret = cursor->IsEnd(); + EXPECT_EQ(ret, false); + + err = cursor->Close(); + EXPECT_EQ(err, GeneralError::E_OK); } -} \ No newline at end of file +} // namespace DistributedRDBTest +} // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/cloud_data_test.cpp b/datamgr_service/services/distributeddataservice/service/test/cloud_data_test.cpp index 09f63137..010d9994 100644 --- a/datamgr_service/services/distributeddataservice/service/test/cloud_data_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/cloud_data_test.cpp @@ -14,31 +14,67 @@ */ #define LOG_TAG "CloudDataTest" #include -#include "log_print.h" -#include "ipc_skeleton.h" +#include + +#include "accesstoken_kit.h" #include "account/account_delegate.h" +#include "bootstrap.h" +#include "checker_mock.h" +#include "cloud/change_event.h" #include "cloud/cloud_event.h" #include "cloud/cloud_server.h" #include "cloud/schema_meta.h" +#include "cloud_service_impl.h" +#include "cloud_types.h" #include "communicator/device_manager_adapter.h" #include "device_matrix.h" #include "eventcenter/event_center.h" #include "feature/feature_system.h" +#include "ipc_skeleton.h" +#include "log_print.h" #include "metadata/meta_data_manager.h" #include "metadata/store_meta_data.h" #include "metadata/store_meta_data_local.h" #include "mock/db_store_mock.h" -#include "store/store_info.h" +#include "mock/general_store_mock.h" +#include "rdb_query.h" +#include "rdb_service.h" +#include "rdb_service_impl.h" #include "rdb_types.h" +#include "store/auto_cache.h" +#include "store/store_info.h" +#include "token_setproc.h" + using namespace testing::ext; using namespace OHOS::DistributedData; +using namespace OHOS::Security::AccessToken; using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; +using Querykey = OHOS::CloudData::QueryKey; +using CloudSyncInfo = OHOS::CloudData::CloudSyncInfo; + +uint64_t g_selfTokenID = 0; + +void AllocHapToken(const HapPolicyParams &policy) +{ + HapInfoParams info = { + .userID = 100, + .bundleName = "test_cloud_bundleName", + .instIndex = 0, + .appIDDesc = "test_cloud_bundleName", + .isSystemApp = true + }; + auto token = AccessTokenKit::AllocHapToken(info, policy); + SetSelfTokenID(token.tokenIDEx); +} namespace OHOS::Test { namespace DistributedDataTest { static constexpr const char *TEST_CLOUD_BUNDLE = "test_cloud_bundleName"; static constexpr const char *TEST_CLOUD_APPID = "test_cloud_appid"; -static constexpr const char *TEST_CLOUD_STORE = "test_cloud_database_name"; +static constexpr const char *TEST_CLOUD_STORE = "test_cloud_store"; +static constexpr const char *TEST_CLOUD_ID = "test_cloud_id"; +static constexpr const char *TEST_CLOUD_DATABASE_ALIAS_1 = "test_cloud_database_alias_1"; +static constexpr const char *TEST_CLOUD_DATABASE_ALIAS_2 = "test_cloud_database_alias_2"; class CloudDataTest : public testing::Test { public: static void SetUpTestCase(void); @@ -47,30 +83,32 @@ public: void TearDown(); static SchemaMeta schemaMeta_; -protected: - static constexpr const char *TEST_DISTRIBUTEDDATA_BUNDLE = "test_distributeddata"; - static constexpr const char *TEST_DISTRIBUTEDDATA_STORE = "test_service_meta"; + static std::shared_ptr cloudServiceImpl_; - void InitMetaData(); - void InitSchemaMeta(); +protected: + static void InitMetaData(); + static void InitSchemaMeta(); + static void InitCloudInfo(); static std::shared_ptr dbStoreMock_; - StoreMetaData metaData_; + static StoreMetaData metaData_; + static CloudInfo cloudInfo_; + static DistributedData::CheckerMock checker_; }; class CloudServerMock : public CloudServer { public: - CloudInfo GetServerInfo(int32_t userId) override; - SchemaMeta GetAppSchema(int32_t userId, const std::string &bundleName) override; + CloudInfo GetServerInfo(int32_t userId, bool needSpaceInfo) override; + std::pair GetAppSchema(int32_t userId, const std::string &bundleName) override; virtual ~CloudServerMock() = default; static constexpr uint64_t REMAINSPACE = 1000; static constexpr uint64_t TATALSPACE = 2000; }; -CloudInfo CloudServerMock::GetServerInfo(int32_t userId) +CloudInfo CloudServerMock::GetServerInfo(int32_t userId, bool needSpaceInfo) { CloudInfo cloudInfo; cloudInfo.user = userId; - cloudInfo.id = "test_cloud_id"; + cloudInfo.id = TEST_CLOUD_ID; cloudInfo.remainSpace = REMAINSPACE; cloudInfo.totalSpace = TATALSPACE; cloudInfo.enableCloud = true; @@ -85,26 +123,31 @@ CloudInfo CloudServerMock::GetServerInfo(int32_t userId) return cloudInfo; } -SchemaMeta CloudServerMock::GetAppSchema(int32_t userId, const std::string &bundleName) +std::pair CloudServerMock::GetAppSchema(int32_t userId, const std::string &bundleName) { - return CloudDataTest::schemaMeta_; + return { E_OK, CloudDataTest::schemaMeta_ }; } std::shared_ptr CloudDataTest::dbStoreMock_ = std::make_shared(); SchemaMeta CloudDataTest::schemaMeta_; +StoreMetaData CloudDataTest::metaData_; +CloudInfo CloudDataTest::cloudInfo_; +std::shared_ptr CloudDataTest::cloudServiceImpl_ = + std::make_shared(); +DistributedData::CheckerMock CloudDataTest::checker_; void CloudDataTest::InitMetaData() { metaData_.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; - metaData_.appId = TEST_DISTRIBUTEDDATA_BUNDLE; - metaData_.bundleName = TEST_DISTRIBUTEDDATA_BUNDLE; + metaData_.appId = TEST_CLOUD_APPID; + metaData_.bundleName = TEST_CLOUD_BUNDLE; metaData_.tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); metaData_.user = std::to_string(DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(metaData_.tokenId)); metaData_.area = OHOS::DistributedKv::EL1; metaData_.instanceId = 0; metaData_.isAutoSync = true; - metaData_.storeType = 1; - metaData_.storeId = TEST_DISTRIBUTEDDATA_STORE; + metaData_.storeType = DistributedRdb::RDB_DEVICE_COLLABORATION; + metaData_.storeId = TEST_CLOUD_STORE; PolicyValue value; value.type = OHOS::DistributedKv::PolicyType::IMMEDIATE_SYNC_ON_ONLINE; } @@ -126,51 +169,99 @@ void CloudDataTest::InitSchemaMeta() SchemaMeta::Database database; database.name = TEST_CLOUD_STORE; - database.alias = "test_cloud_database_alias"; + database.alias = TEST_CLOUD_DATABASE_ALIAS_1; database.tables.emplace_back(table); schemaMeta_.version = 1; - schemaMeta_.bundleName = TEST_DISTRIBUTEDDATA_BUNDLE; + schemaMeta_.bundleName = TEST_CLOUD_BUNDLE; + schemaMeta_.databases.emplace_back(database); + database.alias = TEST_CLOUD_DATABASE_ALIAS_2; schemaMeta_.databases.emplace_back(database); } +void CloudDataTest::InitCloudInfo() +{ + cloudInfo_.user = DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(IPCSkeleton::GetCallingTokenID()); + cloudInfo_.id = TEST_CLOUD_ID; + cloudInfo_.enableCloud = true; + + CloudInfo::AppInfo appInfo; + appInfo.bundleName = TEST_CLOUD_BUNDLE; + appInfo.appId = TEST_CLOUD_APPID; + appInfo.version = 1; + appInfo.cloudSwitch = true; + + cloudInfo_.apps[TEST_CLOUD_BUNDLE] = std::move(appInfo); +} + void CloudDataTest::SetUpTestCase(void) { MetaDataManager::GetInstance().Initialize(dbStoreMock_, nullptr); - MetaDataManager::GetInstance().SetSyncer([](const auto &, auto) { - DeviceMatrix::GetInstance().OnChanged(DeviceMatrix::META_STORE_MASK); - }); + MetaDataManager::GetInstance().SetSyncer( + [](const auto &, auto) { DeviceMatrix::GetInstance().OnChanged(DeviceMatrix::META_STORE_MASK); }); auto cloudServerMock = new CloudServerMock(); CloudServer::RegisterCloudInstance(cloudServerMock); - FeatureSystem::GetInstance().GetCreator("cloud")(); - FeatureSystem::GetInstance().GetCreator("relational_store")(); -} -void CloudDataTest::TearDownTestCase() {} + HapPolicyParams policy = { .apl = APL_SYSTEM_BASIC, + .domain = "test.domain", + .permList = { + { + .permissionName = "ohos.permission.CLOUDDATA_CONFIG", + .bundleName = "test_cloud_bundleName", + .grantMode = 1, + .availableLevel = APL_SYSTEM_BASIC, + .label = "label", + .labelId = 1, + .description = "test_cloud_bundleName", + .descriptionId = 1 + } + }, + .permStateList = { + { + .permissionName = "ohos.permission.CLOUDDATA_CONFIG", + .isGeneral = true, + .resDeviceID = { "local" }, + .grantStatus = { PermissionState::PERMISSION_GRANTED }, + .grantFlags = { 1 } + } + } + }; + g_selfTokenID = GetSelfTokenID(); + AllocHapToken(policy); -void CloudDataTest::SetUp() -{ + InitCloudInfo(); InitMetaData(); InitSchemaMeta(); - MetaDataManager::GetInstance().SaveMeta(metaData_.GetKey(), metaData_); + size_t max = 12; + size_t min = 5; + + auto executor = std::make_shared(max, min); + cloudServiceImpl_->OnBind( + { "CloudDataTest", static_cast(IPCSkeleton::GetSelfTokenID()), std::move(executor) }); + + Bootstrap::GetInstance().LoadCheckers(); +} + +void CloudDataTest::TearDownTestCase() +{ + SetSelfTokenID(g_selfTokenID); +} - StoreMetaData storeMetaData; - storeMetaData.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; - storeMetaData.bundleName = TEST_CLOUD_BUNDLE; - storeMetaData.storeId = TEST_CLOUD_STORE; - storeMetaData.instanceId = 0; - storeMetaData.isAutoSync = true; - storeMetaData.storeType = DistributedRdb::RDB_DEVICE_COLLABORATION; - storeMetaData.area = OHOS::DistributedKv::EL1; - storeMetaData.tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); - auto user = DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(storeMetaData.tokenId); - storeMetaData.user = std::to_string(user); - MetaDataManager::GetInstance().SaveMeta(storeMetaData.GetKey(), storeMetaData); +void CloudDataTest::SetUp() +{ + MetaDataManager::GetInstance().SaveMeta(cloudInfo_.GetKey(), cloudInfo_, true); + MetaDataManager::GetInstance().SaveMeta(metaData_.GetKey(), metaData_, true); + MetaDataManager::GetInstance().SaveMeta(cloudInfo_.GetSchemaKey(TEST_CLOUD_BUNDLE), schemaMeta_, true); } -void CloudDataTest::TearDown() {} +void CloudDataTest::TearDown() +{ + MetaDataManager::GetInstance().DelMeta(cloudInfo_.GetKey(), true); + MetaDataManager::GetInstance().DelMeta(metaData_.GetKey(), true); + MetaDataManager::GetInstance().DelMeta(cloudInfo_.GetSchemaKey(TEST_CLOUD_BUNDLE), true); +} /** * @tc.name: GetSchema @@ -184,16 +275,242 @@ HWTEST_F(CloudDataTest, GetSchema, TestSize.Level0) ZLOGI("CloudDataTest start"); auto cloudServerMock = std::make_shared(); auto user = DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(OHOS::IPCSkeleton::GetCallingTokenID()); - auto cloudInfo = cloudServerMock->GetServerInfo(user); + auto cloudInfo = cloudServerMock->GetServerInfo(user, true); ASSERT_TRUE(MetaDataManager::GetInstance().DelMeta(cloudInfo.GetSchemaKey(TEST_CLOUD_BUNDLE), true)); SchemaMeta schemaMeta; - ASSERT_FALSE( - MetaDataManager::GetInstance().LoadMeta(cloudInfo.GetSchemaKey(TEST_CLOUD_BUNDLE), schemaMeta, true)); - StoreInfo storeInfo { OHOS::IPCSkeleton::GetCallingTokenID(), TEST_CLOUD_BUNDLE, TEST_CLOUD_STORE, 0 }; + ASSERT_FALSE(MetaDataManager::GetInstance().LoadMeta(cloudInfo.GetSchemaKey(TEST_CLOUD_BUNDLE), schemaMeta, true)); + StoreInfo storeInfo{ OHOS::IPCSkeleton::GetCallingTokenID(), TEST_CLOUD_BUNDLE, TEST_CLOUD_STORE, 0 }; auto event = std::make_unique(CloudEvent::GET_SCHEMA, storeInfo); EventCenter::GetInstance().PostEvent(std::move(event)); - ASSERT_FALSE( - MetaDataManager::GetInstance().LoadMeta(cloudInfo.GetSchemaKey(TEST_CLOUD_BUNDLE), schemaMeta, true)); + ASSERT_FALSE(MetaDataManager::GetInstance().LoadMeta(cloudInfo.GetSchemaKey(TEST_CLOUD_BUNDLE), schemaMeta, true)); +} + +/** +* @tc.name: QueryStatistics +* @tc.desc: The query interface failed because cloudInfo could not be found from the metadata. +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(CloudDataTest, QueryStatistics001, TestSize.Level0) +{ + ZLOGI("CloudDataTest QueryStatistics001 start"); + // prepare MetaDta + MetaDataManager::GetInstance().DelMeta(cloudInfo_.GetKey(), true); + + auto [status, result] = cloudServiceImpl_->QueryStatistics(TEST_CLOUD_ID, TEST_CLOUD_BUNDLE, ""); + EXPECT_EQ(status, CloudData::CloudService::ERROR); + EXPECT_TRUE(result.empty()); +} + +/** +* @tc.name: QueryStatistics +* @tc.desc: The query interface failed because SchemaMeta could not be found from the metadata. +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(CloudDataTest, QueryStatistics002, TestSize.Level0) +{ + ZLOGI("CloudDataTest QueryStatistics002 start"); + // prepare MetaDta + MetaDataManager::GetInstance().DelMeta(cloudInfo_.GetSchemaKey(TEST_CLOUD_BUNDLE), true); + MetaDataManager::GetInstance().SaveMeta(cloudInfo_.GetKey(), cloudInfo_, true); + + auto [status, result] = cloudServiceImpl_->QueryStatistics("", "", ""); + EXPECT_EQ(status, CloudData::CloudService::ERROR); + EXPECT_TRUE(result.empty()); + std::tie(status, result) = cloudServiceImpl_->QueryStatistics(TEST_CLOUD_ID, "", ""); + EXPECT_EQ(status, CloudData::CloudService::ERROR); + EXPECT_TRUE(result.empty()); + std::tie(status, result) = cloudServiceImpl_->QueryStatistics(TEST_CLOUD_ID, TEST_CLOUD_STORE, ""); + EXPECT_EQ(status, CloudData::CloudService::ERROR); + EXPECT_TRUE(result.empty()); + std::tie(status, result) = cloudServiceImpl_->QueryStatistics(TEST_CLOUD_ID, TEST_CLOUD_BUNDLE, ""); + EXPECT_EQ(status, CloudData::CloudService::ERROR); + EXPECT_TRUE(result.empty()); +} + +/** +* @tc.name: QueryStatistics +* @tc.desc: Query the statistics of cloud records in a specified database. +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(CloudDataTest, QueryStatistics003, TestSize.Level0) +{ + ZLOGI("CloudDataTest QueryStatistics003 start"); + // Construct the statisticInfo data + auto creator = [](const StoreMetaData &metaData) -> GeneralStore * { + auto store = new (std::nothrow) GeneralStoreMock(); + if (store != nullptr) { + std::map entry = { { "inserted", 1 }, { "updated", 2 }, { "normal", 3 } }; + store->MakeCursor(entry); + } + return store; + }; + AutoCache::GetInstance().RegCreator(DistributedRdb::RDB_DEVICE_COLLABORATION, creator); + + auto [status, result] = + cloudServiceImpl_->QueryStatistics(TEST_CLOUD_ID, TEST_CLOUD_BUNDLE, TEST_CLOUD_DATABASE_ALIAS_1); + ASSERT_EQ(status, CloudData::CloudService::SUCCESS); + ASSERT_EQ(result.size(), 1); + for (const auto &it : result) { + ASSERT_EQ(it.first, TEST_CLOUD_DATABASE_ALIAS_1); + auto statisticInfos = it.second; + ASSERT_FALSE(statisticInfos.empty()); + for (const auto &info : statisticInfos) { + EXPECT_EQ(info.inserted, 1); + EXPECT_EQ(info.updated, 2); + EXPECT_EQ(info.normal, 3); + } + } +} + +/** +* @tc.name: QueryStatistics +* @tc.desc: Query the statistics of all local database cloud records. +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(CloudDataTest, QueryStatistics004, TestSize.Level0) +{ + ZLOGI("CloudDataTest QueryStatistics004 start"); + + // Construct the statisticInfo data + auto creator = [](const StoreMetaData &metaData) -> GeneralStore * { + auto store = new (std::nothrow) GeneralStoreMock(); + if (store != nullptr) { + std::map entry = { { "inserted", 1 }, { "updated", 2 }, { "normal", 3 } }; + store->MakeCursor(entry); + } + return store; + }; + AutoCache::GetInstance().RegCreator(DistributedRdb::RDB_DEVICE_COLLABORATION, creator); + + auto [status, result] = cloudServiceImpl_->QueryStatistics(TEST_CLOUD_ID, TEST_CLOUD_BUNDLE, ""); + ASSERT_EQ(status, CloudData::CloudService::SUCCESS); + ASSERT_EQ(result.size(), 2); + for (const auto &it : result) { + auto statisticInfos = it.second; + ASSERT_FALSE(statisticInfos.empty()); + for (const auto &info : statisticInfos) { + EXPECT_EQ(info.inserted, 1); + EXPECT_EQ(info.updated, 2); + EXPECT_EQ(info.normal, 3); + } + } +} + +/** +* @tc.name: QueryLastSyncInfo001 +* @tc.desc: The query last sync info interface failed because account is false. +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, QueryLastSyncInfo001, TestSize.Level0) +{ + ZLOGI("CloudDataTest QueryLastSyncInfo001 start"); + auto [status, result] = + cloudServiceImpl_->QueryLastSyncInfo("accountId", TEST_CLOUD_BUNDLE, TEST_CLOUD_DATABASE_ALIAS_1); + EXPECT_EQ(status, CloudData::CloudService::SUCCESS); + EXPECT_TRUE(result.empty()); +} + +/** +* @tc.name: QueryLastSyncInfo002 +* @tc.desc: The query last sync info interface failed because bundleName is false. +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, QueryLastSyncInfo002, TestSize.Level0) +{ + ZLOGI("CloudDataTest QueryLastSyncInfo002 start"); + auto [status, result] = + cloudServiceImpl_->QueryLastSyncInfo(TEST_CLOUD_ID, "bundleName", TEST_CLOUD_DATABASE_ALIAS_1); + EXPECT_EQ(status, CloudData::CloudService::Status::INVALID_ARGUMENT); + EXPECT_TRUE(result.empty()); +} + +/** +* @tc.name: QueryLastSyncInfo003 +* @tc.desc: The query last sync info interface failed because storeId is false. +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, QueryLastSyncInfo003, TestSize.Level0) +{ + ZLOGI("CloudDataTest QueryLastSyncInfo003 start"); + auto [status, result] = cloudServiceImpl_->QueryLastSyncInfo(TEST_CLOUD_ID, TEST_CLOUD_BUNDLE, "storeId"); + EXPECT_EQ(status, CloudData::CloudService::INVALID_ARGUMENT); + EXPECT_TRUE(result.empty()); +} + +/** +* @tc.name: QueryLastSyncInfo004 +* @tc.desc: The query last sync info interface failed when switch is close. +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, QueryLastSyncInfo004, TestSize.Level0) +{ + ZLOGI("CloudDataTest QueryLastSyncInfo004 start"); + auto ret = cloudServiceImpl_->DisableCloud(TEST_CLOUD_ID); + EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); + + auto rdbServiceImpl = std::make_shared(); + DistributedRdb::RdbSyncerParam param; + param.bundleName_ = TEST_CLOUD_BUNDLE; + param.storeName_ = TEST_CLOUD_DATABASE_ALIAS_1; + DistributedRdb::RdbService::Option option; + option.mode = DistributedRdb::SyncMode::CLOUD_FIRST; + option.isAutoSync = true; + option.isAsync = false; + DistributedRdb::PredicatesMemo memo; + rdbServiceImpl->Sync(param, option, memo, nullptr); + + sleep(1); + + auto [status, result] = + cloudServiceImpl_->QueryLastSyncInfo(TEST_CLOUD_ID, TEST_CLOUD_BUNDLE, TEST_CLOUD_DATABASE_ALIAS_1); + EXPECT_EQ(status, CloudData::CloudService::SUCCESS); + EXPECT_TRUE(!result.empty()); + EXPECT_TRUE(result[TEST_CLOUD_DATABASE_ALIAS_1].code = E_CLOUD_DISABLED); +} + +/** +* @tc.name: QueryLastSyncInfo005 +* @tc.desc: The query last sync info interface failed when app cloud switch is close. +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, QueryLastSyncInfo005, TestSize.Level0) +{ + ZLOGI("CloudDataTest QueryLastSyncInfo005 start"); + std::map switches; + switches.emplace(TEST_CLOUD_ID, true); + auto ret = cloudServiceImpl_->EnableCloud(TEST_CLOUD_ID, switches); + EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); + + ret = cloudServiceImpl_->ChangeAppSwitch(TEST_CLOUD_ID, TEST_CLOUD_BUNDLE, false); + EXPECT_EQ(ret, CloudData::CloudService::SUCCESS); + + auto rdbServiceImpl = std::make_shared(); + DistributedRdb::RdbSyncerParam param; + param.bundleName_ = TEST_CLOUD_BUNDLE; + param.storeName_ = TEST_CLOUD_DATABASE_ALIAS_1; + DistributedRdb::RdbService::Option option; + option.mode = DistributedRdb::SyncMode::CLOUD_FIRST; + option.isAutoSync = true; + option.isAsync = false; + DistributedRdb::PredicatesMemo memo; + rdbServiceImpl->Sync(param, option, memo, nullptr); + + sleep(1); + + auto [status, result] = + cloudServiceImpl_->QueryLastSyncInfo(TEST_CLOUD_ID, TEST_CLOUD_BUNDLE, TEST_CLOUD_DATABASE_ALIAS_1); + EXPECT_EQ(status, CloudData::CloudService::SUCCESS); + EXPECT_TRUE(!result.empty()); + EXPECT_TRUE(result[TEST_CLOUD_DATABASE_ALIAS_1].code = E_CLOUD_DISABLED); } } // namespace DistributedDataTest -} // namespace OHOS::Test +} // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/cloud_test.cpp b/datamgr_service/services/distributeddataservice/service/test/cloud_test.cpp index b1edd495..607179ab 100644 --- a/datamgr_service/services/distributeddataservice/service/test/cloud_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/cloud_test.cpp @@ -21,12 +21,15 @@ #include "cloud/sync_event.h" #include "gtest/gtest.h" #include "ipc_skeleton.h" +#include "metadata/meta_data_manager.h" +#include "mock/db_store_mock.h" using namespace testing::ext; using namespace OHOS::DistributedData; +using Database = SchemaMeta::Database; namespace OHOS::Test { class CloudTest : public testing::Test { public: - static void SetUpTestCase(void){}; + static void SetUpTestCase(void); static void TearDownTestCase(void){}; void SetUp(){}; void TearDown(){}; @@ -34,7 +37,14 @@ public: protected: static constexpr const char* testCloudBundle = "test_cloud_bundleName"; static constexpr const char* testCloudStore = "test_cloud_database_name"; + static std::shared_ptr dbStoreMock_; }; +std::shared_ptr CloudTest::dbStoreMock_ = std::make_shared(); + +void CloudTest::SetUpTestCase(void) +{ + MetaDataManager::GetInstance().Initialize(dbStoreMock_, nullptr); +} /** * @tc.name: EventInfo @@ -157,4 +167,25 @@ HWTEST_F(CloudTest, Database_Marshal, TestSize.Level1) EXPECT_EQ(tableNames1[i], tableNames2[i]); } } + +/** + * @tc.name: Load old cloudInfo + * @tc.desc: The obtained maxUploadBatchNumber and maxUploadBatchSize are not equal to 0 + * @tc.type: FUNC + * @tc.require: + * @tc.author: ht + */ +HWTEST_F(CloudTest, CloudInfoUpgrade, TestSize.Level0) +{ + CloudInfo oldInfo; + auto user = DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(OHOS::IPCSkeleton::GetCallingTokenID()); + oldInfo.user = user; + EXPECT_NE(oldInfo.maxNumber, CloudInfo::DEFAULT_BATCH_NUMBER); + EXPECT_NE(oldInfo.maxSize, CloudInfo::DEFAULT_BATCH_SIZE); + ASSERT_TRUE(MetaDataManager::GetInstance().SaveMeta(oldInfo.GetKey(), oldInfo, true)); + CloudInfo newInfo; + ASSERT_TRUE(MetaDataManager::GetInstance().LoadMeta(oldInfo.GetKey(), newInfo, true)); + EXPECT_EQ(newInfo.maxNumber, CloudInfo::DEFAULT_BATCH_NUMBER); + EXPECT_EQ(newInfo.maxSize, CloudInfo::DEFAULT_BATCH_SIZE); +} } // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/data_share_profile_config_test.cpp b/datamgr_service/services/distributeddataservice/service/test/data_share_profile_config_test.cpp index c474b4e1..3c2ec549 100644 --- a/datamgr_service/services/distributeddataservice/service/test/data_share_profile_config_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/data_share_profile_config_test.cpp @@ -21,6 +21,7 @@ #include "data_share_profile_config.h" #include "datashare_errno.h" #include "data_share_db_config.h" +#include "data_share_profile_config.h" #include "data_share_service_impl.h" #include "log_print.h" diff --git a/datamgr_service/services/distributeddataservice/service/test/data_share_service_stub_test.cpp b/datamgr_service/services/distributeddataservice/service/test/data_share_service_stub_test.cpp index 9126ddef..0adae040 100644 --- a/datamgr_service/services/distributeddataservice/service/test/data_share_service_stub_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/data_share_service_stub_test.cpp @@ -61,7 +61,7 @@ HWTEST_F(DataShareServiceStubTest, OnRemoteRequest001, TestSize.Level1) auto result = dataShareServiceStub->OnRemoteRequest(code, request, reply); EXPECT_NE(result, IDataShareService::DATA_SHARE_ERROR); - result = dataShareServiceStub->OnRemoteNotifyConnectDone(request, reply); + result = dataShareServiceStub->OnNotifyConnectDone(request, reply); EXPECT_EQ(result, IDataShareService::DATA_SHARE_OK); } @@ -81,17 +81,17 @@ HWTEST_F(DataShareServiceStubTest, OnRemoteRequest002, TestSize.Level1) auto result = dataShareServiceStub->OnRemoteRequest(code, request, reply); EXPECT_EQ(result, IDataShareService::DATA_SHARE_ERROR); - result = dataShareServiceStub->OnRemoteNotifyConnectDone(request, reply); + result = dataShareServiceStub->OnNotifyConnectDone(request, reply); EXPECT_EQ(result, IDataShareService::DATA_SHARE_OK); } /** -* @tc.name: OnRemoteInsert001 +* @tc.name: OnInsert001 * @tc.desc: test Insert Update Query Delete function of abnormal scene * @tc.type: FUNC * @tc.require:SQL */ -HWTEST_F(DataShareServiceStubTest, OnRemoteInsert001, TestSize.Level1) +HWTEST_F(DataShareServiceStubTest, OnInsert001, TestSize.Level1) { uint8_t value = TEST_DATA; uint8_t *data = &value; @@ -101,26 +101,26 @@ HWTEST_F(DataShareServiceStubTest, OnRemoteInsert001, TestSize.Level1) request.WriteBuffer(data, size); request.RewindRead(0); MessageParcel reply; - auto result = dataShareServiceStub->OnRemoteInsert(request, reply); + auto result = dataShareServiceStub->OnInsert(request, reply); EXPECT_EQ(result, IPC_STUB_INVALID_DATA_ERR); - result = dataShareServiceStub->OnRemoteUpdate(request, reply); + result = dataShareServiceStub->OnUpdate(request, reply); EXPECT_EQ(result, IPC_STUB_INVALID_DATA_ERR); - result = dataShareServiceStub->OnRemoteQuery(request, reply); + result = dataShareServiceStub->OnQuery(request, reply); EXPECT_EQ(result, IPC_STUB_INVALID_DATA_ERR); - result = dataShareServiceStub->OnRemoteDelete(request, reply); + result = dataShareServiceStub->OnDelete(request, reply); EXPECT_EQ(result, IPC_STUB_INVALID_DATA_ERR); } /** -* @tc.name: OnRemoteAddTemplate001 -* @tc.desc: test OnRemoteAddTemplate function abnormal scene +* @tc.name: OnAddTemplate001 +* @tc.desc: test OnAddTemplate function abnormal scene * @tc.type: FUNC * @tc.require:SQL */ -HWTEST_F(DataShareServiceStubTest, OnRemoteAddTemplate001, TestSize.Level1) +HWTEST_F(DataShareServiceStubTest, OnAddTemplate001, TestSize.Level1) { uint8_t value = TEST_DATA; uint8_t *data = &value; @@ -130,20 +130,20 @@ HWTEST_F(DataShareServiceStubTest, OnRemoteAddTemplate001, TestSize.Level1) request.WriteBuffer(data, size); request.RewindRead(0); MessageParcel reply; - auto result = dataShareServiceStub->OnRemoteAddTemplate(request, reply); + auto result = dataShareServiceStub->OnAddTemplate(request, reply); EXPECT_EQ(result, IDataShareService::DATA_SHARE_ERROR); - result = dataShareServiceStub->OnRemoteDelTemplate(request, reply); + result = dataShareServiceStub->OnDelTemplate(request, reply); EXPECT_EQ(result, IDataShareService::DATA_SHARE_ERROR); } /** -* @tc.name: OnRemoteEnablePubSubs001 -* @tc.desc: test OnRemoteEnablePubSubs function abnormal scene +* @tc.name: OnEnablePubSubs001 +* @tc.desc: test OnEnablePubSubs function abnormal scene * @tc.type: FUNC * @tc.require:SQL */ -HWTEST_F(DataShareServiceStubTest, OnRemoteEnablePubSubs001, TestSize.Level1) +HWTEST_F(DataShareServiceStubTest, OnEnablePubSubs001, TestSize.Level1) { uint8_t value = TEST_DATA; uint8_t *data = &value; @@ -153,32 +153,32 @@ HWTEST_F(DataShareServiceStubTest, OnRemoteEnablePubSubs001, TestSize.Level1) request.WriteBuffer(data, size); request.RewindRead(0); MessageParcel reply; - auto result = dataShareServiceStub->OnRemoteEnablePubSubs(request, reply); + auto result = dataShareServiceStub->OnEnablePubSubs(request, reply); EXPECT_EQ(result, IDataShareService::DATA_SHARE_ERROR); - result = dataShareServiceStub->OnRemotePublish(request, reply); + result = dataShareServiceStub->OnPublish(request, reply); EXPECT_EQ(result, IDataShareService::DATA_SHARE_ERROR); - result = dataShareServiceStub->OnRemoteGetData(request, reply); + result = dataShareServiceStub->OnGetData(request, reply); EXPECT_EQ(result, IDataShareService::DATA_SHARE_ERROR); - result = dataShareServiceStub->OnRemoteSubscribePublishedData(request, reply); + result = dataShareServiceStub->OnSubscribePublishedData(request, reply); EXPECT_EQ(result, IDataShareService::DATA_SHARE_ERROR); - result = dataShareServiceStub->OnRemoteUnsubscribePublishedData(request, reply); + result = dataShareServiceStub->OnUnsubscribePublishedData(request, reply); EXPECT_EQ(result, IDataShareService::DATA_SHARE_ERROR); - result = dataShareServiceStub->OnRemoteDisablePubSubs(request, reply); + result = dataShareServiceStub->OnDisablePubSubs(request, reply); EXPECT_EQ(result, IDataShareService::DATA_SHARE_ERROR); } /** -* @tc.name: OnRemoteEnableRdbSubs001 -* @tc.desc: test OnRemoteEnableRdbSubs function abnormal scene +* @tc.name: OnEnableRdbSubs001 +* @tc.desc: test OnEnableRdbSubs function abnormal scene * @tc.type: FUNC * @tc.require:SQL */ -HWTEST_F(DataShareServiceStubTest, OnRemoteEnableRdbSubs001, TestSize.Level1) +HWTEST_F(DataShareServiceStubTest, OnEnableRdbSubs001, TestSize.Level1) { uint8_t value = TEST_DATA; uint8_t *data = &value; @@ -188,32 +188,32 @@ HWTEST_F(DataShareServiceStubTest, OnRemoteEnableRdbSubs001, TestSize.Level1) request.WriteBuffer(data, size); request.RewindRead(0); MessageParcel reply; - auto result = dataShareServiceStub->OnRemoteEnablePubSubs(request, reply); + auto result = dataShareServiceStub->OnEnablePubSubs(request, reply); EXPECT_EQ(result, IDataShareService::DATA_SHARE_ERROR); - result = dataShareServiceStub->OnRemotePublish(request, reply); + result = dataShareServiceStub->OnPublish(request, reply); EXPECT_EQ(result, IDataShareService::DATA_SHARE_ERROR); - result = dataShareServiceStub->OnRemoteEnableRdbSubs(request, reply); + result = dataShareServiceStub->OnEnableRdbSubs(request, reply); EXPECT_EQ(result, IDataShareService::DATA_SHARE_ERROR); - result = dataShareServiceStub->OnRemoteSubscribeRdbData(request, reply); + result = dataShareServiceStub->OnSubscribeRdbData(request, reply); EXPECT_EQ(result, IDataShareService::DATA_SHARE_ERROR); - result = dataShareServiceStub->OnRemoteUnsubscribeRdbData(request, reply); + result = dataShareServiceStub->OnUnsubscribeRdbData(request, reply); EXPECT_EQ(result, IDataShareService::DATA_SHARE_ERROR); - result = dataShareServiceStub->OnRemoteDisableRdbSubs(request, reply); + result = dataShareServiceStub->OnDisableRdbSubs(request, reply); EXPECT_EQ(result, IDataShareService::DATA_SHARE_ERROR); } /** -* @tc.name: OnRemoteRegisterObserver001 -* @tc.desc: test OnRemoteRegisterObserver function abnormal scene +* @tc.name: OnRegisterObserver001 +* @tc.desc: test OnRegisterObserver function abnormal scene * @tc.type: FUNC * @tc.require:SQL */ -HWTEST_F(DataShareServiceStubTest, OnRemoteRegisterObserver001, TestSize.Level1) +HWTEST_F(DataShareServiceStubTest, OnRegisterObserver001, TestSize.Level1) { uint8_t value = TEST_DATA; uint8_t *data = &value; @@ -223,19 +223,19 @@ HWTEST_F(DataShareServiceStubTest, OnRemoteRegisterObserver001, TestSize.Level1) request.WriteBuffer(data, size); request.RewindRead(0); MessageParcel reply; - auto result = dataShareServiceStub->OnRemoteRegisterObserver(request, reply); + auto result = dataShareServiceStub->OnRegisterObserver(request, reply); EXPECT_EQ(result, IPC_STUB_INVALID_DATA_ERR); - result = dataShareServiceStub->OnRemoteNotifyObserver(request, reply); + result = dataShareServiceStub->OnNotifyObserver(request, reply); EXPECT_EQ(result, IDataShareService::DATA_SHARE_ERROR); - result = dataShareServiceStub->OnRemoteSetSilentSwitch(request, reply); + result = dataShareServiceStub->OnSetSilentSwitch(request, reply); EXPECT_EQ(result, IPC_STUB_INVALID_DATA_ERR); - result = dataShareServiceStub->OnRemoteIsSilentProxyEnable(request, reply); + result = dataShareServiceStub->OnGetSilentProxyStatus(request, reply); EXPECT_EQ(result, IPC_STUB_INVALID_DATA_ERR); - result = dataShareServiceStub->OnRemoteUnregisterObserver(request, reply); + result = dataShareServiceStub->OnUnregisterObserver(request, reply); EXPECT_EQ(result, IPC_STUB_INVALID_DATA_ERR); } } // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/data_share_subscriber_managers_test.cpp b/datamgr_service/services/distributeddataservice/service/test/data_share_subscriber_managers_test.cpp index 4b93c424..bd34b243 100644 --- a/datamgr_service/services/distributeddataservice/service/test/data_share_subscriber_managers_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/data_share_subscriber_managers_test.cpp @@ -15,7 +15,6 @@ #define LOG_TAG "DataShareSubscriberManagersTest" #include -#include #define private public #include "accesstoken_kit.h" diff --git a/datamgr_service/services/distributeddataservice/service/test/device_matrix_test.cpp b/datamgr_service/services/distributeddataservice/service/test/device_matrix_test.cpp index d9894cc7..975e45f0 100644 --- a/datamgr_service/services/distributeddataservice/service/test/device_matrix_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/device_matrix_test.cpp @@ -15,6 +15,8 @@ #include "device_matrix.h" #include "block_data.h" +#include "bootstrap.h" +#include "checker/checker_manager.h" #include "device_manager_adapter.h" #include "eventcenter/event_center.h" #include "feature/feature_system.h" @@ -23,6 +25,7 @@ #include "matrix_event.h" #include "metadata/meta_data_manager.h" #include "metadata/store_meta_data_local.h" +#include "mock/checker_mock.h" #include "mock/db_store_mock.h" #include "types.h" using namespace testing::ext; @@ -41,7 +44,7 @@ protected: struct Result { uint16_t mask_ = DeviceMatrix::INVALID_LEVEL; std::string deviceId_; - Result() {}; + Result(){}; }; static constexpr const char *TEST_DEVICE = "14a0a92a428005db27c40bad46bf145fede38ec37effe0347cd990fcb031f320"; static constexpr const char *TEST_BUNDLE = "matrix_test"; @@ -50,23 +53,41 @@ protected: void InitRemoteMatrixMeta(); void InitMetaData(); + static inline std::vector> staticStores_ = { { "bundle0", "store0" }, + { "bundle1", "store0" } }; + static inline std::vector> dynamicStores_ = { + { "distributeddata", "service_meta" }, { "bundle0", "store1" }, { "bundle3", "store0" } }; static BlockData isFinished_; static std::shared_ptr dbStoreMock_; static uint32_t selfToken_; StoreMetaData metaData_; StoreMetaDataLocal localMeta_; + static CheckerMock instance_; + static constexpr uint32_t CURRENT_VERSION = 3; }; BlockData DeviceMatrixTest::isFinished_(1, Result()); std::shared_ptr DeviceMatrixTest::dbStoreMock_ = std::make_shared(); uint32_t DeviceMatrixTest::selfToken_ = 0; +CheckerMock DeviceMatrixTest::instance_; void DeviceMatrixTest::SetUpTestCase(void) { MetaDataManager::GetInstance().Initialize(dbStoreMock_, nullptr); - MetaDataManager::GetInstance().SetSyncer([](const auto &, auto) { + MetaDataManager::GetInstance().SetCloudSyncer([]() { DeviceMatrix::GetInstance().OnChanged(DeviceMatrix::META_STORE_MASK); }); selfToken_ = IPCSkeleton::GetCallingTokenID(); FeatureSystem::GetInstance().GetCreator("kv_store")(); + std::vector dynamicStores; + for (auto &[bundle, store] : dynamicStores_) { + dynamicStores.push_back({ 0, 0, bundle, store }); + instance_.SetDynamic(dynamicStores); + } + std::vector staticStores; + for (auto &[bundle, store] : staticStores_) { + staticStores.push_back({ 0, 0, bundle, store }); + instance_.SetStatic(staticStores); + } + Bootstrap::GetInstance().LoadCheckers(); DeviceMatrix::GetInstance().Initialize(selfToken_, "service_meta"); EventCenter::GetInstance().Subscribe(DeviceMatrix::MATRIX_ONLINE, [](const Event &event) { auto &evt = static_cast(event); @@ -120,12 +141,14 @@ void DeviceMatrixTest::TearDown() void DeviceMatrixTest::InitRemoteMatrixMeta() { MatrixMetaData metaData; - metaData.version = 1; - metaData.dynamic = 0xF; + metaData.version = CURRENT_VERSION; + metaData.dynamic = 0x7; metaData.deviceId = TEST_DEVICE; metaData.origin = MatrixMetaData::Origin::REMOTE_RECEIVED; - metaData.dynamicInfo = { "distributed_device_profile_service", "bundle_manager_service", - "dtbhardware_manager_service" }; + metaData.dynamicInfo.clear(); + for (auto &[bundleName, _] : dynamicStores_) { + metaData.dynamicInfo.push_back(bundleName); + } MetaDataManager::GetInstance().DelMeta(metaData.GetKey()); MetaDataManager::GetInstance().SaveMeta(metaData.GetKey(), metaData); } @@ -160,7 +183,7 @@ HWTEST_F(DeviceMatrixTest, FirstOnline, TestSize.Level0) DeviceMatrix::GetInstance().Online(TEST_DEVICE); auto result = isFinished_.GetValue(); ASSERT_EQ(result.deviceId_, std::string(TEST_DEVICE)); - ASSERT_EQ(result.mask_, 0xF); + ASSERT_EQ(result.mask_, 0x7); } /** @@ -175,13 +198,13 @@ HWTEST_F(DeviceMatrixTest, OnlineAgainNoData, TestSize.Level0) DeviceMatrix::GetInstance().Online(TEST_DEVICE); auto result = isFinished_.GetValue(); ASSERT_EQ(result.deviceId_, std::string(TEST_DEVICE)); - ASSERT_EQ(result.mask_, 0xF); + ASSERT_EQ(result.mask_, 0x7); isFinished_.Clear(Result()); DeviceMatrix::GetInstance().Offline(TEST_DEVICE); DeviceMatrix::GetInstance().Online(TEST_DEVICE); result = isFinished_.GetValue(); ASSERT_EQ(result.deviceId_, std::string(TEST_DEVICE)); - ASSERT_EQ(result.mask_, 0xE); + ASSERT_EQ(result.mask_, 0x6); } /** @@ -196,14 +219,14 @@ HWTEST_F(DeviceMatrixTest, OnlineAgainWithData, TestSize.Level0) DeviceMatrix::GetInstance().Online(TEST_DEVICE); auto result = isFinished_.GetValue(); ASSERT_EQ(result.deviceId_, std::string(TEST_DEVICE)); - ASSERT_EQ(result.mask_, 0xF); + ASSERT_EQ(result.mask_, 0x7); isFinished_.Clear(Result()); DeviceMatrix::GetInstance().Offline(TEST_DEVICE); MetaDataManager::GetInstance().SaveMeta(metaData_.GetKey(), metaData_); DeviceMatrix::GetInstance().Online(TEST_DEVICE); result = isFinished_.GetValue(); ASSERT_EQ(result.deviceId_, std::string(TEST_DEVICE)); - ASSERT_EQ(result.mask_, 0xF); + ASSERT_EQ(result.mask_, 0x7); } /** @@ -218,14 +241,14 @@ HWTEST_F(DeviceMatrixTest, OnlineAgainWithLocal, TestSize.Level0) DeviceMatrix::GetInstance().Online(TEST_DEVICE); auto result = isFinished_.GetValue(); ASSERT_EQ(result.deviceId_, std::string(TEST_DEVICE)); - ASSERT_EQ(result.mask_, 0xF); + ASSERT_EQ(result.mask_, 0x7); isFinished_.Clear(Result()); DeviceMatrix::GetInstance().Offline(TEST_DEVICE); MetaDataManager::GetInstance().SaveMeta(metaData_.GetKeyLocal(), localMeta_, true); DeviceMatrix::GetInstance().Online(TEST_DEVICE); result = isFinished_.GetValue(); ASSERT_EQ(result.deviceId_, std::string(TEST_DEVICE)); - ASSERT_EQ(result.mask_, 0xE); + ASSERT_EQ(result.mask_, 0x6); } /** @@ -247,19 +270,21 @@ HWTEST_F(DeviceMatrixTest, GetMetaStoreCode, TestSize.Level0) } /** -* @tc.name: GetDPCode -* @tc.desc: get the device profile store mask code; +* @tc.name: GetAllCode +* @tc.desc: get all dynamic store mask code; * @tc.type: FUNC * @tc.require: * @tc.author: blue sky */ -HWTEST_F(DeviceMatrixTest, GetDPCode, TestSize.Level0) +HWTEST_F(DeviceMatrixTest, GetAllCode, TestSize.Level0) { StoreMetaData meta = metaData_; - meta.appId = "distributed_device_profile_service"; - meta.bundleName = "distributed_device_profile_service"; - auto code = DeviceMatrix::GetInstance().GetCode(meta); - ASSERT_EQ(code, 0x2); + + for (size_t i = 0; i < dynamicStores_.size(); ++i) { + meta.appId = dynamicStores_[i].first; + meta.bundleName = dynamicStores_[i].first; + ASSERT_EQ(DeviceMatrix::GetInstance().GetCode(meta), 0x1 << i); + } } /** @@ -293,23 +318,24 @@ HWTEST_F(DeviceMatrixTest, BroadcastMeta, TestSize.Level0) } /** -* @tc.name: BroadcastDP -* @tc.desc: broadcast the device profile store change; +* @tc.name: BroadcastFirst +* @tc.desc: broadcast all stores change; * @tc.type: FUNC * @tc.require: * @tc.author: blue sky */ -HWTEST_F(DeviceMatrixTest, BroadcastDP, TestSize.Level0) +HWTEST_F(DeviceMatrixTest, BroadcastFirst, TestSize.Level0) { StoreMetaData meta = metaData_; - meta.appId = "distributed_device_profile_service"; - meta.bundleName = "distributed_device_profile_service"; + meta.appId = dynamicStores_[1].first; + meta.bundleName = dynamicStores_[1].first; auto code = DeviceMatrix::GetInstance().GetCode(meta); + ASSERT_EQ(code, 0x2); DeviceMatrix::DataLevel level = { .dynamic = code, }; auto mask = DeviceMatrix::GetInstance().OnBroadcast(TEST_DEVICE, level); - ASSERT_EQ(mask.first, 0x2); + ASSERT_EQ(mask.first, code); } /** @@ -345,18 +371,17 @@ HWTEST_F(DeviceMatrixTest, BroadcastAll, TestSize.Level0) auto mask = DeviceMatrix::GetInstance().OnBroadcast(TEST_DEVICE, level); ASSERT_EQ(mask.first, DeviceMatrix::META_STORE_MASK); StoreMetaData meta = metaData_; - meta.appId = "distributed_device_profile_service"; - meta.bundleName = "distributed_device_profile_service"; - auto code = DeviceMatrix::GetInstance().GetCode(meta); - level.dynamic = code; - mask = DeviceMatrix::GetInstance().OnBroadcast(TEST_DEVICE, level); - ASSERT_EQ(mask.first, 0x3); + for (size_t i = 1; i < dynamicStores_.size(); ++i) { + meta.appId = dynamicStores_[i].first; + meta.bundleName = dynamicStores_[i].first; + auto code = DeviceMatrix::GetInstance().GetCode(meta); + level.dynamic = code; + mask = DeviceMatrix::GetInstance().OnBroadcast(TEST_DEVICE, level); + ASSERT_EQ(mask.first, (0x1 << i) + 1); + DeviceMatrix::GetInstance().OnExchanged(TEST_DEVICE, code); + } DeviceMatrix::GetInstance().OnExchanged(TEST_DEVICE, DeviceMatrix::META_STORE_MASK); - DeviceMatrix::GetInstance().OnExchanged(TEST_DEVICE, 0x2); - - meta = metaData_; - code = DeviceMatrix::GetInstance().GetCode(meta); - level.dynamic = code; + level.dynamic = DeviceMatrix::GetInstance().GetCode(metaData_); mask = DeviceMatrix::GetInstance().OnBroadcast(TEST_DEVICE, level); ASSERT_EQ(mask.first, 0); @@ -380,7 +405,7 @@ HWTEST_F(DeviceMatrixTest, UpdateMatrixMeta, TestSize.Level0) metaData.dynamic = 0x1F; metaData.deviceId = TEST_DEVICE; metaData.origin = MatrixMetaData::Origin::REMOTE_RECEIVED; - metaData.dynamicInfo = { TEST_BUNDLE, "distributed_device_profile_service" }; + metaData.dynamicInfo = { TEST_BUNDLE, dynamicStores_[1].first }; MetaDataManager::GetInstance().Subscribe(MatrixMetaData::GetPrefix({ TEST_DEVICE }), [](const std::string &, const std::string &value, int32_t flag) { if (flag != MetaDataManager::INSERT && flag != MetaDataManager::UPDATE) { diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/BUILD.gn b/datamgr_service/services/distributeddataservice/service/test/fuzztest/BUILD.gn index 59ad2cd8..5a9c8229 100644 --- a/datamgr_service/services/distributeddataservice/service/test/fuzztest/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/BUILD.gn @@ -20,7 +20,9 @@ group("fuzztest") { deps = [ "cloudservicestub_fuzzer:fuzztest", + "customutdinstaller_fuzzer:fuzztest", "datashareservicestub_fuzzer:fuzztest", + "dumphelper_fuzzer:fuzztest", "kvdbservicestub_fuzzer:fuzztest", "objectservicestub_fuzzer:fuzztest", "rdbresultsetstub_fuzzer:fuzztest", 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 38071fb3..2007179c 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 @@ -73,6 +73,7 @@ ohos_fuzztest("CloudServiceStubFuzzTest") { "${data_service_path}/service/cloud/sync_strategies/network_sync_strategy.cpp", "${data_service_path}/service/common/common_types_utils.cpp", "${data_service_path}/service/common/value_proxy.cpp", + "${data_service_path}/service/common/xcollie.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", @@ -104,6 +105,7 @@ ohos_fuzztest("CloudServiceStubFuzzTest") { "${data_service_path}/adapter:distributeddata_adapter", "${data_service_path}/adapter/utils:distributeddata_utils_static", "${data_service_path}/framework:distributeddatasvcfwk", + "${data_service_path}/service:distributeddatasvc", "${kv_store_distributeddb_path}:distributeddb", ] @@ -118,6 +120,7 @@ ohos_fuzztest("CloudServiceStubFuzzTest") { "c_utils:utils", "device_auth:deviceauth_sdk", "device_manager:devicemanagersdk", + "hicollie:libhicollie", "hilog:libhilog", "huks:libhukssdk", "ipc:ipc_core", diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/BUILD.gn b/datamgr_service/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/BUILD.gn new file mode 100644 index 00000000..485c816f --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/BUILD.gn @@ -0,0 +1,111 @@ +# Copyright (c) 2024 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +##############################hydra-fuzz######################################## +import("//build/config/features.gni") +import("//build/test.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") + +##############################fuzztest########################################## +ohos_fuzztest("CustomUtdInstallerFuzzTest") { + module_out_path = "datamgr_service/datamgr_service" + + include_dirs = [ + "${data_service_path}/service/udmf/utd", + "${udmf_path}/framework/common", + "${udmf_path}/interfaces/innerkits/common", + "${udmf_path}/interfaces/innerkits/data", + "${data_service_path}/framework/include", + "${data_service_path}/service/udmf/lifecycle", + "${data_service_path}/service/udmf/permission", + "${data_service_path}/service/udmf/preprocess", + "${data_service_path}/service/udmf/store", + "${data_service_path}/service/udmf", + "${kv_store_path}/frameworks/common", + "${kv_store_common_path}", + "${kv_store_path}/frameworks/innerkitsimpl/distributeddatafwk/include", + "${kv_store_path}/frameworks/innerkitsimpl/distributeddatasvc/include", + "${kv_store_path}/frameworks/innerkitsimpl/kvdb/include", + "${kv_store_distributeddb_path}", + "${kv_store_distributeddb_path}/include/", + "${kv_store_distributeddb_path}/interfaces/include/", + "${kv_store_distributeddb_path}/interfaces/include/relational", + "${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", + "${data_service_path}/framework/include", + "${data_service_path}/adapter/include/communicator", + "${data_service_path}/adapter/include/dfx", + "${data_service_path}/service/bootstrap/include", + "${device_manager_path}/interfaces/inner_kits/native_cpp/include", + "${file_service_path}/interfaces/innerkits/native/remote_file_share/include", + "${kv_store_path}/interfaces/innerkits/distributeddata/include", + "${kv_store_path}/framework/libs/distributeddb/interfaces/include", + "${kv_store_common_path}", + "${udmf_path}/framework/common", + "${udmf_path}/interfaces/innerkits/common", + "${udmf_path}/interfaces/innerkits/data", + ] + + fuzz_config_file = + "${data_service_path}/service/test/fuzztest/customutdinstaller_fuzzer" + + cflags = [ + "-g", + "-O0", + "-Wno-unused-variable", + "-fno-omit-frame-pointer", + ] + + sources = [ + "${data_service_path}/service/udmf/utd/custom_utd_installer.cpp", + "customutdinstaller_fuzzer.cpp", + ] + + deps = [ + "${data_service_path}/adapter:distributeddata_adapter", + "${data_service_path}/adapter/utils:distributeddata_utils_static", + "${data_service_path}/framework:distributeddatasvcfwk", + "${data_service_path}/service:distributeddatasvc", + "${data_service_path}/service/udmf:udmf_server", + "${kv_store_distributeddb_path}:distributeddb", + ] + + external_deps = [ + "ability_base:zuri", + "ability_runtime:uri_permission_mgr", + "access_token:libaccesstoken_sdk", + "app_file_service:remote_file_share_native", + "bundle_framework:appexecfwk_base", + "bundle_framework:appexecfwk_core", + "c_utils:utils", + "hilog:libhilog", + "image_framework:image", + "ipc:ipc_core", + "kv_store:distributeddata_inner", + "kv_store:distributeddata_mgr", + "kv_store:distributeddb", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", + "udmf:udmf_client", + ] +} + +############################################################################### +group("fuzztest") { + testonly = true + + deps = [ ":CustomUtdInstallerFuzzTest" ] +} +############################################################################### diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/corpus/init b/datamgr_service/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/corpus/init new file mode 100644 index 00000000..6198079a --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/corpus/init @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +FUZZ \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/customutdinstaller_fuzzer.cpp b/datamgr_service/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/customutdinstaller_fuzzer.cpp new file mode 100644 index 00000000..36670b42 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/customutdinstaller_fuzzer.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "customutdinstaller_fuzzer.h" +#include +#include + +#include "ipc_skeleton.h" +#include "custom_utd_installer.h" +#include "message_parcel.h" +#include "securec.h" + +using namespace OHOS::UDMF; + +namespace OHOS { + +bool InstallUtdFuzz(const uint8_t* data, size_t size) +{ + int32_t user = static_cast(*data); + std::string bundleName(reinterpret_cast(data), size); + CustomUtdInstaller::GetInstance().InstallUtd(bundleName, user); + return true; +} + +bool UninstallUtdFuzz(const uint8_t* data, size_t size) +{ + int32_t user = static_cast(*data); + std::string bundleName(reinterpret_cast(data), size); + CustomUtdInstaller::GetInstance().UninstallUtd(bundleName, user); + return true; +} +} + +/* Fuzzer entry point */ +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) +{ + if (data == nullptr) { + return 0; + } + + OHOS::InstallUtdFuzz(data, size); + OHOS::UninstallUtdFuzz(data, size); + + return 0; +} \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/customutdinstaller_fuzzer.h b/datamgr_service/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/customutdinstaller_fuzzer.h new file mode 100644 index 00000000..da098deb --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/customutdinstaller_fuzzer.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CUSTOM_UTD_INSTALLER_FUZZER_H +#define CUSTOM_UTD_INSTALLER_FUZZER_H + +#define FUZZ_PROJECT_NAME "customutdinstaller_fuzzer" + +#endif // CUSTOM_UTD_INSTALLER_FUZZER_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/project.xml b/datamgr_service/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/project.xml new file mode 100644 index 00000000..e3791389 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/customutdinstaller_fuzzer/project.xml @@ -0,0 +1,25 @@ + + + + + + 1000 + + 300 + + 4096 + + \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/BUILD.gn b/datamgr_service/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/BUILD.gn index 8c06ea33..310150e2 100644 --- a/datamgr_service/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/datashareservicestub_fuzzer/BUILD.gn @@ -23,6 +23,7 @@ ohos_fuzztest("DataShareServiceStubFuzzTest") { "${data_service_path}/adapter/include", "${data_service_path}/app/src", "${data_service_path}/framework/include", + "${data_service_path}/service/common", "${data_service_path}/service/crypto/include", "${data_service_path}/service/data_share/common", "${data_service_path}/service/data_share/data", @@ -48,6 +49,7 @@ ohos_fuzztest("DataShareServiceStubFuzzTest") { ] sources = [ + "${data_service_path}/service/common/xcollie.cpp", "${data_service_path}/service/crypto/src/crypto_manager.cpp", "${data_service_path}/service/data_share/common/app_connect_manager.cpp", "${data_service_path}/service/data_share/common/base64_utils.cpp", @@ -89,6 +91,7 @@ ohos_fuzztest("DataShareServiceStubFuzzTest") { "${data_service_path}/service/data_share/strategies/template_strategy.cpp", "${data_service_path}/service/data_share/subscriber_managers/published_data_subscriber_manager.cpp", "${data_service_path}/service/data_share/subscriber_managers/rdb_subscriber_manager.cpp", + "${data_service_path}/service/data_share/sys_event_subscriber.cpp", "${data_service_path}/service/kvdb/user_delegate.cpp", "${data_service_path}/service/permission/src/permit_delegate.cpp", "datashareservicestub_fuzzer.cpp", @@ -114,7 +117,9 @@ ohos_fuzztest("DataShareServiceStubFuzzTest") { "common_event_service:cesfwk_innerkits", "data_share:datashare_common", "device_manager:devicemanagersdk", + "hicollie:libhicollie", "hilog:libhilog", + "hisysevent:libhisysevent", "huks:libhukssdk", "ipc:ipc_core", "kv_store:distributeddb", diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/dumphelper_fuzzer/BUILD.gn b/datamgr_service/services/distributeddataservice/service/test/fuzztest/dumphelper_fuzzer/BUILD.gn new file mode 100644 index 00000000..0416b718 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/dumphelper_fuzzer/BUILD.gn @@ -0,0 +1,87 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +##############################hydra-fuzz######################################## +import("//build/config/features.gni") +import("//build/test.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") + +##############################fuzztest########################################## +ohos_fuzztest("DumpHelperFuzzTest") { + module_out_path = "datamgr_service/datamgr_service" + + include_dirs = [ + "${data_service_path}/service/dumper/include", + "${kv_store_common_path}", + "${kv_store_path}/frameworks/innerkitsimpl/distributeddatafwk/include", + "${kv_store_path}/frameworks/innerkitsimpl/distributeddatasvc/include", + "${kv_store_path}/frameworks/innerkitsimpl/kvdb/include", + "${kv_store_distributeddb_path}", + "${kv_store_distributeddb_path}/include/", + "${kv_store_distributeddb_path}/interfaces/include/", + "${kv_store_distributeddb_path}/interfaces/include/relational", + "${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", + ] + + fuzz_config_file = + "${data_service_path}/service/test/fuzztest/dumphelper_fuzzer" + + cflags = [ + "-g", + "-O0", + "-Wno-unused-variable", + "-fno-omit-frame-pointer", + ] + + sources = [ + "${data_service_path}/service/dumper/src/dump_helper.cpp", + "dumphelper_fuzzer.cpp", + ] + + deps = [ + "${data_service_path}/adapter:distributeddata_adapter", + "${data_service_path}/adapter/utils:distributeddata_utils_static", + "${data_service_path}/framework:distributeddatasvcfwk", + "${kv_store_distributeddb_path}:distributeddb", + ] + + external_deps = [ + "ability_base:want", + "ability_base:zuri", + "ability_runtime:ability_manager", + "ability_runtime:dataobs_manager", + "access_token:libaccesstoken_sdk", + "access_token:libtoken_setproc", + "access_token:libtokenid_sdk", + "c_utils:utils", + "device_auth:deviceauth_sdk", + "device_manager:devicemanagersdk", + "hilog:libhilog", + "huks:libhukssdk", + "ipc:ipc_core", + "kv_store:distributeddata_inner", + "kv_store:distributeddata_mgr", + "relational_store:native_rdb", + ] +} + +############################################################################### +group("fuzztest") { + testonly = true + + deps = [ ":DumpHelperFuzzTest" ] +} +############################################################################### diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/dumphelper_fuzzer/corpus/init b/datamgr_service/services/distributeddataservice/service/test/fuzztest/dumphelper_fuzzer/corpus/init new file mode 100644 index 00000000..6198079a --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/dumphelper_fuzzer/corpus/init @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +FUZZ \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/dumphelper_fuzzer/dumphelper_fuzzer.cpp b/datamgr_service/services/distributeddataservice/service/test/fuzztest/dumphelper_fuzzer/dumphelper_fuzzer.cpp new file mode 100644 index 00000000..b8ff95c4 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/dumphelper_fuzzer/dumphelper_fuzzer.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "dumphelper_fuzzer.h" + +#include +#include + +#include "accesstoken_kit.h" +#include "dump_helper.h" +#include "ipc_skeleton.h" +#include "message_parcel.h" +#include "securec.h" +#include "token_setproc.h" +#include +using namespace OHOS::DistributedData; +using namespace OHOS::Security::AccessToken; + +namespace OHOS { + +bool DumpFuzz(const uint8_t *data, size_t size) +{ + int connId = static_cast(*data); + std::vector args; + const std::string argstest1 = "OHOS.DistributedData.DumpHelper1"; + const std::string argstest2 = "OHOS.DistributedData.DumpHelper2"; + args.emplace_back(argstest1); + args.emplace_back(argstest2); + DumpHelper::GetInstance().Dump(connId, args); + + return true; +} +} // namespace OHOS + +/* Fuzzer entry point */ +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + if (data == nullptr) { + return 0; + } + + OHOS::DumpFuzz(data, size); + + return 0; +} \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/dumphelper_fuzzer/dumphelper_fuzzer.h b/datamgr_service/services/distributeddataservice/service/test/fuzztest/dumphelper_fuzzer/dumphelper_fuzzer.h new file mode 100644 index 00000000..6f48e234 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/dumphelper_fuzzer/dumphelper_fuzzer.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DATAMGR_SERVICE_DUMP_HELPER_FUZZER_H +#define DATAMGR_SERVICE_DUMP_HELPER_FUZZER_H + +#define FUZZ_PROJECT_NAME "dumphelper_fuzzer" + +#endif // DATAMGR_SERVICE_DUMP_HELPER_FUZZER_H \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/fuzztest/dumphelper_fuzzer/project.xml b/datamgr_service/services/distributeddataservice/service/test/fuzztest/dumphelper_fuzzer/project.xml new file mode 100644 index 00000000..3fdba3e8 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/fuzztest/dumphelper_fuzzer/project.xml @@ -0,0 +1,25 @@ + + + + + + 1000 + + 300 + + 4096 + + \ No newline at end of file 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 bc17e0a7..7e0a8249 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 @@ -112,6 +112,7 @@ ohos_fuzztest("KvdbServiceStubFuzzTest") { "device_auth:deviceauth_sdk", "device_manager:devicemanagersdk", "hilog:libhilog", + "hisysevent:libhisysevent", "huks:libhukssdk", "ipc:ipc_core", "kv_store:distributeddata_inner", 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 7f35440a..9f310308 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 @@ -29,6 +29,7 @@ ohos_fuzztest("ObjectServiceStubFuzzTest") { "${data_service_path}/service/config/include", "${data_service_path}/service/crypto/include", "${data_service_path}/service/object", + "${data_service_path}/service/matrix/include", "${data_service_path}/service/waterversion", "${kv_store_common_path}", "${kv_store_path}/frameworks/innerkitsimpl/distributeddatafwk/include", @@ -39,6 +40,7 @@ ohos_fuzztest("ObjectServiceStubFuzzTest") { "${kv_store_distributeddb_path}/interfaces/include/", "${kv_store_distributeddb_path}/interfaces/include/relational", "${dataobject_path}/frameworks/innerkitsimpl/include", + "${dataobject_path}/frameworks/innerkitsimpl/include/common", "${dataobject_path}/interfaces/innerkits", "//third_party/json/single_include", "${relational_store_path}/interfaces/inner_api/common_type/include", @@ -86,6 +88,7 @@ ohos_fuzztest("ObjectServiceStubFuzzTest") { "${data_service_path}/adapter:distributeddata_adapter", "${data_service_path}/adapter/utils:distributeddata_utils_static", "${data_service_path}/framework:distributeddatasvcfwk", + "${data_service_path}/service:distributeddatasvc", "${kv_store_distributeddb_path}:distributeddb", ] @@ -100,7 +103,9 @@ ohos_fuzztest("ObjectServiceStubFuzzTest") { "device_auth:deviceauth_sdk", "device_manager:devicemanagersdk", "dfs_service:cloudsync_asset_kit_inner", + "dfs_service:distributed_file_daemon_kit_inner", "hilog:libhilog", + "hisysevent:libhisysevent", "huks:libhukssdk", "ipc:ipc_core", "kv_store:distributeddata_inner", 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 38684010..f45834ee 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 @@ -67,6 +67,7 @@ ohos_fuzztest("RdbServiceStubFuzzTest") { "${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/common/xcollie.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", @@ -98,6 +99,7 @@ ohos_fuzztest("RdbServiceStubFuzzTest") { "${data_service_path}/adapter:distributeddata_adapter", "${data_service_path}/adapter/utils:distributeddata_utils_static", "${data_service_path}/framework:distributeddatasvcfwk", + "${data_service_path}/service:distributeddatasvc", "${kv_store_distributeddb_path}:distributeddb", "${relational_store_inner_api_path}:native_rdb_static", ] @@ -112,6 +114,7 @@ ohos_fuzztest("RdbServiceStubFuzzTest") { "c_utils:utils", "device_auth:deviceauth_sdk", "device_manager:devicemanagersdk", + "hicollie:libhicollie", "hilog:libhilog", "huks:libhukssdk", "ipc:ipc_core", diff --git a/datamgr_service/services/distributeddataservice/service/test/kvdb_service_impl_test.cpp b/datamgr_service/services/distributeddataservice/service/test/kvdb_service_impl_test.cpp index 1911dc01..6360e4cd 100644 --- a/datamgr_service/services/distributeddataservice/service/test/kvdb_service_impl_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/kvdb_service_impl_test.cpp @@ -535,7 +535,7 @@ HWTEST_F(KvdbServiceImplTest, OnReadyTest001, TestSize.Level0) std::string device = "OH_device_test"; auto status = kvdbServiceImpl_->OnReady(device); ZLOGI("OnReadyTest001 status = :%{public}d", status); - ASSERT_NE(status, Status::SUCCESS); + ASSERT_EQ(status, Status::SUCCESS); } } // namespace DistributedDataTest } // namespace OHOS::Test diff --git a/kv_store/frameworks/libs/distributeddb/cfi_blocklist.txt b/datamgr_service/services/distributeddataservice/service/test/mock/BUILD.gn similarity index 35% rename from kv_store/frameworks/libs/distributeddb/cfi_blocklist.txt rename to datamgr_service/services/distributeddataservice/service/test/mock/BUILD.gn index 9033f668..4a458579 100644 --- a/kv_store/frameworks/libs/distributeddb/cfi_blocklist.txt +++ b/datamgr_service/services/distributeddataservice/service/test/mock/BUILD.gn @@ -1,17 +1,52 @@ -# Copyright (c) 2023 Huawei Device Co., Ltd. +# Copyright (c) 2024 Huawei Device Co., Ltd. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - - [cfi] - type:*DistributedDB::KvStoreObserver* - src:*/foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb/interfaces/include/kv_store_observer.h - src:*/foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb/* \ No newline at end of file +import("//build/ohos.gni") +import("//foundation/distributeddatamgr/datamgr_service/datamgr_service.gni") + +config("module_private_config") { + visibility = [ ":*" ] + + include_dirs = [ + "../../../framework/include/", + "../../../service/rdb/", + ] + + defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] +} + +ohos_static_library("distributeddata_mock_static") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + + sources = [ + "cursor_mock.cpp", + "db_change_data_mock.cpp", + "db_store_mock.cpp", + "general_store_mock.cpp", + ] + + external_deps = [ + "kv_store:distributeddata_mgr", + "kv_store:distributeddb", + "relational_store:native_rdb", + ] + + configs = [ ":module_private_config" ] + subsystem_name = "distributeddatamgr" + part_name = "datamgr_service" +} +############################################################################### diff --git a/datamgr_service/services/distributeddataservice/service/test/mock/checker_mock.cpp b/datamgr_service/services/distributeddataservice/service/test/mock/checker_mock.cpp new file mode 100644 index 00000000..e3021079 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/mock/checker_mock.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "checker_mock.h" + +namespace OHOS::DistributedData { +CheckerMock::CheckerMock() noexcept +{ + CheckerManager::GetInstance().RegisterPlugin( + "SystemChecker", [this]() -> auto { return this; }); +} +CheckerMock::~CheckerMock() {} +void CheckerMock::SetDynamic(const std::vector &dynamicStores) +{ + dynamicInfos_ = dynamicStores; +} +void CheckerMock::SetStatic(const std::vector &staticStores) +{ + staticInfos_ = staticStores; +} +void CheckerMock::Initialize() {} +bool CheckerMock::SetTrustInfo(const CheckerManager::Trust &trust) +{ + return true; +} +std::string CheckerMock::GetAppId(const CheckerManager::StoreInfo &info) +{ + return info.bundleName; +} +bool CheckerMock::IsValid(const CheckerManager::StoreInfo &info) +{ + return true; +} +bool CheckerMock::SetDistrustInfo(const CheckerManager::Distrust &distrust) +{ + return true; +}; + +bool CheckerMock::IsDistrust(const CheckerManager::StoreInfo &info) +{ + return true; +} +std::vector CheckerMock::GetDynamicStores() +{ + return dynamicInfos_; +} +std::vector CheckerMock::GetStaticStores() +{ + return staticInfos_; +} +bool CheckerMock::IsDynamic(const CheckerManager::StoreInfo &info) +{ + for (const auto &store : dynamicInfos_) { + if (info.bundleName == store.bundleName && info.storeId == store.storeId) { + return true; + } + } + return false; +} +bool CheckerMock::IsStatic(const CheckerManager::StoreInfo &info) +{ + for (const auto &store : staticInfos_) { + if (info.bundleName == store.bundleName && info.storeId == store.storeId) { + return true; + } + } + return false; +} +bool CheckerMock::AddDynamicStore(const CheckerManager::StoreInfo &storeInfo) +{ + return false; +} +bool CheckerMock::AddStaticStore(const CheckerManager::StoreInfo &storeInfo) +{ + return false; +} +bool CheckerMock::IsSwitches(const CheckerManager::StoreInfo &info) +{ + return false; +} +bool CheckerMock::SetSwitchesInfo(const CheckerManager::Switches &switches) +{ + return true; +} +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/mock/checker_mock.h b/datamgr_service/services/distributeddataservice/service/test/mock/checker_mock.h new file mode 100644 index 00000000..f59fca7d --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/mock/checker_mock.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OHOS_DISTRIBUTEDDATA_SERVICE_TEST_CHECKER_MOCK_H +#define OHOS_DISTRIBUTEDDATA_SERVICE_TEST_CHECKER_MOCK_H + +#include "checker/checker_manager.h" +namespace OHOS { +namespace DistributedData { +class CheckerMock : public CheckerManager::Checker { +public: + CheckerMock() noexcept; + ~CheckerMock(); + void SetDynamic(const std::vector &dynamicStores); + void SetStatic(const std::vector &staticStores); + void Initialize() override; + bool SetTrustInfo(const CheckerManager::Trust &trust) override; + std::string GetAppId(const CheckerManager::StoreInfo &info) override; + bool IsValid(const CheckerManager::StoreInfo &info) override; + bool SetDistrustInfo(const CheckerManager::Distrust &distrust) override; + bool IsDistrust(const CheckerManager::StoreInfo &info) override; + std::vector GetDynamicStores() override; + std::vector GetStaticStores() override; + bool IsDynamic(const CheckerManager::StoreInfo &info) override; + bool IsStatic(const CheckerManager::StoreInfo &info) override; + bool AddDynamicStore(const CheckerManager::StoreInfo &storeInfo) override; + bool AddStaticStore(const CheckerManager::StoreInfo &storeInfo) override; + bool IsSwitches(const CheckerManager::StoreInfo &info) override; + bool SetSwitchesInfo(const CheckerManager::Switches &switches) override; + +private: + std::vector dynamicInfos_; + std::vector staticInfos_; +}; + +} // namespace DistributedData +} // namespace OHOS +#endif //OHOS_DISTRIBUTEDDATA_SERVICE_TEST_CHECKER_MOCK_H diff --git a/datamgr_service/services/distributeddataservice/service/test/mock/cloud_server_mock.cpp b/datamgr_service/services/distributeddataservice/service/test/mock/cloud_server_mock.cpp index 4c9b95ee..3b06746b 100644 --- a/datamgr_service/services/distributeddataservice/service/test/mock/cloud_server_mock.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/mock/cloud_server_mock.cpp @@ -21,17 +21,20 @@ CloudServerMock::CloudServerMock(const CloudInfo &cloudInfo, const std::map CloudServerMock::GetAppSchema(int32_t userId, const std::string &bundleName) { auto it = schemaMetas_.find(bundleName); - return it != schemaMetas_.end() ? it->second : SchemaMeta(); + if (it != schemaMetas_.end()) { + return { E_OK, it->second }; + } + return { E_ERROR, SchemaMeta() }; } } // namespace DistributedData } // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/service/test/mock/cloud_server_mock.h b/datamgr_service/services/distributeddataservice/service/test/mock/cloud_server_mock.h index e0f68f0d..d6b2ebbe 100644 --- a/datamgr_service/services/distributeddataservice/service/test/mock/cloud_server_mock.h +++ b/datamgr_service/services/distributeddataservice/service/test/mock/cloud_server_mock.h @@ -24,8 +24,8 @@ namespace DistributedData { class CloudServerMock : public CloudServer { public: CloudServerMock(const CloudInfo& cloudInfo, const std::map& schemaMetas); - CloudInfo GetServerInfo(int32_t userId) override; - SchemaMeta GetAppSchema(int32_t userId, const std::string &bundleName) override; + CloudInfo GetServerInfo(int32_t userId, bool needSpaceInfo = true) override; + std::pair GetAppSchema(int32_t userId, const std::string &bundleName) override; virtual ~CloudServerMock() = default; private: diff --git a/datamgr_service/services/distributeddataservice/service/test/mock/cursor_mock.cpp b/datamgr_service/services/distributeddataservice/service/test/mock/cursor_mock.cpp index a11612e2..78d49360 100644 --- a/datamgr_service/services/distributeddataservice/service/test/mock/cursor_mock.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/mock/cursor_mock.cpp @@ -80,7 +80,8 @@ int32_t CursorMock::MoveToPrev() int32_t CursorMock::GetEntry(DistributedData::VBucket &entry) { - return GeneralError::E_NOT_SUPPORT; + GetRow(entry); + return GeneralError::E_OK; } int32_t CursorMock::GetRow(DistributedData::VBucket &data) 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 493c4902..acb05513 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 @@ -317,7 +317,6 @@ std::pair DBStoreMock::GetWatermarkInfo(const std::stri return { DBStatus::OK, mark }; } - DBStatus DBStoreMock::Sync(const CloudSyncOption &option, const SyncProcessCallback &onProcess) { return NOT_SUPPORT; @@ -357,6 +356,20 @@ std::pair> DBStoreMock::GetCloudVer { return { NOT_SUPPORT, {} }; } +DBStatus DBStoreMock::SetReceiveDataInterceptor(const DataInterceptor &interceptor) +{ + return NOT_SUPPORT; +} + +DBStatus DBStoreMock::SetCloudSyncConfig(const CloudSyncConfig &config) +{ + return NOT_SUPPORT; +} + +DBStatus DBStoreMock::GetDeviceEntries(const std::string &device, std::vector &entries) const +{ + return NOT_SUPPORT; +} DBStatus DBStoreMock::Reset() { return OK; diff --git a/datamgr_service/services/distributeddataservice/service/test/mock/db_store_mock.h b/datamgr_service/services/distributeddataservice/service/test/mock/db_store_mock.h index 562d9690..051ef045 100644 --- a/datamgr_service/services/distributeddataservice/service/test/mock/db_store_mock.h +++ b/datamgr_service/services/distributeddataservice/service/test/mock/db_store_mock.h @@ -44,6 +44,8 @@ public: using CloudSyncOption = DistributedDB::CloudSyncOption; using SyncProcessCallback = DistributedDB::SyncProcessCallback; using GenerateCloudVersionCallback = DistributedDB::GenerateCloudVersionCallback; + using DataInterceptor = DistributedDB::DataInterceptor; + using CloudSyncConfig = DistributedDB::CloudSyncConfig; DBStatus Get(const Key &key, Value &value) const override; DBStatus GetEntries(const Key &keyPrefix, std::vector &entries) const override; DBStatus GetEntries(const Key &keyPrefix, KvStoreResultSet *&resultSet) const override; @@ -105,6 +107,9 @@ public: int32_t GetTaskCount() override; void SetGenCloudVersionCallback(const GenerateCloudVersionCallback &callback) override; std::pair> GetCloudVersion(const std::string &device) override; + DBStatus SetReceiveDataInterceptor(const DataInterceptor &interceptor) override; + DBStatus SetCloudSyncConfig(const CloudSyncConfig &config) override; + DBStatus GetDeviceEntries(const std::string &device, std::vector &entries) const override; DBStatus Reset(); private: static const uint32_t DEFAULT_SIZE = 0; 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 5edaea77..748c0224 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 @@ -1,110 +1,115 @@ /* -* Copyright (c) 2023 Huawei Device Co., Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include "general_store_mock.h" - namespace OHOS { namespace DistributedData { - -StoreMetaData GeneralStoreMock::GetStoreMetaData() -{ - return StoreMetaData(); -} -int32_t GeneralStoreMock::Clean(const std::vector& devices, int32_t mode, const std::string& tableName) -{ - return 0; -} GeneralStoreMock::GeneralStoreMock(const StoreMetaData& meta) {} GeneralStoreMock::~GeneralStoreMock() {} bool GeneralStoreMock::IsValid() { return true; } -int32_t GeneralStoreMock::Bind(Database &database, const std::map &bindInfos) +StoreMetaData GeneralStoreMock::GetStoreMetaData() +{ + return StoreMetaData(); +} +int32_t GeneralStoreMock::Bind(Database &database, const std::map &bindInfos, + const CloudConfig &config) { return 0; } + 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, int32_t type, const std::vector &references) { return 0; } -int32_t GeneralStoreMock::Insert(const std::string& table, VBuckets&& values) + +int32_t GeneralStoreMock::SetTrackerTable( + const std::string &tableName, const std::set &trackerColNames, const std::string &extendColName) { return 0; } -int32_t GeneralStoreMock::Update(const std::string& table, const std::string& setSql, Values&& values, - const std::string& whereSql, Values&& conditions) + +int32_t GeneralStoreMock::Insert(const std::string &table, VBuckets &&values) { return 0; } -int32_t GeneralStoreMock::Delete(const std::string& table, const std::string& sql, Values&& args) + +int32_t GeneralStoreMock::Update(const std::string &table, const std::string &setSql, Values &&values, + const std::string &whereSql, Values &&conditions) { return 0; } -std::shared_ptr GeneralStoreMock::Query(const std::string& table, const std::string& sql, Values&& args) + +int32_t GeneralStoreMock::Replace(const std::string &table, VBucket &&value) { - return std::shared_ptr(); + return 0; } -std::shared_ptr GeneralStoreMock::Query(const std::string& table, GenQuery& query) + +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, GenQuery &query) { - return std::shared_ptr(); + return nullptr; } + int32_t GeneralStoreMock::Sync(const Devices &devices, GenQuery &query, DetailAsync async, SyncParam &syncParm) { return 0; } -int32_t GeneralStoreMock::Watch(int32_t origin, Watcher& watcher) +std::shared_ptr GeneralStoreMock::PreSharing(GenQuery &query) { - if (origin != Watcher::Origin::ORIGIN_ALL || watcher_ != nullptr) { - return GeneralError::E_INVALID_ARGS; - } - - watcher_ = &watcher; - return GeneralError::E_OK; + return nullptr; } -int32_t GeneralStoreMock::Unwatch(int32_t origin, Watcher& watcher) +int32_t GeneralStoreMock::Clean(const std::vector &devices, int32_t mode, const std::string &tableName) { - if (origin != Watcher::Origin::ORIGIN_ALL || watcher_ != &watcher) { - return GeneralError::E_INVALID_ARGS; - } + return 0; +} - watcher_ = nullptr; - return GeneralError::E_OK; +int32_t GeneralStoreMock::Watch(int32_t origin, Watcher &watcher) +{ + return 0; } -int32_t GeneralStoreMock::Close() +int32_t GeneralStoreMock::Unwatch(int32_t origin, Watcher &watcher) { return 0; } -int32_t GeneralStoreMock::AddRef() +int32_t GeneralStoreMock::RegisterDetailProgressObserver(DetailAsync async) { return 0; } -int32_t GeneralStoreMock::Release() +int32_t GeneralStoreMock::UnregisterDetailProgressObserver() { return 0; } @@ -118,39 +123,47 @@ int32_t GeneralStoreMock::OnChange(const GeneralWatcher::Origin& origin, const G } return GeneralError::E_ERROR; } -int32_t GeneralStoreMock::RegisterDetailProgressObserver(GeneralStore::DetailAsync async) + +int32_t GeneralStoreMock::Close() { return 0; } -int32_t GeneralStoreMock::UnregisterDetailProgressObserver() + +int32_t GeneralStoreMock::AddRef() { return 0; } -int32_t GeneralStoreMock::SetTrackerTable(const std::string& tableName, const std::set& trackerColNames, - const std::string& extendColName) + +int32_t GeneralStoreMock::Release() { return 0; } -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) + +int32_t GeneralStoreMock::MergeMigratedData(const std::string &tableName, VBuckets &&values) { return 0; } -int32_t GeneralStoreMock::Replace(const std::string& table, VBucket&& value) + +std::shared_ptr GeneralStoreMock::Query(const std::string &table, const std::string &sql, Values &&args) { - return 0; + return cursor_; } -std::vector GeneralStoreMock::GetWaterVersion(const std::string& deviceId) + +std::vector GeneralStoreMock::GetWaterVersion(const std::string &deviceId) { return std::vector(); } +void GeneralStoreMock::MakeCursor(const std::map &entry) +{ + auto resultSet = std::make_shared(1, entry); + cursor_ = std::make_shared(resultSet); +} +GeneralStoreMock::GeneralStoreMock() {} } // 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 10344794..45773e34 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 @@ -1,23 +1,24 @@ /* -* Copyright (c) 2023 Huawei Device Co., Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OHOS_DISTRIBUTEDDATA_SERVICE_TEST_GENERAL_STORE_MOCK_H +#define OHOS_DISTRIBUTEDDATA_SERVICE_TEST_GENERAL_STORE_MOCK_H -#ifndef OHOS_DISTRIBUTEDDATA_SERVICE_TEST_RDB_GENERAL_STORE_H -#define OHOS_DISTRIBUTEDDATA_SERVICE_TEST_RDB_GENERAL_STORE_H #include #include #include +#include "cursor_mock.h" #include "metadata/store_meta_data.h" #include "rdb_asset_loader.h" #include "rdb_cloud.h" @@ -25,50 +26,52 @@ #include "relational_store_delegate.h" #include "relational_store_manager.h" #include "store/general_store.h" -#include "store/general_value.h" -#include "store/general_watcher.h" -namespace OHOS::DistributedData { -using namespace OHOS::DistributedData; -class GeneralStoreMock : public DistributedData::GeneralStore { +namespace OHOS { +namespace DistributedData { +class GeneralStoreMock : public GeneralStore { public: - explicit GeneralStoreMock(const StoreMetaData &meta); - ~GeneralStoreMock(); - bool IsValid(); - int32_t Bind(Database &database, const std::map &bindInfos) override; - bool IsBound() override; - int32_t Execute(const std::string &table, const std::string &sql) override; - int32_t SetDistributedTables(const std::vector &tables, int type, - const std::vector &references) override; - int32_t SetTrackerTable(const std::string& tableName, const std::set& trackerColNames, - const std::string& extendColName) override; - int32_t Insert(const std::string& table, VBuckets&& values) override; - int32_t Update(const std::string& table, const std::string& setSql, Values&& values, const std::string& whereSql, - Values&& conditions) override; - int32_t Delete(const std::string &table, const std::string &sql, Values &&args) override; - std::shared_ptr Query(const std::string &table, const std::string &sql, Values &&args) override; - std::shared_ptr Query(const std::string &table, GenQuery &query) override; - std::shared_ptr PreSharing(GenQuery &query) override; - int32_t Sync(const Devices &devices, GenQuery &query, DetailAsync async, SyncParam &syncParm) override; - int32_t Clean(const std::vector &devices, int32_t mode, const std::string &tableName) override; - int32_t Watch(int32_t origin, Watcher &watcher) override; - int32_t Unwatch(int32_t origin, Watcher &watcher) override; - int32_t RegisterDetailProgressObserver(DetailAsync async) override; - int32_t UnregisterDetailProgressObserver() override; - int32_t Close() override; - int32_t AddRef() override; - int32_t Release() override; - int32_t Replace(const std::string &table, VBucket &&value) override; + explicit GeneralStoreMock(const StoreMetaData &meta); + GeneralStoreMock(); + ~GeneralStoreMock(); + bool IsValid(); + int32_t Bind(Database &database, const std::map &bindInfos, + const CloudConfig &config) override; + bool IsBound() override; + int32_t Execute(const std::string &table, const std::string &sql) override; + int32_t SetDistributedTables( + const std::vector &tables, int32_t type, const std::vector &references) override; + int32_t SetTrackerTable(const std::string &tableName, const std::set &trackerColNames, + const std::string &extendColName) override; + int32_t Insert(const std::string &table, VBuckets &&values) override; + int32_t Update(const std::string &table, const std::string &setSql, Values &&values, const std::string &whereSql, + Values &&conditions) override; + int32_t Replace(const std::string &table, VBucket &&value) override; + int32_t Delete(const std::string &table, const std::string &sql, Values &&args) override; + std::shared_ptr Query(const std::string &table, const std::string &sql, Values &&args) override; + std::shared_ptr Query(const std::string &table, GenQuery &query) override; + int32_t Sync(const Devices &devices, GenQuery &query, DetailAsync async, SyncParam &syncParm) override; + std::shared_ptr PreSharing(GenQuery &query) override; + int32_t Clean(const std::vector &devices, int32_t mode, const std::string &tableName) override; + int32_t Watch(int32_t origin, Watcher &watcher) override; + int32_t Unwatch(int32_t origin, Watcher &watcher) override; + int32_t RegisterDetailProgressObserver(DetailAsync async) override; + int32_t UnregisterDetailProgressObserver() override; + int32_t Close() override; + int32_t AddRef() override; + int32_t Release() override; + int32_t BindSnapshots(std::shared_ptr>> bindAssets) override; + int32_t MergeMigratedData(const std::string &tableName, VBuckets &&values) override; + std::vector GetWaterVersion(const std::string &deviceId) override; + void MakeCursor(const std::map &entry); + int32_t OnChange(const GeneralWatcher::Origin &origin, const GeneralWatcher::PRIFields &primaries, + GeneralWatcher::ChangeInfo &&changeInfo); - int32_t BindSnapshots(std::shared_ptr>> bindAssets) override; - std::vector GetWaterVersion(const std::string& deviceId) 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); - - StoreMetaData GetStoreMetaData(); + StoreMetaData GetStoreMetaData(); private: + std::shared_ptr cursor_ = nullptr; Watcher* watcher_ = nullptr; }; -} // namespace OHOS::DistributedData -#endif // OHOS_DISTRIBUTEDDATA_SERVICE_TEST_RDB_GENERAL_STORE_H +} // namespace DistributedData +} // namespace OHOS +#endif \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/object_asset_machine_test.cpp b/datamgr_service/services/distributeddataservice/service/test/object_asset_machine_test.cpp index 76fe7a80..96912249 100644 --- a/datamgr_service/services/distributeddataservice/service/test/object_asset_machine_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/object_asset_machine_test.cpp @@ -64,7 +64,7 @@ void ObjectAssetMachineTest::SetUp() .assetName = "asset1.jpg", }; AssetBindInfo_ = AssetBindInfo; - StoreInfo storeInfo{ + StoreInfo storeInfo { .tokenId = 0, .bundleName = "bundleName_test", .storeName = "store_test", @@ -180,6 +180,31 @@ HWTEST_F(ObjectAssetMachineTest, StatusTransfer004, TestSize.Level0) ASSERT_EQ(changedAssets_[uri_].status, STATUS_STABLE); } +/** +* @tc.name: StatusTransfer005 +* @tc.desc: Transfer event +* @tc.type: FUNC +* @tc.require: +* @tc.author: nhj +*/ +HWTEST_F(ObjectAssetMachineTest, StatusTransfer005, TestSize.Level0) +{ + auto machine = std::make_shared(); + Asset asset{ + .name = "test_name", + .uri = uri_, + .modifyTime = "modifyTime1", + .size = "size1", + .hash = "modifyTime1_size1", + }; + std::pair changedAsset{ "device_2", asset }; + changedAssets_[uri_].status = STATUS_UPLOADING; + machine->DFAPostEvent(REMOTE_CHANGED, changedAssets_[uri_], asset, changedAsset); + ASSERT_EQ(changedAssets_[uri_].status, STATUS_WAIT_TRANSFER); + ASSERT_EQ(changedAssets_[uri_].deviceId, changedAsset.first); + ASSERT_EQ(changedAssets_[uri_].asset.hash, asset.hash); +} + /** * @tc.name: StatusUpload001 * @tc.desc: No conflict scenarios: normal cloud sync. @@ -233,4 +258,58 @@ HWTEST_F(ObjectAssetMachineTest, StatusUpload002, TestSize.Level0) machine->DFAPostEvent(UPLOAD_FINISHED, changedAssets_[uri_], asset); ASSERT_EQ(changedAssets_[uri_].status, STATUS_TRANSFERRING); } -} // namespace OHOS::Test + +/** +* @tc.name: StatusDownload001 +* @tc.desc: No conflict scenarios: normal cloud sync. +* @tc.type: FUNC +* @tc.require: +* @tc.author: nhj +*/ +HWTEST_F(ObjectAssetMachineTest, StatusDownload001, TestSize.Level0) +{ + auto machine = std::make_shared(); + Asset asset{ + .name = "test_name", + .uri = uri_, + .modifyTime = "modifyTime1", + .size = "size1", + .hash = "modifyTime1_size1", + }; + std::pair changedAsset{ "device_1", asset }; + machine->DFAPostEvent(DOWNLOAD, changedAssets_[uri_], asset, changedAsset); + ASSERT_EQ(changedAssets_[uri_].status, STATUS_DOWNLOADING); + + machine->DFAPostEvent(DOWNLOAD_FINISHED, changedAssets_[uri_], asset); + ASSERT_EQ(changedAssets_[uri_].status, STATUS_STABLE); +} + +/** +* @tc.name: StatusDownload002 +* @tc.desc: Conflict scenario: Download before transfer. +* @tc.type: FUNC +* @tc.require: +* @tc.author: nhj +*/ +HWTEST_F(ObjectAssetMachineTest, StatusDownload002, TestSize.Level0) +{ + auto machine = std::make_shared(); + Asset asset{ + .name = "test_name", + .uri = uri_, + .modifyTime = "modifyTime1", + .size = "size1", + .hash = "modifyTime1_size1", + }; + std::pair changedAsset{ "device_1", asset }; + machine->DFAPostEvent(DOWNLOAD, changedAssets_[uri_], asset); + ASSERT_EQ(changedAssets_[uri_].status, STATUS_DOWNLOADING); + + machine->DFAPostEvent(REMOTE_CHANGED, changedAssets_[uri_], asset, changedAsset); + ASSERT_EQ(changedAssets_[uri_].status, STATUS_WAIT_TRANSFER); + ASSERT_EQ(changedAssets_[uri_].asset.hash, asset.hash); + + machine->DFAPostEvent(DOWNLOAD_FINISHED, changedAssets_[uri_], asset); + ASSERT_EQ(changedAssets_[uri_].status, STATUS_TRANSFERRING); +} +} // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/rdb_asset_loader_test.cpp b/datamgr_service/services/distributeddataservice/service/test/rdb_asset_loader_test.cpp new file mode 100644 index 00000000..9ab9c95e --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/rdb_asset_loader_test.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define LOG_TAG "RdbAssetLoaderTest" + +#include "gtest/gtest.h" +#include "log_print.h" +#include "rdb_asset_loader.h" +#include "store/cursor.h" + +using namespace OHOS; +using namespace testing; +using namespace testing::ext; +using namespace OHOS::DistributedRdb; +using namespace OHOS::DistributedData; +using Type = DistributedDB::Type; +const DistributedDB::Asset g_rdbAsset = { + .version = 1, + .name = "Phone", + .assetId = "0", + .subpath = "/local/sync", + .uri = "file://rdbtest/local/sync", + .modifyTime = "123456", + .createTime = "createTime", + .size = "256", + .hash = "ASE" +}; +namespace OHOS::Test { +namespace DistributedRDBTest { +class RdbAssetLoaderTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp(){}; + void TearDown(){}; +}; + +class MockAssetLoader : public DistributedData::AssetLoader { +public: + int32_t Download(const std::string &tableName, const std::string &gid, + const DistributedData::Value &prefix, VBucket &assets) override + { + return GeneralError::E_OK; + } + + int32_t RemoveLocalAssets(const std::string &tableName, const std::string &gid, + const DistributedData::Value &prefix, VBucket &assets) override + { + return GeneralError::E_OK; + } +}; + +/** +* @tc.name: Download +* @tc.desc: RdbAssetLoader download test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbAssetLoaderTest, Download, TestSize.Level0) +{ + BindAssets bindAssets; + std::shared_ptr cloudAssetLoader = std::make_shared(); + DistributedRdb::RdbAssetLoader rdbAssetLoader(cloudAssetLoader, &bindAssets); + std::string tableName = "testTable"; + std::string groupId = "testGroup"; + Type prefix; + std::map assets; + assets["asset1"].push_back(g_rdbAsset); + auto result = rdbAssetLoader.Download(tableName, groupId, prefix, assets); + EXPECT_EQ(result, DistributedDB::DBStatus::OK); +} + +/** +* @tc.name: RemoveLocalAssets +* @tc.desc: RdbAssetLoader RemoveLocalAssets test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbAssetLoaderTest, RemoveLocalAssets, TestSize.Level0) +{ + BindAssets bindAssets; + std::shared_ptr cloudAssetLoader = std::make_shared(); + DistributedRdb::RdbAssetLoader rdbAssetLoader(cloudAssetLoader, &bindAssets); + std::vector assets; + assets.push_back(g_rdbAsset); + auto result = rdbAssetLoader.RemoveLocalAssets(assets); + EXPECT_EQ(result, DistributedDB::DBStatus::OK); +} + +/** +* @tc.name: PostEvent +* @tc.desc: RdbAssetLoader PostEvent abnormal +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbAssetLoaderTest, PostEvent, TestSize.Level0) +{ + BindAssets bindAssets; + bindAssets.bindAssets = nullptr; + std::shared_ptr assetLoader = std::make_shared(); + DistributedRdb::RdbAssetLoader rdbAssetLoader(assetLoader, &bindAssets); + std::string tableName = "testTable"; + std::string groupId = "testGroup"; + Type prefix; + std::map assets; + assets["asset1"].push_back(g_rdbAsset); + auto result = rdbAssetLoader.Download(tableName, groupId, prefix, assets); + EXPECT_EQ(result, DistributedDB::DBStatus::CLOUD_ERROR); +} +} // namespace DistributedRDBTest +} // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/rdb_cloud_test.cpp b/datamgr_service/services/distributeddataservice/service/test/rdb_cloud_test.cpp new file mode 100644 index 00000000..3be6d2d0 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/rdb_cloud_test.cpp @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define LOG_TAG "RdbCloudTest" + +#include "gtest/gtest.h" +#include "log_print.h" +#include "rdb_cloud.h" +#include "rdb_cloud_data_translate.h" + +using namespace testing::ext; +using namespace OHOS::DistributedData; +using namespace OHOS::DistributedRdb; +using DBVBucket = DistributedDB::VBucket; +using DBStatus = DistributedDB::DBStatus; +std::vector g_DBVBucket = { + { + {"#gid", {"0000000"}}, + {"#flag", {true}}, + {"#value", {int64_t(100)}}, + {"#float", {double(100)}}, + {"#_type", {int64_t(1)}}, + {"#_query", {Bytes({ 1, 2, 3, 4 })}} + } +}; +namespace OHOS::Test { +namespace DistributedRDBTest { +class RdbCloudTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp(){}; + void TearDown(){}; +protected: +}; + +/** +* @tc.name: RdbCloudTest001 +* @tc.desc: RdbCloud BatchInsert BatchUpdate BatchDelete test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbCloudTest, RdbCloudTest001, TestSize.Level1) +{ + BindAssets bindAssets; + Bytes bytes; + std::shared_ptr cloudDB = std::make_shared(); + RdbCloud rdbCloud(cloudDB, &bindAssets); + std::string tableName = "testTable"; + auto result = rdbCloud.BatchInsert(tableName, std::move(g_DBVBucket), g_DBVBucket); + EXPECT_EQ(result, DBStatus::CLOUD_ERROR); + result = rdbCloud.BatchUpdate(tableName, std::move(g_DBVBucket), g_DBVBucket); + EXPECT_EQ(result, DBStatus::CLOUD_ERROR); + result = rdbCloud.BatchDelete(tableName, g_DBVBucket); + EXPECT_EQ(result, DBStatus::CLOUD_ERROR); +} + +/** +* @tc.name: RdbCloudTest002 +* @tc.desc: RdbCloud Query PreSharing HeartBeat Close test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbCloudTest, RdbCloudTest002, TestSize.Level1) +{ + BindAssets bindAssets; + std::shared_ptr cloudDB = std::make_shared(); + RdbCloud rdbCloud(cloudDB, &bindAssets); + std::string tableName = "testTable"; + rdbCloud.Lock(); + auto result = rdbCloud.BatchInsert(tableName, std::move(g_DBVBucket), g_DBVBucket); + EXPECT_EQ(result, DBStatus::CLOUD_ERROR); + DBVBucket extends = { + {"#gid", {"0000000"}}, {"#flag", {true}}, {"#value", {int64_t(100)}}, {"#float", {double(100)}}, + {"#_type", {int64_t(1)}}, {"#_query", {Bytes({ 1, 2, 3, 4 })}} + }; + result = rdbCloud.Query(tableName, extends, g_DBVBucket); + EXPECT_EQ(result, DBStatus::CLOUD_ERROR); + std::vector vBuckets = { + {{"#gid", {"0000000"}}, {"#flag", {true}}, {"#value", {int64_t(100)}}, {"#float", {double(100)}}, + {"#_type", {int64_t(1)}}, {"#_query", {Bytes({ 1, 2, 3, 4 })}}} + }; + rdbCloud.PreSharing(tableName, vBuckets); + result = rdbCloud.HeartBeat(); + EXPECT_EQ(result, DBStatus::CLOUD_ERROR); + rdbCloud.UnLock(); + rdbCloud.GetEmptyCursor(tableName); + result = rdbCloud.Close(); + EXPECT_EQ(result, DBStatus::CLOUD_ERROR); +} + +/** +* @tc.name: RdbCloudTest003 +* @tc.desc: RdbCloud Query error test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbCloudTest, RdbCloudTest003, TestSize.Level1) +{ + BindAssets bindAssets; + bindAssets.bindAssets = nullptr; + std::shared_ptr cloudDB = std::make_shared(); + RdbCloud rdbCloud(cloudDB, &bindAssets); + std::string tableName = "testTable"; + DBVBucket extends = { + {"#gid", {"0000000"}}, {"#flag", {true}}, {"#value", {int64_t(100)}}, {"#float", {double(100)}}, + {"#_type", {int64_t(1)}} + }; + std::vector data = { + {{"#gid", {"0000000"}}, {"#flag", {true}}, {"#value", {int64_t(100)}}, {"#float", {double(100)}}} + }; + auto result = rdbCloud.Query(tableName, extends, data); + EXPECT_EQ(result, DBStatus::CLOUD_ERROR); + + extends = { + {"#gid", {"0000000"}}, {"#flag", {true}}, {"#value", {int64_t(100)}}, {"#float", {double(100)}}, + {"#_query", {Bytes({ 1, 2, 3, 4 })}} + }; + result = rdbCloud.Query(tableName, extends, data); + EXPECT_EQ(result, DBStatus::CLOUD_ERROR); + + extends = { + {"#gid", {"0000000"}}, {"#flag", {true}}, {"#value", {int64_t(100)}}, {"#float", {double(100)}}, + {"#_type", {int64_t(0)}} + }; + result = rdbCloud.Query(tableName, extends, data); + EXPECT_EQ(result, DBStatus::CLOUD_ERROR); +} + +/** +* @tc.name: ConvertStatus +* @tc.desc: RdbCloud ConvertStatus function test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbCloudTest, ConvertStatus, TestSize.Level1) +{ + BindAssets bindAssets; + std::shared_ptr cloudDB = std::make_shared(); + RdbCloud rdbCloud(cloudDB, &bindAssets); + auto result = rdbCloud.ConvertStatus(GeneralError::E_OK); + EXPECT_EQ(result, DBStatus::OK); + result = rdbCloud.ConvertStatus(GeneralError::E_NETWORK_ERROR); + EXPECT_EQ(result, DBStatus::CLOUD_NETWORK_ERROR); + result = rdbCloud.ConvertStatus(GeneralError::E_LOCKED_BY_OTHERS); + EXPECT_EQ(result, DBStatus::CLOUD_LOCK_ERROR); + result = rdbCloud.ConvertStatus(GeneralError::E_RECODE_LIMIT_EXCEEDED); + EXPECT_EQ(result, DBStatus::CLOUD_FULL_RECORDS); + result = rdbCloud.ConvertStatus(GeneralError::E_NO_SPACE_FOR_ASSET); + EXPECT_EQ(result, DBStatus::CLOUD_ASSET_SPACE_INSUFFICIENT); + result = rdbCloud.ConvertStatus(GeneralError::E_RECORD_EXIST_CONFLICT); + EXPECT_EQ(result, DBStatus::CLOUD_RECORD_EXIST_CONFLICT); +} + +/** +* @tc.name: BlobToAssets +* @tc.desc: rdb_cloud_data_translate BlobToAsset error test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbCloudTest, BlobToAssets, TestSize.Level1) +{ + RdbCloudDataTranslate rdbTranslate; + DistributedDB::Asset asset = { + .name = "", + .assetId = "", + .subpath = "", + .uri = "", + .modifyTime = "", + .createTime = "", + .size = "", + .hash = "" + }; + std::vector blob; + auto result = rdbTranslate.BlobToAsset(blob); + EXPECT_EQ(result, asset); + + DistributedDB::Assets assets; + blob = rdbTranslate.AssetsToBlob(assets); + auto results = rdbTranslate.BlobToAssets(blob); + EXPECT_EQ(results, assets); +} +} // namespace DistributedRDBTest +} // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/rdb_cursor_test.cpp b/datamgr_service/services/distributeddataservice/service/test/rdb_cursor_test.cpp new file mode 100644 index 00000000..d8aa4815 --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/rdb_cursor_test.cpp @@ -0,0 +1,312 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define LOG_TAG "RdbCursorTest" + +#include "gtest/gtest.h" +#include "log_print.h" +#define private public +#include "rdb_cursor.h" +#include "result_set.h" +#include "store/general_value.h" + +using namespace OHOS; +using namespace testing; +using namespace testing::ext; +using namespace OHOS::DistributedRdb; +using namespace OHOS::DistributedData; +using DBStatus = DistributedDB::DBStatus; +namespace OHOS::Test { +namespace DistributedRDBTest { +static constexpr int MAX_DATA_NUM = 100; +class MockResultSet : public DistributedDB::ResultSet { +public: + MockResultSet() {} + virtual ~MockResultSet() {} + + void Close() override + { + } + + int GetCount() const override + { + return MAX_DATA_NUM; + } + + bool MoveToFirst() override + { + return true; + } + + bool MoveToNext() override + { + return true; + } + + bool MoveToPrevious() override + { + return true; + } + + bool IsAfterLast() const override + { + return true; + } + + int GetPosition() const override + { + return MAX_DATA_NUM; + } + + bool MoveToLast() override + { + return true; + } + + bool Move(int offset) override + { + return true; + } + + bool MoveToPosition(int position) override + { + return true; + } + + bool IsFirst() const override + { + return true; + } + + bool IsLast() const override + { + return true; + } + + bool IsBeforeFirst() const override + { + return true; + } + + bool IsClosed() const override + { + return true; + } + + DBStatus GetEntry(DistributedDB::Entry &entry) const override + { + return DBStatus::OK; + } + + void GetColumnNames(std::vector &columnNames) const override + { + columnNames = {"age", "identifier", "name", "phoneNumber"}; + } + + DBStatus GetColumnType(int columnIndex, DistributedDB::ResultSet::ColumnType &columnType) const override + { + if (columnIndex < 0) { + return DBStatus::DB_ERROR; + } + return DBStatus::OK; + } + + DBStatus GetColumnIndex(const std::string &columnName, int &columnIndex) const override + { + if (columnName == "ERROR") { + return DBStatus::DB_ERROR; + } + return DBStatus::OK; + } + + DBStatus GetColumnName(int columnIndex, std::string &columnName) const override + { + if (columnIndex < 0) { + return DBStatus::DB_ERROR; + } + return DBStatus::OK; + } + + DBStatus Get(int columnIndex, std::vector &value) const override + { + if (columnIndex < 0) { + return DBStatus::DB_ERROR; + } + return DBStatus::OK; + } + + DBStatus Get(int columnIndex, std::string &value) const override + { + if (columnIndex < 0) { + return DBStatus::DB_ERROR; + } + return DBStatus::OK; + } + + DBStatus Get(int columnIndex, int64_t &value) const override + { + if (columnIndex < 0) { + return DBStatus::DB_ERROR; + } + return DBStatus::OK; + } + + DBStatus Get(int columnIndex, double &value) const override + { + if (columnIndex < 0) { + return DBStatus::DB_ERROR; + } + return DBStatus::OK; + } + + DBStatus IsColumnNull(int columnIndex, bool &isNull) const override + { + if (columnIndex < 0) { + return DBStatus::DB_ERROR; + } + return DBStatus::OK; + } + + DBStatus GetRow(std::map &data) const override + { + return DBStatus::OK; + } +}; + +class RdbCursorTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp(){}; + void TearDown(){}; +protected: + static std::shared_ptr resultSet; + static std::shared_ptr rdbCursor; +}; +std::shared_ptr RdbCursorTest::resultSet = std::make_shared(); +std::shared_ptr RdbCursorTest::rdbCursor = std::make_shared(std::move(resultSet)); + +/** +* @tc.name: RdbCursorTest001 +* @tc.desc: RdbCacheCursor function and error test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbCursorTest, RdbCursorTest001, TestSize.Level1) +{ + EXPECT_NE(rdbCursor, nullptr); + std::vector expectedNames = {"age", "identifier", "name", "phoneNumber"}; + std::vector names; + auto result = rdbCursor->GetColumnNames(names); + EXPECT_EQ(result, GeneralError::E_OK); + EXPECT_EQ(names, expectedNames); + + std::string colName = "colName"; + auto err = rdbCursor->GetColumnName(1, colName); + EXPECT_EQ(err, GeneralError::E_OK); + + int32_t type = rdbCursor->GetColumnType(0); + EXPECT_EQ(type, TYPE_INDEX); + type = rdbCursor->GetColumnType(-1); + EXPECT_EQ(type, TYPE_INDEX); + + int32_t count = rdbCursor->GetCount(); + EXPECT_EQ(count, MAX_DATA_NUM); + + err = rdbCursor->MoveToFirst(); + EXPECT_EQ(err, GeneralError::E_OK); + + err = rdbCursor->MoveToNext(); + EXPECT_EQ(err, GeneralError::E_OK); + + err = rdbCursor->MoveToPrev(); + EXPECT_EQ(err, GeneralError::E_OK); +} + +/** +* @tc.name: RdbCursorTest002 +* @tc.desc: RdbCacheCursor function and error test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbCursorTest, RdbCursorTest002, TestSize.Level1) +{ + EXPECT_NE(rdbCursor, nullptr); + DistributedData::VBucket data; + auto result = rdbCursor->GetEntry(data); + EXPECT_EQ(result, GeneralError::E_OK); + + result = rdbCursor->GetRow(data); + EXPECT_EQ(result, GeneralError::E_OK); + + DistributedData::Value value; + result = rdbCursor->Get(1, value); + EXPECT_EQ(result, GeneralError::E_OK); + result = rdbCursor->Get(-1, value); + EXPECT_EQ(result, GeneralError::E_ERROR); + + std::string col = "col"; + result = rdbCursor->Get(col, value); + EXPECT_EQ(result, GeneralError::E_ERROR); + result = rdbCursor->Get("ERROR", value); + EXPECT_EQ(result, GeneralError::E_ERROR); + bool ret = rdbCursor->IsEnd(); + EXPECT_EQ(ret, true); + + result = rdbCursor->Close(); + EXPECT_EQ(result, GeneralError::E_OK); +} + +/** +* @tc.name: Convert +* @tc.desc: Convert function test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbCursorTest, Convert, TestSize.Level1) +{ + EXPECT_NE(rdbCursor, nullptr); + DistributedDB::ResultSet::ColumnType dbColumnType = DistributedDB::ResultSet::ColumnType::INT64; + int32_t result = rdbCursor->Convert(dbColumnType); + EXPECT_EQ(result, TYPE_INDEX); + + dbColumnType = DistributedDB::ResultSet::ColumnType::STRING; + result = rdbCursor->Convert(dbColumnType); + EXPECT_EQ(result, TYPE_INDEX); + + dbColumnType = DistributedDB::ResultSet::ColumnType::BLOB; + result = rdbCursor->Convert(dbColumnType); + EXPECT_EQ(result, TYPE_INDEX>); + + dbColumnType = DistributedDB::ResultSet::ColumnType::DOUBLE; + result = rdbCursor->Convert(dbColumnType); + EXPECT_EQ(result, TYPE_INDEX); + + dbColumnType = DistributedDB::ResultSet::ColumnType::NULL_VALUE; + result = rdbCursor->Convert(dbColumnType); + EXPECT_EQ(result, TYPE_INDEX); + + dbColumnType = DistributedDB::ResultSet::ColumnType::INVALID_TYPE; + result = rdbCursor->Convert(dbColumnType); + EXPECT_EQ(result, TYPE_INDEX); + + dbColumnType = static_cast(MAX_DATA_NUM); + result = rdbCursor->Convert(dbColumnType); + EXPECT_EQ(result, TYPE_INDEX); +} +} // namespace DistributedRDBTest +} // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/rdb_general_store_test.cpp b/datamgr_service/services/distributeddataservice/service/test/rdb_general_store_test.cpp new file mode 100644 index 00000000..a0a1794c --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/rdb_general_store_test.cpp @@ -0,0 +1,1018 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#define LOG_TAG "RdbGeneralStoreTest" + + +#include + +#include "bootstrap.h" +#include "cloud/schema_meta.h" +#include "gtest/gtest.h" +#define private public +#include "rdb_general_store.h" +#include "log_print.h" +#include "metadata/meta_data_manager.h" +#include "metadata/secret_key_meta_data.h" +#include "metadata/store_meta_data.h" +#include "metadata/store_meta_data_local.h" +#include "rdb_query.h" +#include "store/general_store.h" +#include "types.h" + +using namespace testing::ext; +using namespace DistributedDB; +using namespace OHOS::DistributedData; +using namespace OHOS::DistributedRdb; +using DBStatus = DistributedDB::DBStatus; +using StoreMetaData = OHOS::DistributedData::StoreMetaData; +RdbGeneralStore::Values g_RdbValues = { { "0000000" }, { true }, { int64_t(100) }, { double(100) }, { int64_t(1) }, + { Bytes({ 1, 2, 3, 4 }) } }; +RdbGeneralStore::VBucket g_RdbVBucket = { { "#gid", { "0000000" } }, { "#flag", { true } }, + { "#value", { int64_t(100) } }, { "#float", { double(100) } } }; +bool g_testResult = false; +namespace OHOS::Test { +namespace DistributedRDBTest { +static constexpr uint32_t PRINT_ERROR_CNT = 150; +static constexpr const char *BUNDLE_NAME = "test_rdb_general_store"; +static constexpr const char *STORE_NAME = "test_service_rdb"; +class RdbGeneralStoreTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp() + { + Bootstrap::GetInstance().LoadDirectory(); + InitMetaData(); + }; + void TearDown() + { + g_testResult = false; + }; + +protected: + void InitMetaData(); + StoreMetaData metaData_; +}; + +void RdbGeneralStoreTest::InitMetaData() +{ + metaData_.bundleName = BUNDLE_NAME; + metaData_.appId = BUNDLE_NAME; + metaData_.user = "0"; + metaData_.area = DistributedKv::Area::EL1; + metaData_.instanceId = 0; + metaData_.isAutoSync = true; + metaData_.storeType = 1; + metaData_.storeId = STORE_NAME; + metaData_.dataDir = "/data/service/el1/public/database/" + std::string(BUNDLE_NAME) + "/rdb"; + metaData_.securityLevel = DistributedKv::SecurityLevel::S2; +} + +class MockRelationalStoreDelegate : public DistributedDB::RelationalStoreDelegate { +public: + ~MockRelationalStoreDelegate() = default; + + DBStatus Sync(const std::vector &devices, DistributedDB::SyncMode mode, const Query &query, + const SyncStatusCallback &onComplete, bool wait) override + { + return DBStatus::OK; + } + + int32_t GetCloudSyncTaskCount() override + { + static int32_t count = 0; + count = (count + 1) % 2; // The result of count + 1 is the remainder of 2. + return count; + } + + DBStatus RemoveDeviceData(const std::string &device, const std::string &tableName) override + { + return DBStatus::OK; + } + + DBStatus RemoteQuery(const std::string &device, const RemoteCondition &condition, uint64_t timeout, + std::shared_ptr &result) override + { + if (device == "test") { + return DBStatus::DB_ERROR; + } + return DBStatus::OK; + } + + DBStatus RemoveDeviceData() override + { + return DBStatus::OK; + } + + DBStatus Sync(const std::vector &devices, DistributedDB::SyncMode mode, const Query &query, + const SyncProcessCallback &onProcess, int64_t waitTime) override + { + return DBStatus::OK; + } + + DBStatus SetCloudDB(const std::shared_ptr &cloudDb) override + { + return DBStatus::OK; + } + + DBStatus SetCloudDbSchema(const DataBaseSchema &schema) override + { + return DBStatus::OK; + } + + DBStatus RegisterObserver(StoreObserver *observer) override + { + return DBStatus::OK; + } + + DBStatus UnRegisterObserver() override + { + return DBStatus::OK; + } + + DBStatus UnRegisterObserver(StoreObserver *observer) override + { + return DBStatus::OK; + } + + DBStatus SetIAssetLoader(const std::shared_ptr &loader) override + { + return DBStatus::OK; + } + + DBStatus Sync(const CloudSyncOption &option, const SyncProcessCallback &onProcess) override + { + return DBStatus::OK; + } + + DBStatus SetTrackerTable(const TrackerSchema &schema) override + { + if (schema.tableName == "WITH_INVENTORY_DATA") { + return DBStatus::WITH_INVENTORY_DATA; + } + if (schema.tableName == "test") { + return DBStatus::DB_ERROR; + } + return DBStatus::OK; + } + + DBStatus ExecuteSql(const SqlCondition &condition, std::vector &records) override + { + if (condition.sql == "") { + return DBStatus::DB_ERROR; + } + + std::string sqls = "INSERT INTO test ( #flag, #float, #gid, #value) VALUES ( ?, ?, ?, ?)"; + std::string sqlIn = " UPDATE test SET setSql WHERE whereSql"; + std::string sql = "REPLACE INTO test ( #flag, #float, #gid, #value) VALUES ( ?, ?, ?, ?)"; + if (condition.sql == sqls || condition.sql == sqlIn || condition.sql == sql) { + return DBStatus::DB_ERROR; + } + return DBStatus::OK; + } + + DBStatus SetReference(const std::vector &tableReferenceProperty) override + { + if (g_testResult) { + return DBStatus::DB_ERROR; + } + return DBStatus::OK; + } + + DBStatus CleanTrackerData(const std::string &tableName, int64_t cursor) override + { + return DBStatus::OK; + } + + DBStatus Pragma(PragmaCmd cmd, PragmaData &pragmaData) override + { + return DBStatus::OK; + } + + DBStatus UpsertData(const std::string &tableName, const std::vector &records, + RecordStatus status = RecordStatus::WAIT_COMPENSATED_SYNC) override + { + return DBStatus::OK; + } + + DBStatus SetCloudSyncConfig(const CloudSyncConfig &config) override + { + return DBStatus::OK; + } + +protected: + DBStatus RemoveDeviceDataInner(const std::string &device, ClearMode mode) override + { + if (g_testResult) { + return DBStatus::DB_ERROR; + } + return DBStatus::OK; + } + + DBStatus CreateDistributedTableInner(const std::string &tableName, TableSyncType type) override + { + if (tableName == "test") { + return DBStatus::DB_ERROR; + } + return DBStatus::OK; + } +}; + +class MockQuery : public GenQuery { +public: + ~MockQuery() = default; + static constexpr uint64_t TYPE_ID = 0x20000001; + std::vector tables_; + bool lastResult = false; + bool IsEqual(uint64_t tid) override + { + return (tid == TYPE_ID) && lastResult; + } + + std::vector GetTables() override + { + return tables_; + } +}; + +class MockGeneralWatcher : public DistributedData::GeneralWatcher { +public: + int32_t OnChange(const Origin &origin, const PRIFields &primaryFields, ChangeInfo &&values) override + { + return GeneralError::E_OK; + } + + int32_t OnChange(const Origin &origin, const Fields &fields, ChangeData &&datas) override + { + return GeneralError::E_OK; + } +}; + +class MockStoreChangedData : public DistributedDB::StoreChangedData { +public: + std::string GetDataChangeDevice() const override + { + return "DataChangeDevice"; + } + void GetStoreProperty(DistributedDB::StoreProperty &storeProperty) const override + { + return; + } +}; + +/** +* @tc.name: BindSnapshots001 +* @tc.desc: RdbGeneralStore BindSnapshots test +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbGeneralStoreTest, BindSnapshots001, TestSize.Level1) +{ + auto store = new (std::nothrow) RdbGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + BindAssets bindAssets; + auto result = store->BindSnapshots(bindAssets.bindAssets); + EXPECT_EQ(result, GeneralError::E_OK); +} + +/** +* @tc.name: BindSnapshots002 +* @tc.desc: RdbGeneralStore BindSnapshots nullptr test +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbGeneralStoreTest, BindSnapshots002, TestSize.Level1) +{ + DistributedData::StoreMetaData meta; + meta = metaData_; + meta.isEncrypt = true; + auto store = new (std::nothrow) RdbGeneralStore(meta); + ASSERT_NE(store, nullptr); + store->snapshots_.bindAssets = nullptr; + BindAssets bindAssets; + auto result = store->BindSnapshots(bindAssets.bindAssets); + EXPECT_EQ(result, GeneralError::E_OK); +} + +/** +* @tc.name: Bind001 +* @tc.desc: RdbGeneralStore Bind bindInfo test +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbGeneralStoreTest, Bind001, TestSize.Level1) +{ + auto store = new (std::nothrow) RdbGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + DistributedData::Database database; + GeneralStore::CloudConfig config; + std::map bindInfos; + auto result = store->Bind(database, bindInfos, config); + EXPECT_TRUE(bindInfos.empty()); + EXPECT_EQ(result, GeneralError::E_OK); + + std::shared_ptr db; + std::shared_ptr loader; + GeneralStore::BindInfo bindInfo(db, loader); + EXPECT_EQ(bindInfo.db_, nullptr); + EXPECT_EQ(bindInfo.loader_, nullptr); + uint32_t key = 1; + bindInfos[key] = bindInfo; + result = store->Bind(database, bindInfos, config); + EXPECT_TRUE(!bindInfos.empty()); + EXPECT_EQ(result, GeneralError::E_INVALID_ARGS); + + std::shared_ptr dbs = std::make_shared(); + std::shared_ptr loaders = std::make_shared(); + GeneralStore::BindInfo bindInfo1(dbs, loader); + EXPECT_NE(bindInfo1.db_, nullptr); + bindInfos[key] = bindInfo1; + result = store->Bind(database, bindInfos, config); + EXPECT_TRUE(!bindInfos.empty()); + EXPECT_EQ(result, GeneralError::E_INVALID_ARGS); + + GeneralStore::BindInfo bindInfo2(db, loaders); + EXPECT_NE(bindInfo2.loader_, nullptr); + bindInfos[key] = bindInfo2; + result = store->Bind(database, bindInfos, config); + EXPECT_TRUE(!bindInfos.empty()); + EXPECT_EQ(result, GeneralError::E_INVALID_ARGS); +} + +/** +* @tc.name: Bind002 +* @tc.desc: RdbGeneralStore Bind delegate_ is nullptr test +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbGeneralStoreTest, Bind002, TestSize.Level1) +{ + auto store = new (std::nothrow) RdbGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + DistributedData::Database database; + std::map bindInfos; + + std::shared_ptr db = std::make_shared(); + std::shared_ptr loader = std::make_shared(); + GeneralStore::BindInfo bindInfo(db, loader); + uint32_t key = 1; + bindInfos[key] = bindInfo; + GeneralStore::CloudConfig config; + auto result = store->Bind(database, bindInfos, config); + EXPECT_EQ(store->delegate_, nullptr); + EXPECT_EQ(result, GeneralError::E_ALREADY_CLOSED); + + store->isBound_ = true; + result = store->Bind(database, bindInfos, config); + EXPECT_EQ(result, GeneralError::E_OK); +} + +/** +* @tc.name: Bind003 +* @tc.desc: RdbGeneralStore Bind delegate_ test +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbGeneralStoreTest, Bind003, TestSize.Level1) +{ + auto store = new (std::nothrow) RdbGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + DistributedData::Database database; + std::map bindInfos; + + std::shared_ptr db = std::make_shared(); + std::shared_ptr loader = std::make_shared(); + GeneralStore::BindInfo bindInfo(db, loader); + uint32_t key = 1; + bindInfos[key] = bindInfo; + MockRelationalStoreDelegate mockDelegate; + store->delegate_ = &mockDelegate; + GeneralStore::CloudConfig config; + auto result = store->Bind(database, bindInfos, config); + EXPECT_NE(store->delegate_, nullptr); + EXPECT_EQ(result, GeneralError::E_OK); +} + +/** +* @tc.name: Close +* @tc.desc: RdbGeneralStore Close and IsBound function test +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbGeneralStoreTest, Close, TestSize.Level1) +{ + auto store = new (std::nothrow) RdbGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + auto result = store->IsBound(); + EXPECT_EQ(result, false); + EXPECT_EQ(store->delegate_, nullptr); + auto ret = store->Close(); + EXPECT_EQ(ret, GeneralError::E_OK); + + MockRelationalStoreDelegate mockDelegate; + store->delegate_ = &mockDelegate; + ret = store->Close(); + EXPECT_EQ(ret, GeneralError::E_BUSY); +} + +/** +* @tc.name: Execute +* @tc.desc: RdbGeneralStore Execute function test +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbGeneralStoreTest, Execute, TestSize.Level1) +{ + auto store = new (std::nothrow) RdbGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + std::string table = "table"; + std::string sql = "sql"; + EXPECT_EQ(store->delegate_, nullptr); + auto result = store->Execute(table, sql); + EXPECT_EQ(result, GeneralError::E_ERROR); + + MockRelationalStoreDelegate mockDelegate; + store->delegate_ = &mockDelegate; + result = store->Execute(table, sql); + EXPECT_EQ(result, GeneralError::E_OK); + + std::string null = ""; + result = store->Execute(table, null); + EXPECT_EQ(result, GeneralError::E_ERROR); +} + +/** +* @tc.name: SqlConcatenate +* @tc.desc: RdbGeneralStore SqlConcatenate function test +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbGeneralStoreTest, SqlConcatenate, TestSize.Level1) +{ + auto store = new (std::nothrow) RdbGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + DistributedData::VBucket value; + std::string strColumnSql = "strColumnSql"; + std::string strRowValueSql = "strRowValueSql"; + auto result = store->SqlConcatenate(value, strColumnSql, strRowValueSql); + size_t columnSize = value.size(); + EXPECT_EQ(columnSize, 0); + EXPECT_EQ(result, columnSize); + + DistributedData::VBucket values = g_RdbVBucket; + result = store->SqlConcatenate(values, strColumnSql, strRowValueSql); + columnSize = values.size(); + EXPECT_NE(columnSize, 0); + EXPECT_EQ(result, columnSize); +} + +/** +* @tc.name: Insert001 +* @tc.desc: RdbGeneralStore Insert error test +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbGeneralStoreTest, Insert001, TestSize.Level1) +{ + auto store = new (std::nothrow) RdbGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + DistributedData::VBuckets values; + EXPECT_EQ(values.size(), 0); + std::string table = "table"; + auto result = store->Insert("", std::move(values)); + EXPECT_EQ(result, GeneralError::E_INVALID_ARGS); + result = store->Insert(table, std::move(values)); + EXPECT_EQ(result, GeneralError::E_INVALID_ARGS); + + DistributedData::VBuckets extends = { { { "#gid", { "0000000" } }, { "#flag", { true } }, + { "#value", { int64_t(100) } }, { "#float", { double(100) } } }, + { { "#gid", { "0000001" } } } }; + result = store->Insert("", std::move(extends)); + EXPECT_EQ(result, GeneralError::E_INVALID_ARGS); + + DistributedData::VBucket value; + DistributedData::VBuckets vbuckets = { value }; + result = store->Insert(table, std::move(vbuckets)); + EXPECT_EQ(result, GeneralError::E_INVALID_ARGS); + + result = store->Insert(table, std::move(extends)); + EXPECT_EQ(result, GeneralError::E_INVALID_ARGS); +} + +/** +* @tc.name: Insert002 +* @tc.desc: RdbGeneralStore Insert function test +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbGeneralStoreTest, Insert002, TestSize.Level1) +{ + auto store = new (std::nothrow) RdbGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + std::string table = "table"; + DistributedData::VBuckets extends = { { g_RdbVBucket } }; + auto result = store->Insert(table, std::move(extends)); + EXPECT_EQ(result, GeneralError::E_ERROR); + + MockRelationalStoreDelegate mockDelegate; + store->delegate_ = &mockDelegate; + result = store->Insert(table, std::move(extends)); + EXPECT_EQ(result, GeneralError::E_OK); + + std::string test = "test"; + result = store->Insert(test, std::move(extends)); + EXPECT_EQ(result, GeneralError::E_ERROR); + + result = store->Insert(test, std::move(extends)); + EXPECT_EQ(result, GeneralError::E_ERROR); + + for (size_t i = 0; i < PRINT_ERROR_CNT + 1; i++) { + result = store->Insert(test, std::move(extends)); + EXPECT_EQ(result, GeneralError::E_ERROR); + } +} + +/** +* @tc.name: Update +* @tc.desc: RdbGeneralStore Update function test +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbGeneralStoreTest, Update, TestSize.Level1) +{ + auto store = new (std::nothrow) RdbGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + std::string table = "table"; + std::string setSql = "setSql"; + RdbGeneralStore::Values values; + std::string whereSql = "whereSql"; + RdbGeneralStore::Values conditions; + auto result = store->Update("", setSql, std::move(values), whereSql, std::move(conditions)); + EXPECT_EQ(result, GeneralError::E_INVALID_ARGS); + + result = store->Update(table, "", std::move(values), whereSql, std::move(conditions)); + EXPECT_EQ(result, GeneralError::E_INVALID_ARGS); + + result = store->Update(table, setSql, std::move(values), whereSql, std::move(conditions)); + EXPECT_EQ(result, GeneralError::E_INVALID_ARGS); + + result = store->Update(table, setSql, std::move(g_RdbValues), "", std::move(conditions)); + EXPECT_EQ(result, GeneralError::E_INVALID_ARGS); + + result = store->Update(table, setSql, std::move(g_RdbValues), whereSql, std::move(conditions)); + EXPECT_EQ(result, GeneralError::E_INVALID_ARGS); + + result = store->Update(table, setSql, std::move(g_RdbValues), whereSql, std::move(g_RdbValues)); + EXPECT_EQ(result, GeneralError::E_ERROR); + + MockRelationalStoreDelegate mockDelegate; + store->delegate_ = &mockDelegate; + result = store->Update(table, setSql, std::move(g_RdbValues), whereSql, std::move(g_RdbValues)); + EXPECT_EQ(result, GeneralError::E_OK); + + result = store->Update("test", setSql, std::move(g_RdbValues), whereSql, std::move(g_RdbValues)); + EXPECT_EQ(result, GeneralError::E_ERROR); +} + +/** +* @tc.name: Replace +* @tc.desc: RdbGeneralStore Replace function test +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbGeneralStoreTest, Replace, TestSize.Level1) +{ + auto store = new (std::nothrow) RdbGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + std::string table = "table"; + RdbGeneralStore::VBucket values; + auto result = store->Replace("", std::move(g_RdbVBucket)); + EXPECT_EQ(result, GeneralError::E_INVALID_ARGS); + + result = store->Replace(table, std::move(values)); + EXPECT_EQ(result, GeneralError::E_INVALID_ARGS); + + result = store->Replace(table, std::move(g_RdbVBucket)); + EXPECT_EQ(result, GeneralError::E_ERROR); + + MockRelationalStoreDelegate mockDelegate; + store->delegate_ = &mockDelegate; + result = store->Replace(table, std::move(g_RdbVBucket)); + EXPECT_EQ(result, GeneralError::E_OK); + + result = store->Replace("test", std::move(g_RdbVBucket)); + EXPECT_EQ(result, GeneralError::E_ERROR); +} + +/** +* @tc.name: Delete +* @tc.desc: RdbGeneralStore Delete function test +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbGeneralStoreTest, Delete, TestSize.Level1) +{ + auto store = new (std::nothrow) RdbGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + std::string table = "table"; + std::string sql = "sql"; + auto result = store->Delete(table, sql, std::move(g_RdbValues)); + EXPECT_EQ(result, GeneralError::E_OK); +} + +/** +* @tc.name: Query001 +* @tc.desc: RdbGeneralStore Query function test +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbGeneralStoreTest, Query001, TestSize.Level1) +{ + auto store = new (std::nothrow) RdbGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + std::string table = "table"; + std::string sql = "sql"; + auto result = store->Query(table, sql, std::move(g_RdbValues)); + EXPECT_EQ(result, nullptr); + + MockRelationalStoreDelegate mockDelegate; + store->delegate_ = &mockDelegate; + result = store->Query(table, sql, std::move(g_RdbValues)); + EXPECT_NE(result, nullptr); +} + +/** +* @tc.name: Query002 +* @tc.desc: RdbGeneralStore Query function test +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbGeneralStoreTest, Query002, TestSize.Level1) +{ + auto store = new (std::nothrow) RdbGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + std::string table = "table"; + std::string sql = "sql"; + MockQuery query; + auto result = store->Query(table, query); + EXPECT_EQ(result, nullptr); + + query.lastResult = true; + result = store->Query(table, query); + EXPECT_EQ(result, nullptr); +} + +/** +* @tc.name: MergeMigratedData +* @tc.desc: RdbGeneralStore MergeMigratedData function test +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbGeneralStoreTest, MergeMigratedData, TestSize.Level1) +{ + auto store = new (std::nothrow) RdbGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + std::string tableName = "tableName"; + DistributedData::VBuckets extends = { { g_RdbVBucket } }; + auto result = store->MergeMigratedData(tableName, std::move(extends)); + EXPECT_EQ(result, GeneralError::E_ERROR); + + MockRelationalStoreDelegate mockDelegate; + store->delegate_ = &mockDelegate; + result = store->MergeMigratedData(tableName, std::move(extends)); + EXPECT_EQ(result, GeneralError::E_OK); +} + +/** +* @tc.name: Sync +* @tc.desc: RdbGeneralStore Sync function test +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbGeneralStoreTest, Sync, TestSize.Level1) +{ + auto store = new (std::nothrow) RdbGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + GeneralStore::Devices devices; + MockQuery query; + GeneralStore::DetailAsync async; + SyncParam syncParam; + auto result = store->Sync(devices, query, async, syncParam); + EXPECT_EQ(result, GeneralError::E_ALREADY_CLOSED); + + MockRelationalStoreDelegate mockDelegate; + store->delegate_ = &mockDelegate; + result = store->Sync(devices, query, async, syncParam); + EXPECT_EQ(result, GeneralError::E_OK); +} + +/** +* @tc.name: PreSharing +* @tc.desc: RdbGeneralStore PreSharing function test +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbGeneralStoreTest, PreSharing, TestSize.Level1) +{ + auto store = new (std::nothrow) RdbGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + MockQuery query; + auto result = store->PreSharing(query); + EXPECT_EQ(result, nullptr); +} + +/** +* @tc.name: ExtractExtend +* @tc.desc: RdbGeneralStore ExtractExtend function test +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbGeneralStoreTest, ExtractExtend, TestSize.Level1) +{ + auto store = new (std::nothrow) RdbGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + RdbGeneralStore::VBucket extend = { { "#gid", { "0000000" } }, { "#flag", { true } }, + { "#value", { int64_t(100) } }, { "#float", { double(100) } }, { "#cloud_gid", { "cloud_gid" } } }; + DistributedData::VBuckets extends = { { extend } }; + auto result = store->ExtractExtend(extends); + EXPECT_EQ(result.size(), extends.size()); + DistributedData::VBuckets values; + result = store->ExtractExtend(values); + EXPECT_EQ(result.size(), values.size()); +} + +/** +* @tc.name: Clean +* @tc.desc: RdbGeneralStore Clean function test +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbGeneralStoreTest, Clean, TestSize.Level1) +{ + auto store = new (std::nothrow) RdbGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + std::string tableName = "tableName"; + std::vector devices = { "device1", "device2" }; + auto result = store->Clean(devices, -1, tableName); + EXPECT_EQ(result, GeneralError::E_INVALID_ARGS); + result = store->Clean(devices, GeneralStore::CLEAN_MODE_BUTT + 1, tableName); + EXPECT_EQ(result, GeneralError::E_INVALID_ARGS); + result = store->Clean(devices, GeneralStore::CLOUD_INFO, tableName); + EXPECT_EQ(result, GeneralError::E_ALREADY_CLOSED); + + MockRelationalStoreDelegate mockDelegate; + store->delegate_ = &mockDelegate; + result = store->Clean(devices, GeneralStore::CLOUD_INFO, tableName); + EXPECT_EQ(result, GeneralError::E_OK); + result = store->Clean(devices, GeneralStore::CLOUD_DATA, tableName); + EXPECT_EQ(result, GeneralError::E_OK); + std::vector devices1; + result = store->Clean(devices1, GeneralStore::NEARBY_DATA, tableName); + EXPECT_EQ(result, GeneralError::E_OK); + + g_testResult = true; + result = store->Clean(devices, GeneralStore::CLOUD_INFO, tableName); + EXPECT_EQ(result, GeneralError::E_ERROR); + result = store->Clean(devices, GeneralStore::CLOUD_DATA, tableName); + EXPECT_EQ(result, GeneralError::E_ERROR); + result = store->Clean(devices, GeneralStore::CLEAN_MODE_BUTT, tableName); + EXPECT_EQ(result, GeneralError::E_ERROR); + result = store->Clean(devices, GeneralStore::NEARBY_DATA, tableName); + EXPECT_EQ(result, GeneralError::E_OK); +} + +/** +* @tc.name: Watch +* @tc.desc: RdbGeneralStore Watch and Unwatch function test +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbGeneralStoreTest, Watch, TestSize.Level1) +{ + auto store = new (std::nothrow) RdbGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + MockGeneralWatcher watcher; + auto result = store->Watch(GeneralWatcher::Origin::ORIGIN_CLOUD, watcher); + EXPECT_EQ(result, GeneralError::E_INVALID_ARGS); + result = store->Unwatch(GeneralWatcher::Origin::ORIGIN_CLOUD, watcher); + EXPECT_EQ(result, GeneralError::E_INVALID_ARGS); + + result = store->Watch(GeneralWatcher::Origin::ORIGIN_ALL, watcher); + EXPECT_EQ(result, GeneralError::E_OK); + result = store->Watch(GeneralWatcher::Origin::ORIGIN_ALL, watcher); + EXPECT_EQ(result, GeneralError::E_INVALID_ARGS); + + result = store->Unwatch(GeneralWatcher::Origin::ORIGIN_ALL, watcher); + EXPECT_EQ(result, GeneralError::E_OK); + result = store->Unwatch(GeneralWatcher::Origin::ORIGIN_ALL, watcher); + EXPECT_EQ(result, GeneralError::E_INVALID_ARGS); +} + +/** +* @tc.name: OnChange +* @tc.desc: RdbGeneralStore OnChange function test +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbGeneralStoreTest, OnChange, TestSize.Level1) +{ + auto store = new (std::nothrow) RdbGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + MockGeneralWatcher watcher; + MockStoreChangedData data; + DistributedDB::ChangedData changedData; + store->observer_.OnChange(data); + store->observer_.OnChange(DistributedDB::Origin::ORIGIN_CLOUD, "originalId", std::move(changedData)); + auto result = store->Watch(GeneralWatcher::Origin::ORIGIN_ALL, watcher); + EXPECT_EQ(result, GeneralError::E_OK); + store->observer_.OnChange(data); + store->observer_.OnChange(DistributedDB::Origin::ORIGIN_CLOUD, "originalId", std::move(changedData)); + result = store->Unwatch(GeneralWatcher::Origin::ORIGIN_ALL, watcher); + EXPECT_EQ(result, GeneralError::E_OK); +} + +/** +* @tc.name: Release +* @tc.desc: RdbGeneralStore Release function test +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbGeneralStoreTest, Release, TestSize.Level1) +{ + auto store = new (std::nothrow) RdbGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + auto result = store->Release(); + EXPECT_EQ(result, 0); + result = store->Release(); + EXPECT_EQ(result, 0); + store->ref_ = 2; + result = store->Release(); + EXPECT_EQ(result, 1); + + result = store->AddRef(); + EXPECT_EQ(result, 2); + store->ref_ = 0; + result = store->AddRef(); + EXPECT_EQ(result, 0); +} + +/** +* @tc.name: SetDistributedTables +* @tc.desc: RdbGeneralStore SetDistributedTables function test +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbGeneralStoreTest, SetDistributedTables, TestSize.Level1) +{ + auto store = new (std::nothrow) RdbGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + std::vector tables = { "table1", "table2" }; + int32_t type = 0; + std::vector references; + auto result = store->SetDistributedTables(tables, type, references); + EXPECT_EQ(result, GeneralError::E_ALREADY_CLOSED); + + MockRelationalStoreDelegate mockDelegate; + store->delegate_ = &mockDelegate; + result = store->SetDistributedTables(tables, type, references); + EXPECT_EQ(result, GeneralError::E_OK); + + std::vector test = { "test" }; + result = store->SetDistributedTables(test, type, references); + EXPECT_EQ(result, GeneralError::E_ERROR); + g_testResult = true; + result = store->SetDistributedTables(tables, type, references); + EXPECT_EQ(result, GeneralError::E_ERROR); +} + +/** +* @tc.name: SetTrackerTable +* @tc.desc: RdbGeneralStore SetTrackerTable function test +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbGeneralStoreTest, SetTrackerTable, TestSize.Level1) +{ + auto store = new (std::nothrow) RdbGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + std::string tableName = "tableName"; + std::set trackerColNames = { "col1", "col2" }; + std::string extendColName = "extendColName"; + auto result = store->SetTrackerTable(tableName, trackerColNames, extendColName); + EXPECT_EQ(result, GeneralError::E_ALREADY_CLOSED); + + MockRelationalStoreDelegate mockDelegate; + store->delegate_ = &mockDelegate; + result = store->SetTrackerTable(tableName, trackerColNames, extendColName); + EXPECT_EQ(result, GeneralError::E_OK); + result = store->SetTrackerTable("WITH_INVENTORY_DATA", trackerColNames, extendColName); + EXPECT_EQ(result, GeneralError::E_WITH_INVENTORY_DATA); + result = store->SetTrackerTable("test", trackerColNames, extendColName); + EXPECT_EQ(result, GeneralError::E_ERROR); +} + +/** +* @tc.name: RemoteQuery +* @tc.desc: RdbGeneralStore RemoteQuery function test +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbGeneralStoreTest, RemoteQuery, TestSize.Level1) +{ + auto store = new (std::nothrow) RdbGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + std::string device = "device"; + DistributedDB::RemoteCondition remoteCondition; + MockRelationalStoreDelegate mockDelegate; + store->delegate_ = &mockDelegate; + auto result = store->RemoteQuery("test", remoteCondition); + EXPECT_EQ(result, nullptr); + result = store->RemoteQuery(device, remoteCondition); + EXPECT_NE(result, nullptr); +} + +/** +* @tc.name: ConvertStatus +* @tc.desc: RdbGeneralStore ConvertStatus function test +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbGeneralStoreTest, ConvertStatus, TestSize.Level1) +{ + auto store = new (std::nothrow) RdbGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + auto result = store->ConvertStatus(DBStatus::OK); + EXPECT_EQ(result, GeneralError::E_OK); + result = store->ConvertStatus(DBStatus::CLOUD_NETWORK_ERROR); + EXPECT_EQ(result, GeneralError::E_NETWORK_ERROR); + result = store->ConvertStatus(DBStatus::CLOUD_LOCK_ERROR); + EXPECT_EQ(result, GeneralError::E_LOCKED_BY_OTHERS); + result = store->ConvertStatus(DBStatus::CLOUD_FULL_RECORDS); + EXPECT_EQ(result, GeneralError::E_RECODE_LIMIT_EXCEEDED); + result = store->ConvertStatus(DBStatus::CLOUD_ASSET_SPACE_INSUFFICIENT); + EXPECT_EQ(result, GeneralError::E_NO_SPACE_FOR_ASSET); + result = store->ConvertStatus(DBStatus::BUSY); + EXPECT_EQ(result, GeneralError::E_BUSY); + result = store->ConvertStatus(DBStatus::DB_ERROR); + EXPECT_EQ(result, GeneralError::E_ERROR); +} + +/** +* @tc.name: QuerySql +* @tc.desc: RdbGeneralStore QuerySql function test +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbGeneralStoreTest, QuerySql, TestSize.Level1) +{ + auto store = new (std::nothrow) RdbGeneralStore(metaData_); + ASSERT_NE(store, nullptr); + MockRelationalStoreDelegate mockDelegate; + store->delegate_ = &mockDelegate; + auto result = store->QuerySql("", std::move(g_RdbValues)); + EXPECT_TRUE(result.empty()); + result = store->QuerySql("sql", std::move(g_RdbValues)); + EXPECT_TRUE(result.empty()); +} +} // namespace DistributedRDBTest +} // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/rdb_query_test.cpp b/datamgr_service/services/distributeddataservice/service/test/rdb_query_test.cpp new file mode 100644 index 00000000..618f7dcf --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/rdb_query_test.cpp @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define LOG_TAG "RdbQueryTest" + +#include "gtest/gtest.h" +#include "log_print.h" +#include "rdb_query.h" +#include "utils/anonymous.h" +#include "value_proxy.h" + +using namespace testing::ext; +using namespace OHOS::DistributedData; +using namespace OHOS::DistributedRdb; + +namespace OHOS::Test { +namespace DistributedRDBTest { +class RdbQueryTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp(){}; + void TearDown(){}; +protected: +}; + +/** +* @tc.name: RdbQueryTest001 +* @tc.desc: RdbQuery function empty test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbQueryTest, RdbQueryTest001, TestSize.Level1) +{ + RdbQuery rdbQuery; + uint64_t tid = RdbQuery::TYPE_ID; + bool result = rdbQuery.IsEqual(tid); + EXPECT_TRUE(result); + std::vector tables = rdbQuery.GetTables(); + EXPECT_TRUE(tables.empty()); + std::string devices = "devices1"; + std::string sql = "SELECT * FROM table"; + Values args; + rdbQuery.MakeRemoteQuery(devices, sql, std::move(args)); + EXPECT_TRUE(rdbQuery.IsRemoteQuery()); + EXPECT_EQ(rdbQuery.GetDevices().size(), 1); + EXPECT_EQ(rdbQuery.GetDevices()[0], devices); + DistributedRdb::PredicatesMemo predicates; + rdbQuery.MakeQuery(predicates); + rdbQuery.MakeCloudQuery(predicates); + EXPECT_EQ(predicates.tables_.size(), 0); + EXPECT_TRUE(predicates.tables_.empty()); + EXPECT_EQ(predicates.operations_.size(), 0); +} + +/** +* @tc.name: RdbQueryTest002 +* @tc.desc: RdbQuery function test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbQueryTest, RdbQueryTest002, TestSize.Level1) +{ + RdbQuery rdbQuery; + std::string devices = "devices1"; + std::string sql = "SELECT * FROM table"; + Values args; + rdbQuery.MakeRemoteQuery(devices, sql, std::move(args)); + DistributedRdb::PredicatesMemo predicates; + predicates.tables_.push_back("table1"); + predicates.tables_.push_back("table2"); + predicates.devices_.push_back("device1"); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::EQUAL_TO, "name", "John Doe"); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::GREATER_THAN, "age", "30"); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::OPERATOR_MAX, "too", "99"); + rdbQuery.MakeQuery(predicates); + rdbQuery.MakeCloudQuery(predicates); + EXPECT_EQ(predicates.tables_.size(), 2); + EXPECT_TRUE(!predicates.tables_.empty()); + EXPECT_EQ(predicates.operations_.size(), 3); +} + +/** +* @tc.name: RdbQueryTest003 +* @tc.desc: RdbQuery function operation empty test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbQueryTest, RdbQueryTest003, TestSize.Level1) +{ + RdbQuery rdbQuery; + std::string devices = "devices1"; + std::string sql = "SELECT * FROM table"; + Values args; + rdbQuery.MakeRemoteQuery(devices, sql, std::move(args)); + DistributedRdb::PredicatesMemo predicates; + predicates.tables_.push_back("table1"); + predicates.tables_.push_back("table2"); + predicates.devices_.push_back("device1"); + std::vector values; + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::EQUAL_TO, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::NOT_EQUAL_TO, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::ORDER_BY, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::CONTAIN, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::BEGIN_WITH, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::END_WITH, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::LIKE, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::GLOB, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::BETWEEN, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::NOT_BETWEEN, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::GREATER_THAN, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::GREATER_THAN_OR_EQUAL, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::LESS_THAN, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::LESS_THAN_OR_EQUAL, "test", values); + rdbQuery.MakeQuery(predicates); + EXPECT_TRUE(values.empty()); + EXPECT_TRUE(values.size() != 2); +} + +/** +* @tc.name: RdbQueryTest004 +* @tc.desc: RdbQuery function operation test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbQueryTest, RdbQueryTest004, TestSize.Level1) +{ + RdbQuery rdbQuery; + std::string devices = "devices1"; + std::string sql = "SELECT * FROM table"; + Values args; + rdbQuery.MakeRemoteQuery(devices, sql, std::move(args)); + DistributedRdb::PredicatesMemo predicates; + predicates.tables_.push_back("table1"); + predicates.tables_.push_back("table2"); + predicates.devices_.push_back("device1"); + std::vector values = { "value1", "value2" }; + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::EQUAL_TO, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::NOT_EQUAL_TO, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::AND, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::OR, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::ORDER_BY, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::LIMIT, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::BEGIN_GROUP, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::END_GROUP, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::IN, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::NOT_IN, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::CONTAIN, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::BEGIN_WITH, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::END_WITH, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::IS_NULL, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::IS_NOT_NULL, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::LIKE, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::GLOB, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::BETWEEN, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::NOT_BETWEEN, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::GREATER_THAN, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::GREATER_THAN_OR_EQUAL, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::LESS_THAN, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::LESS_THAN_OR_EQUAL, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::DISTINCT, "test", values); + predicates.AddOperation(DistributedRdb::RdbPredicateOperator::INDEXED_BY, "test", values); + rdbQuery.MakeQuery(predicates); + EXPECT_TRUE(!values.empty()); + EXPECT_FALSE(values.size() != 2); +} +} // namespace DistributedRDBTest +} // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/rdb_result_set_impl_test.cpp b/datamgr_service/services/distributeddataservice/service/test/rdb_result_set_impl_test.cpp index 1e6f9036..3275efb5 100644 --- a/datamgr_service/services/distributeddataservice/service/test/rdb_result_set_impl_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/rdb_result_set_impl_test.cpp @@ -209,5 +209,98 @@ HWTEST_F(RdbResultSetImplTest, RdbResultSetImplGet, TestSize.Level0) resultSet->IsEnded(result); } } + +/** +* @tc.name: RdbResultSetImpl001 +* @tc.desc: RdbResultSetImpl function test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbResultSetImplTest, RdbResultSetImpl001, TestSize.Level0) +{ + std::vector names; + EXPECT_EQ(resultSet->GetAllColumnNames(names), NativeRdb::E_OK); + int count = 0; + EXPECT_EQ(resultSet->GetColumnCount(count), NativeRdb::E_OK); + std::string columnName = "columnName"; + int columnIndex = 0; + EXPECT_EQ(resultSet->GetColumnIndex(columnName, columnIndex), NativeRdb::E_ERROR); + EXPECT_EQ(resultSet->GetColumnIndex(names[1], columnIndex), NativeRdb::E_OK); + EXPECT_EQ(resultSet->GetColumnName(columnIndex, columnName), NativeRdb::E_OK); + columnIndex = 10; // 10 > colNames_.size() + EXPECT_EQ(resultSet->GetColumnName(columnIndex, columnName), NativeRdb::E_ERROR); + EXPECT_EQ(resultSet->GetColumnName(-1, columnName), NativeRdb::E_ERROR); + bool result = false; + EXPECT_EQ(resultSet->IsAtFirstRow(result), NativeRdb::E_OK); + EXPECT_EQ(resultSet->IsAtLastRow(result), NativeRdb::E_OK); + int value = 1; + EXPECT_EQ(resultSet->GetInt(value, value), NativeRdb::E_OK); + EXPECT_EQ(resultSet->IsColumnNull(value, result), NativeRdb::E_OK); + int32_t col = 1; + NativeRdb::ValueObject::Asset asset; + NativeRdb::ValueObject::Assets assets; + EXPECT_EQ(resultSet->GetAsset(col, asset), NativeRdb::E_OK); + EXPECT_EQ(resultSet->GetAssets(col, assets), NativeRdb::E_OK); + NativeRdb::ValueObject::FloatVector vecs; + size_t size = 0; + EXPECT_EQ(resultSet->GetFloat32Array(col, vecs), NativeRdb::E_NOT_SUPPORT); + EXPECT_EQ(resultSet->GetSize(col, size), NativeRdb::E_OK); + EXPECT_FALSE(resultSet->IsClosed()); + EXPECT_EQ(resultSet->Close(), NativeRdb::E_OK); +} + +/** +* @tc.name: RdbResultSetImpl002 +* @tc.desc: RdbResultSetImpl function error test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbResultSetImplTest, RdbResultSetImpl002, TestSize.Level0) +{ + auto cursorMock = std::make_shared(cursor); + cursorMock = nullptr; + std::shared_ptr result = std::make_shared(cursorMock); + std::vector columnNames; + int columnIndex = 0; + RdbResultSetImpl::ColumnType columnType; + std::string columnName = "columnName"; + bool ret = false; + std::vector value; + int64_t value1 = 0; + double value2 = 0.0; + int32_t col = 0; + NativeRdb::ValueObject::Asset asset; + NativeRdb::ValueObject::Assets assets; + NativeRdb::ValueObject::FloatVector vecs; + NativeRdb::ValueObject valueObject; + size_t size = 0; + EXPECT_EQ(result->GetAllColumnNames(columnNames), NativeRdb::E_ALREADY_CLOSED); + EXPECT_EQ(result->GetColumnCount(columnIndex), NativeRdb::E_ALREADY_CLOSED); + EXPECT_EQ(result->GetColumnType(columnIndex, columnType), NativeRdb::E_ALREADY_CLOSED); + EXPECT_EQ(result->GetColumnIndex(columnName, columnIndex), NativeRdb::E_ALREADY_CLOSED); + EXPECT_EQ(result->GetColumnName(columnIndex, columnName), NativeRdb::E_ALREADY_CLOSED); + EXPECT_EQ(result->GetRowCount(columnIndex), NativeRdb::E_ALREADY_CLOSED); + EXPECT_EQ(result->GetRowIndex(columnIndex), NativeRdb::E_ALREADY_CLOSED); + EXPECT_EQ(result->GoToFirstRow(), NativeRdb::E_ALREADY_CLOSED); + EXPECT_EQ(result->GoToNextRow(), NativeRdb::E_ALREADY_CLOSED); + EXPECT_EQ(result->GoToPreviousRow(), NativeRdb::E_ALREADY_CLOSED); + EXPECT_EQ(result->IsEnded(ret), NativeRdb::E_ALREADY_CLOSED); + EXPECT_EQ(result->IsStarted(ret), NativeRdb::E_ALREADY_CLOSED); + EXPECT_EQ(result->IsAtFirstRow(ret), NativeRdb::E_ALREADY_CLOSED); + EXPECT_EQ(result->IsAtLastRow(ret), NativeRdb::E_ALREADY_CLOSED); + EXPECT_EQ(result->GetBlob(columnIndex, value), NativeRdb::E_ALREADY_CLOSED); + EXPECT_EQ(result->GetString(columnIndex, columnName), NativeRdb::E_ALREADY_CLOSED); + EXPECT_EQ(result->GetLong(columnIndex, value1), NativeRdb::E_ALREADY_CLOSED); + EXPECT_EQ(result->GetDouble(columnIndex, value2), NativeRdb::E_ALREADY_CLOSED); + EXPECT_EQ(result->IsColumnNull(columnIndex, ret), NativeRdb::E_ALREADY_CLOSED); + EXPECT_EQ(result->Close(), NativeRdb::E_OK); + EXPECT_EQ(result->GetAsset(col, asset), NativeRdb::E_ALREADY_CLOSED); + EXPECT_EQ(result->GetAssets(col, assets), NativeRdb::E_ALREADY_CLOSED); + EXPECT_EQ(result->GetFloat32Array(col, vecs), NativeRdb::E_ALREADY_CLOSED); + EXPECT_EQ(result->Get(col, valueObject), NativeRdb::E_ALREADY_CLOSED); + EXPECT_EQ(result->GetSize(col, size), NativeRdb::E_ALREADY_CLOSED); +} } // namespace DistributedRDBTest } // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/rdb_result_set_stub_test.cpp b/datamgr_service/services/distributeddataservice/service/test/rdb_result_set_stub_test.cpp new file mode 100644 index 00000000..981ca6ed --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/rdb_result_set_stub_test.cpp @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define LOG_TAG "RdbResultSetStubTest" + +#include "gtest/gtest.h" +#include "log_print.h" +#include "message_parcel.h" +#include "rdb_result_set_impl.h" +#include "rdb_result_set_stub.h" +#include "store/cursor.h" +#include "securec.h" + +using namespace testing::ext; +using namespace OHOS; +using namespace OHOS::DistributedRdb; +using namespace OHOS::DistributedData; +const std::u16string INTERFACE_TOKEN = u"OHOS::NativeRdb.IResultSet"; +namespace OHOS::Test { +namespace DistributedRDBTest { +class RdbResultSetStubTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp(){}; + void TearDown(){}; +protected: +}; + +/** +* @tc.name: OnRemoteRequest001 +* @tc.desc: RdbResultSetStub OnRemoteRequest function error test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbResultSetStubTest, OnRemoteRequest001, TestSize.Level1) +{ + std::shared_ptr dbResultSet; + auto result = std::make_shared(dbResultSet); + MessageParcel request1; + MessageParcel reply1; + MessageOption option1; + std::shared_ptr rdbResultSetStub1 = std::make_shared(result); + auto ret = rdbResultSetStub1->OnRemoteRequest(RdbResultSetStub::Code::CMD_GET_ALL_COLUMN_NAMES, + request1, reply1, option1); + EXPECT_EQ(ret, -1); + + result = nullptr; + uint8_t value = 1; + uint8_t *data = &value; + size_t size = 1; + MessageParcel request2; + request2.WriteInterfaceToken(INTERFACE_TOKEN); + request2.WriteBuffer(data, size); + request2.RewindRead(0); + MessageParcel reply2; + MessageOption option2; + std::shared_ptr rdbResultSetStub2 = std::make_shared(result); + ret = rdbResultSetStub2->OnRemoteRequest(RdbResultSetStub::Code::CMD_GET_ALL_COLUMN_NAMES, + request2, reply2, option2); + EXPECT_EQ(ret, -1); + + MessageParcel request3; + MessageParcel reply3; + MessageOption option3; + std::shared_ptr rdbResultSetStub3 = std::make_shared(result); + ret = rdbResultSetStub3->OnRemoteRequest(RdbResultSetStub::Code::CMD_GET_ALL_COLUMN_NAMES, + request3, reply3, option3); + EXPECT_EQ(ret, -1); +} + +/** +* @tc.name: OnRemoteRequest002 +* @tc.desc: RdbResultSetStub OnRemoteRequest function error test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbResultSetStubTest, OnRemoteRequest002, TestSize.Level1) +{ + std::shared_ptr dbResultSet; + auto result = std::make_shared(dbResultSet); + std::shared_ptr rdbResultSetStub = std::make_shared(result); + uint8_t value = 1; + uint8_t *data = &value; + size_t size = 1; + MessageParcel request1; + request1.WriteInterfaceToken(INTERFACE_TOKEN); + request1.WriteBuffer(data, size); + request1.RewindRead(0); + MessageParcel reply1; + MessageOption option1; + uint32_t code = -1; + auto ret = rdbResultSetStub->OnRemoteRequest(code, request1, reply1, option1); + EXPECT_GT(ret, 0); + + code = 20; // invalid code > Code::CMD_MAX + MessageParcel request2; + request2.WriteInterfaceToken(INTERFACE_TOKEN); + request2.WriteBuffer(data, size); + request2.RewindRead(0); + MessageParcel reply2; + MessageOption option2; + ret = rdbResultSetStub->OnRemoteRequest(code, request2, reply2, option2); + EXPECT_GT(ret, 0); +} + +/** +* @tc.name: RdbResultSetStub +* @tc.desc: RdbResultSetStub function test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbResultSetStubTest, RdbResultSetStub, TestSize.Level1) +{ + std::shared_ptr dbResultSet; + auto result = std::make_shared(dbResultSet); + std::shared_ptr rdbResultSetStub = std::make_shared(result); + for (uint32_t i = RdbResultSetStub::Code::CMD_GET_ALL_COLUMN_NAMES; i < RdbResultSetStub::Code::CMD_MAX; ++i) + { + RdbResultSetStub::Code code = static_cast(i); + uint8_t value = 1; + uint8_t *data = &value; + size_t size = 1; + MessageParcel request; + request.WriteInterfaceToken(INTERFACE_TOKEN); + request.WriteBuffer(data, size); + request.RewindRead(0); + MessageParcel reply; + MessageOption option; + auto ret = rdbResultSetStub->OnRemoteRequest(code, request, reply, option); + EXPECT_EQ(ret, 0); + } +} +} // namespace DistributedRDBTest +} // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp b/datamgr_service/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp index f4d38184..d625d654 100644 --- a/datamgr_service/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/udmf_run_time_store_test.cpp @@ -25,10 +25,12 @@ #include "kvstore_meta_manager.h" #include "metadata/meta_data_manager.h" #include "nativetoken_kit.h" +#include "text.h" #include "token_setproc.h" #define private public #include "store/runtime_store.h" #undef private + using namespace testing::ext; using namespace OHOS::DistributedData; using namespace OHOS::Security::AccessToken; @@ -37,31 +39,34 @@ using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; using Entry = DistributedDB::Entry; using Key = DistributedDB::Key; using Value = DistributedDB::Value; - +using UnifiedData = OHOS::UDMF::UnifiedData; +using Summary = OHOS::UDMF::Summary; namespace OHOS::Test { namespace DistributedDataTest { + +static void GrantPermissionNative() +{ + const char **perms = new const char *[2]; + perms[0] = "ohos.permission.DISTRIBUTED_DATASYNC"; + perms[1] = "ohos.permission.ACCESS_SERVICE_DM"; + TokenInfoParams infoInstance = { + .dcapsNum = 0, + .permsNum = 2, + .aclsNum = 0, + .dcaps = nullptr, + .perms = perms, + .acls = nullptr, + .processName = "distributed_data_test", + .aplStr = "system_basic", + }; + uint64_t tokenId = GetAccessTokenId(&infoInstance); + SetSelfTokenID(tokenId); + AccessTokenKit::ReloadNativeTokenInfo(); + delete[] perms; +} + class UdmfRunTimeStoreTest : public testing::Test { public: - static void GrantPermissionNative() - { - const char **perms = new const char *[2]; - perms[0] = "ohos.permission.DISTRIBUTED_DATASYNC"; - perms[1] = "ohos.permission.ACCESS_SERVICE_DM"; - TokenInfoParams infoInstance = { - .dcapsNum = 0, - .permsNum = 2, - .aclsNum = 0, - .dcaps = nullptr, - .perms = perms, - .acls = nullptr, - .processName = "distributed_data_test", - .aplStr = "system_basic", - }; - uint64_t tokenId = GetAccessTokenId(&infoInstance); - SetSelfTokenID(tokenId); - AccessTokenKit::ReloadNativeTokenInfo(); - delete[] perms; - } static void SetUpTestCase(void) { GrantPermissionNative(); @@ -86,6 +91,8 @@ public: const uint32_t MAX_VALUE_SIZE = 4 * 1024 * 1024; const std::string STORE_ID = "drag"; const std::string KEY_PREFIX = "TEST_"; + const std::string EMPTY_DEVICE_ID = ""; + static constexpr size_t tempUdataRecordSize = 1; }; void UdmfRunTimeStoreTest::GetRandomKey(std::vector& key, uint32_t defaultSize) @@ -320,5 +327,227 @@ HWTEST_F(UdmfRunTimeStoreTest, DeleteEntries001, TestSize.Level1) EXPECT_EQ(E_OK, status); EXPECT_EQ(0, entries.size()); } + +/** +* @tc.name: DeleteEntries002 +* @tc.desc: check for illegal parameters, delete entries error. +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(UdmfRunTimeStoreTest, DeleteEntries002, TestSize.Level1) +{ + auto store = std::make_shared(STORE_ID); + bool result = store->Init(); + EXPECT_TRUE(result); + Key key; + Value value; + GetRandomKey(key, MAX_KEY_SIZE); // 1K + GetRandomValue(value, MAX_VALUE_SIZE); // 4M + vector entrysRand(127, { key, value }); + vector keys(3970); + Value emptyValue; + for (int i = 0; i < 3970; ++i) { + GetRandomKey(keys[i], 3970); + entrysRand.push_back({ keys[i], emptyValue }); + } + + int32_t status = store->PutEntries(entrysRand); + EXPECT_EQ(E_DB_ERROR, status); + + vector entries; + status = store->GetEntries(KEY_PREFIX, entries); + EXPECT_EQ(E_OK, status); + EXPECT_EQ(0, entries.size()); + + status = store->DeleteEntries(keys); + EXPECT_EQ(E_DB_ERROR, status); + + entries.clear(); + status = store->GetEntries(KEY_PREFIX, entries); + EXPECT_EQ(E_OK, status); + EXPECT_EQ(0, entries.size()); +} + +/** +* @tc.name: Init +* @tc.desc: check for illegal parameters, delete entries error. +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(UdmfRunTimeStoreTest, Init, TestSize.Level1) +{ + auto dvInfo = DeviceManagerAdapter::GetInstance().GetLocalDevice(); + auto uuid = DeviceManagerAdapter::GetInstance().GetUuidByNetworkId(EMPTY_DEVICE_ID); + EXPECT_TRUE(uuid.empty()); + dvInfo.uuid = EMPTY_DEVICE_ID; + auto store = std::make_shared(STORE_ID); + bool result = store->Init(); + EXPECT_TRUE(result); +} + +/** +* @tc.name: Get001 +* @tc.desc: check for illegal parameters, delete entries error. +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(UdmfRunTimeStoreTest, Get001, TestSize.Level1) +{ + auto store = std::make_shared(STORE_ID); + bool result = store->Init(); + EXPECT_TRUE(result); + + Key key; + Key keyInvalid; + Value value; + Value valueInvalid; + GetRandomKey(key, MAX_KEY_SIZE); // 1K + GetRandomKey(keyInvalid, MAX_KEY_SIZE + 1); // 1K + 1 + GetRandomValue(value, MAX_VALUE_SIZE); // 4M + GetRandomValue(valueInvalid, MAX_VALUE_SIZE + 1); // 4M + 1 + vector entrysMix1(1, { keyInvalid, value }); + vector entrysMix2(1, { key, valueInvalid }); + UnifiedData unifiedData; + int32_t status = store->PutEntries(entrysMix1); + EXPECT_EQ(E_DB_ERROR, status); + status = store->GetEntries(KEY_PREFIX, entrysMix1); + EXPECT_EQ(E_OK, status); + + status = store->Get(KEY_PREFIX, unifiedData); + EXPECT_EQ(E_NOT_FOUND, status); +} + +/** +* @tc.name: Get002 +* @tc.desc: check for legal parameters, delete entries error. +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(UdmfRunTimeStoreTest, Get002, TestSize.Level1) +{ + auto store = std::make_shared(STORE_ID); + bool result = store->Init(); + EXPECT_TRUE(result); + + Key key; + Value value; + GetRandomKey(key, MAX_KEY_SIZE); // 1K + GetRandomValue(value, MAX_VALUE_SIZE); // 4M + vector entrysRand(127, { key, value }); + Value emptyValue; + for (int i = 0; i < 3970; i++) { + entrysRand.push_back({ key, emptyValue }); + } + auto status = store->PutEntries(entrysRand); + EXPECT_EQ(E_DB_ERROR, status); + status = store->GetEntries(EMPTY_DEVICE_ID, entrysRand); + EXPECT_EQ(E_OK, status); + UnifiedData data1; + status = store->Get(EMPTY_DEVICE_ID, data1); + EXPECT_EQ(E_NOT_FOUND, status); +} + +/** +* @tc.name: GetDetailsFromUData +* @tc.desc: check for legal parameters, delete entries error. +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(UdmfRunTimeStoreTest, GetDetailsFromUData, TestSize.Level1) +{ + auto store = std::make_shared(STORE_ID); + bool result = store->Init(); + EXPECT_TRUE(result); + + Key key; + Value value; + GetRandomValue(value, MAX_KEY_SIZE); // 1K + vector entrysRand; + for (int i = 0; i < 129; ++i) { + GetRandomKey(key, MAX_KEY_SIZE); // 1K + entrysRand.push_back({ key, value }); + } + + int32_t status = store->PutEntries(entrysRand); + EXPECT_EQ(E_OK, status); + vector entries; + status = store->GetEntries(KEY_PREFIX, entries); + EXPECT_EQ(E_OK, status); + EXPECT_EQ(129, entries.size()); + UnifiedData data1; + UDDetails details1; + details1.insert({ "udmf_key", "udmf_value" }); + auto records = data1.GetRecords(); + EXPECT_EQ(records.size(), 0); + status = store->GetDetailsFromUData(data1, details1); + EXPECT_FALSE(status); +} + +/** +* @tc.name: GetDetailsFromUData01 +* @tc.desc: check for legal parameters, delete entries error. +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(UdmfRunTimeStoreTest, GetDetailsFromUData01, TestSize.Level1) +{ + auto store = std::make_shared(STORE_ID); + bool result = store->Init(); + EXPECT_TRUE(result); + + Key key; + Value value; + GetRandomValue(value, MAX_KEY_SIZE); // 1K + vector entrysRand; + for (int i = 0; i < 129; ++i) { + GetRandomKey(key, MAX_KEY_SIZE); // 1K + entrysRand.push_back({ key, value }); + } + + int32_t status = store->PutEntries(entrysRand); + EXPECT_EQ(E_OK, status); + vector entries; + status = store->GetEntries(KEY_PREFIX, entries); + EXPECT_EQ(E_OK, status); + UDDetails details1; + details1.insert({ "udmf_key", "udmf_value" }); + UnifiedData inputData; + std::vector> inputRecords; + for (int32_t i = 0; i < 512; ++i) { + inputRecords.emplace_back(std::make_shared()); + } + inputData.SetRecords(inputRecords); + UnifiedData outputData; + auto outputRecords = outputData.GetRecords(); + ASSERT_EQ(inputRecords.size(), 512); + ASSERT_EQ(0, outputRecords.size()); + status = store->GetDetailsFromUData(inputData, details1); + EXPECT_FALSE(status); +} + +/** +* @tc.name: GetSummary +* @tc.desc: check for legal parameters, delete entries error. +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(UdmfRunTimeStoreTest, GetSummary, TestSize.Level1) +{ + auto store = std::make_shared(STORE_ID); + bool result = store->Init(); + EXPECT_TRUE(result); + + UnifiedData data; + UDDetails details; + details.insert({ "udmf_key", "udmf_value" }); + Text text; + text.SetDetails(details); + std::shared_ptr record1 = std::make_shared(text); + data.AddRecord(record1); + + Summary summary; + auto status = store->GetSummary(KEY_PREFIX, summary); + ASSERT_EQ(status, E_DB_ERROR); +} }; // namespace DistributedDataTest }; // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/water_version_manager_test.cpp b/datamgr_service/services/distributeddataservice/service/test/water_version_manager_test.cpp index 1a8a0163..d520a57b 100644 --- a/datamgr_service/services/distributeddataservice/service/test/water_version_manager_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/water_version_manager_test.cpp @@ -21,7 +21,9 @@ #include "device_manager_adapter.h" #include "executor_pool.h" #include "gtest/gtest.h" +#include "metadata/matrix_meta_data.h" #include "metadata/meta_data_manager.h" +#include "mock/checker_mock.h" #include "mock/db_store_mock.h" #include "nativetoken_kit.h" #include "serializable/serializable.h" @@ -37,9 +39,10 @@ using WaterVersionMetaData = WvManager::WaterVersionMetaData; namespace OHOS::Test { namespace DistributedDataTest { -class TestChecker; -static std::vector> stores_ = { { "bundle0", "store0" }, { "bundle1", "store0" }, - { "bundle2", "store0" } }; +static std::vector> staticStores_ = { { "bundle0", "store0" }, + { "bundle1", "store0" }, { "bundle2", "store0" } }; +static std::vector> dynamicStores_ = { { "bundle0", "store1" }, + { "bundle3", "store0" }, { "bundle4", "store0" } }; class WaterVersionManagerTest : public testing::Test { public: static void SetUpTestCase(void); @@ -55,7 +58,7 @@ protected: static std::shared_ptr dbStoreMock_; static WaterVersionMetaData dynamicMeta_; static WaterVersionMetaData staticMeta_; - static TestChecker instance_; + static CheckerMock instance_; }; void WaterVersionManagerTest::GrantPermissionNative() @@ -78,93 +81,7 @@ void WaterVersionManagerTest::GrantPermissionNative() AccessTokenKit::ReloadNativeTokenInfo(); delete[] perms; } - -class TestChecker : public CheckerManager::Checker { -public: - TestChecker() noexcept - { - CheckerManager::GetInstance().RegisterPlugin( - "SystemChecker", [this]() -> auto { return this; }); - } - ~TestChecker() {} - void Initialize() override - { - staticInfos_.clear(); - dynamicInfos_.clear(); - for (auto &it : stores_) { - staticInfos_.push_back({ 0, 0, it.first, it.second }); - dynamicInfos_.push_back({ 0, 0, it.first, it.second }); - } - } - bool SetTrustInfo(const CheckerManager::Trust &trust) override - { - return true; - } - std::string GetAppId(const CheckerManager::StoreInfo &info) override - { - return info.bundleName; - } - bool IsValid(const CheckerManager::StoreInfo &info) override - { - return true; - } - bool SetDistrustInfo(const CheckerManager::Distrust &distrust) override - { - return true; - }; - - bool IsDistrust(const CheckerManager::StoreInfo &info) override - { - return true; - } - vector GetDynamicStores() override - { - return dynamicInfos_; - } - vector GetStaticStores() override - { - return staticInfos_; - } - bool IsDynamic(const CheckerManager::StoreInfo &info) override - { - for (const auto &store : dynamicInfos_) { - if (info.bundleName == store.bundleName && info.storeId == store.storeId) { - return true; - } - } - return false; - } - bool IsStatic(const CheckerManager::StoreInfo &info) override - { - for (const auto &store : staticInfos_) { - if (info.bundleName == store.bundleName && info.storeId == store.storeId) { - return true; - } - } - return false; - } - bool AddDynamicStore(const CheckerManager::StoreInfo &storeInfo) override - { - return false; - } - bool AddStaticStore(const CheckerManager::StoreInfo &storeInfo) override - { - return false; - } - bool IsSwitches(const CheckerManager::StoreInfo &info) override - { - return false; - } - bool SetSwitchesInfo(const CheckerManager::Switches &switches) override - { - return true; - } - -private: - vector dynamicInfos_; - vector staticInfos_; -}; -TestChecker WaterVersionManagerTest::instance_; +CheckerMock WaterVersionManagerTest::instance_; std::shared_ptr WaterVersionManagerTest::dbStoreMock_ = std::make_shared(); WaterVersionMetaData WaterVersionManagerTest::staticMeta_; WaterVersionMetaData WaterVersionManagerTest::dynamicMeta_; @@ -175,6 +92,17 @@ void WaterVersionManagerTest::SetUpTestCase(void) DeviceManagerAdapter::GetInstance().Init(std::make_shared(max, min)); GrantPermissionNative(); Bootstrap::GetInstance().LoadCheckers(); + std::vector dynamicStores; + for (auto &[bundle, store] : dynamicStores_) { + dynamicStores.push_back({ 0, 0, bundle, store }); + instance_.SetDynamic(dynamicStores); + } + std::vector staticStores; + for (auto &[bundle, store] : staticStores_) { + staticStores.push_back({ 0, 0, bundle, store }); + instance_.SetStatic(staticStores); + } + WaterVersionManager::GetInstance().Init(); MetaDataManager::GetInstance().Initialize(dbStoreMock_, nullptr); staticMeta_.deviceId = TEST_DEVICE; @@ -182,11 +110,16 @@ void WaterVersionManagerTest::SetUpTestCase(void) staticMeta_.waterVersion = 0; staticMeta_.type = WvManager::STATIC; staticMeta_.keys.clear(); - for (auto &it : stores_) { + for (auto &it : staticStores_) { staticMeta_.keys.push_back(Constant::Join(it.first, Constant::KEY_SEPARATOR, { it.second })); } staticMeta_.infos = { staticMeta_.keys.size(), std::vector(staticMeta_.keys.size(), 0) }; dynamicMeta_ = staticMeta_; + dynamicMeta_.keys.clear(); + for (auto &it : dynamicStores_) { + dynamicMeta_.keys.push_back(Constant::Join(it.first, Constant::KEY_SEPARATOR, { it.second })); + } + dynamicMeta_.infos = { dynamicMeta_.keys.size(), std::vector(dynamicMeta_.keys.size(), 0) }; dynamicMeta_.type = WvManager::DYNAMIC; } @@ -203,6 +136,9 @@ void WaterVersionManagerTest::TearDown() WvManager::GetInstance().DelWaterVersion(DMAdapter::GetInstance().GetLocalDevice().uuid); MetaDataManager::GetInstance().DelMeta(staticMeta_.GetKey(), true); MetaDataManager::GetInstance().DelMeta(dynamicMeta_.GetKey(), true); + MatrixMetaData matrixMetaData; + matrixMetaData.deviceId = DMAdapter::GetInstance().GetLocalDevice().uuid; + MetaDataManager::GetInstance().DelMeta(matrixMetaData.GetKey(), true); } void WaterVersionManagerTest::InitMetaData() @@ -227,8 +163,8 @@ HWTEST_F(WaterVersionManagerTest, SetWaterVersionTest1, TestSize.Level0) meta.infos[0] = { 1, 0, 0 }; meta.waterVersion = 1; - EXPECT_TRUE( - WvManager::GetInstance().SetWaterVersion(stores_[0].first, stores_[0].second, Serializable::Marshall(meta))) + EXPECT_TRUE(WvManager::GetInstance().SetWaterVersion(staticStores_[0].first, staticStores_[0].second, + Serializable::Marshall(meta))) << Serializable::Marshall(meta); waterVersion = WvManager::GetInstance().GetWaterVersion(TEST_DEVICE, WvManager::STATIC); @@ -236,6 +172,12 @@ HWTEST_F(WaterVersionManagerTest, SetWaterVersionTest1, TestSize.Level0) auto [success, version] = WvManager::GetInstance().GetVersion(TEST_DEVICE, WvManager::STATIC); EXPECT_TRUE(success && version == 1) << "success:" << success << " version:" << version << " meta: " << meta.ToAnonymousString(); + + // update to matrixMeta + MatrixMetaData matrixMetaData; + matrixMetaData.deviceId = TEST_DEVICE; + EXPECT_TRUE(MetaDataManager::GetInstance().LoadMeta(matrixMetaData.GetConsistentKey(), matrixMetaData, true)); + EXPECT_EQ(matrixMetaData.statics, version << 4); } /** @@ -254,18 +196,24 @@ HWTEST_F(WaterVersionManagerTest, SetWaterVersionTest2, TestSize.Level0) // first store update meta.infos[0] = { 1, 0, 0 }; meta.waterVersion = 1; - EXPECT_TRUE( - WvManager::GetInstance().SetWaterVersion(stores_[0].first, stores_[0].second, Serializable::Marshall(meta))); + EXPECT_TRUE(WvManager::GetInstance().SetWaterVersion(staticStores_[0].first, staticStores_[0].second, + Serializable::Marshall(meta))); auto [_, version] = WvManager::GetInstance().GetVersion(TEST_DEVICE, WvManager::STATIC); EXPECT_EQ(version, 1); // second store update meta.infos[1] = { 1, 2, 0 }; meta.waterVersion = 2; - EXPECT_TRUE( - WvManager::GetInstance().SetWaterVersion(stores_[1].first, stores_[1].second, Serializable::Marshall(meta))); + EXPECT_TRUE(WvManager::GetInstance().SetWaterVersion(staticStores_[1].first, staticStores_[1].second, + Serializable::Marshall(meta))); std::tie(_, version) = WvManager::GetInstance().GetVersion(TEST_DEVICE, WvManager::STATIC); EXPECT_EQ(version, 2); + + // update to matrixMeta + MatrixMetaData matrixMetaData; + matrixMetaData.deviceId = TEST_DEVICE; + EXPECT_TRUE(MetaDataManager::GetInstance().LoadMeta(matrixMetaData.GetConsistentKey(), matrixMetaData, true)); + EXPECT_EQ(matrixMetaData.statics, version << 4); } /** @@ -286,8 +234,8 @@ HWTEST_F(WaterVersionManagerTest, SetWaterVersionTest3, TestSize.Level0) //bundle2 updated later, but sync first. Do not update waterVersion meta.infos[1] = { 1, 2, 0 }; meta.waterVersion = 2; - EXPECT_TRUE( - WvManager::GetInstance().SetWaterVersion(stores_[1].first, stores_[1].second, Serializable::Marshall(meta))); + EXPECT_TRUE(WvManager::GetInstance().SetWaterVersion(dynamicStores_[1].first, dynamicStores_[1].second, + Serializable::Marshall(meta))); auto res = WvManager::GetInstance().GetVersion(TEST_DEVICE, WvManager::STATIC); EXPECT_TRUE(res.first && res.second == 0) << "success:" << res.first << " version:" << res.second << " meta: " << meta.ToAnonymousString(); @@ -295,11 +243,17 @@ HWTEST_F(WaterVersionManagerTest, SetWaterVersionTest3, TestSize.Level0) //bundle1 updated earlier, but sync later. update waterVersion meta.infos[0] = { 1, 0, 0 }; meta.waterVersion = 1; - EXPECT_TRUE( - WvManager::GetInstance().SetWaterVersion(stores_[0].first, stores_[0].second, Serializable::Marshall(meta))); + EXPECT_TRUE(WvManager::GetInstance().SetWaterVersion(dynamicStores_[0].first, dynamicStores_[0].second, + Serializable::Marshall(meta))); res = WvManager::GetInstance().GetVersion(TEST_DEVICE, WvManager::DYNAMIC); EXPECT_TRUE(res.first && res.second == 2) << "success:" << res.first << " version:" << res.second << " meta: " << meta.ToAnonymousString(); + + // update to matrixMeta + MatrixMetaData matrixMetaData; + matrixMetaData.deviceId = TEST_DEVICE; + EXPECT_TRUE(MetaDataManager::GetInstance().LoadMeta(matrixMetaData.GetConsistentKey(), matrixMetaData, true)); + EXPECT_EQ(matrixMetaData.dynamic, res.second << 4); } /** @@ -320,8 +274,8 @@ HWTEST_F(WaterVersionManagerTest, SetWaterVersionTest4, TestSize.Level0) //bundle1 updated twice, but sync once. update waterVersion meta.infos[0] = { 2, 0, 0 }; meta.waterVersion = 2; - EXPECT_TRUE( - WvManager::GetInstance().SetWaterVersion(stores_[0].first, stores_[0].second, Serializable::Marshall(meta))); + EXPECT_TRUE(WvManager::GetInstance().SetWaterVersion(staticStores_[0].first, staticStores_[0].second, + Serializable::Marshall(meta))); auto res = WvManager::GetInstance().GetVersion(TEST_DEVICE, WvManager::STATIC); EXPECT_TRUE(res.first && res.second == 2) @@ -350,8 +304,8 @@ HWTEST_F(WaterVersionManagerTest, SetWaterVersionTest5, TestSize.Level0) meta.infos[1] = { 1, 2, 0 }; meta.infos[2] = { 0, 0, 0 }; meta.waterVersion = 2; - EXPECT_TRUE( - WvManager::GetInstance().SetWaterVersion(stores_[1].first, stores_[1].second, Serializable::Marshall(meta))); + EXPECT_TRUE(WvManager::GetInstance().SetWaterVersion(dynamicStores_[1].first, dynamicStores_[1].second, + Serializable::Marshall(meta))); auto res = WvManager::GetInstance().GetVersion(TEST_DEVICE, type); EXPECT_TRUE(res.first && res.second == 0) @@ -362,8 +316,8 @@ HWTEST_F(WaterVersionManagerTest, SetWaterVersionTest5, TestSize.Level0) meta.infos[1] = { 1, 2, 0 }; meta.infos[2] = { 3, 2, 4 }; meta.waterVersion = 4; - EXPECT_TRUE( - WvManager::GetInstance().SetWaterVersion(stores_[2].first, stores_[2].second, Serializable::Marshall(meta))); + EXPECT_TRUE(WvManager::GetInstance().SetWaterVersion(dynamicStores_[2].first, dynamicStores_[2].second, + Serializable::Marshall(meta))); res = WvManager::GetInstance().GetVersion(TEST_DEVICE, type); EXPECT_TRUE(res.first && res.second == 0) << "success:" << res.first << " version:" << res.second << " meta: " << meta.ToAnonymousString(); @@ -373,8 +327,8 @@ HWTEST_F(WaterVersionManagerTest, SetWaterVersionTest5, TestSize.Level0) meta.infos[1] = { 1, 2, 0 }; meta.infos[2] = { 0, 0, 0 }; meta.waterVersion = 3; - EXPECT_TRUE( - WvManager::GetInstance().SetWaterVersion(stores_[0].first, stores_[0].second, Serializable::Marshall(meta))); + EXPECT_TRUE(WvManager::GetInstance().SetWaterVersion(dynamicStores_[0].first, dynamicStores_[0].second, + Serializable::Marshall(meta))); res = WvManager::GetInstance().GetVersion(TEST_DEVICE, type); EXPECT_TRUE(res.first && res.second == 4) << "success:" << res.first << " version:" << res.second << " meta: " << meta.ToAnonymousString(); @@ -390,20 +344,24 @@ HWTEST_F(WaterVersionManagerTest, SetWaterVersionTest5, TestSize.Level0) HWTEST_F(WaterVersionManagerTest, GenerateWaterVersionTest1, TestSize.Level0) { std::string waterVersion = - WvManager::GetInstance().GenerateWaterVersion(stores_[0].first, stores_[0].second, WvManager::STATIC); + WvManager::GetInstance().GenerateWaterVersion(staticStores_[0].first, staticStores_[0].second); WvManager::WaterVersionMetaData meta; ASSERT_TRUE(Serializable::Unmarshall(waterVersion, meta)) << "waterVersion: " << waterVersion; EXPECT_EQ(meta.waterVersion, 1) << "waterVersion: " << waterVersion; - waterVersion = - WvManager::GetInstance().GenerateWaterVersion(stores_[1].first, stores_[1].second, WvManager::STATIC); + waterVersion = WvManager::GetInstance().GenerateWaterVersion(staticStores_[1].first, staticStores_[1].second); ASSERT_TRUE(Serializable::Unmarshall(waterVersion, meta)) << "waterVersion: " << waterVersion; EXPECT_EQ(meta.waterVersion, 2) << "waterVersion: " << waterVersion; - waterVersion = - WvManager::GetInstance().GenerateWaterVersion(stores_[0].first, stores_[0].second, WvManager::STATIC); + waterVersion = WvManager::GetInstance().GenerateWaterVersion(staticStores_[0].first, staticStores_[0].second); ASSERT_TRUE(Serializable::Unmarshall(waterVersion, meta)) << "waterVersion: " << waterVersion; EXPECT_EQ(meta.waterVersion, 3) << "waterVersion: " << waterVersion; + + MatrixMetaData matrixMetaData; + matrixMetaData.deviceId = DMAdapter::GetInstance().GetLocalDevice().uuid; + auto key = matrixMetaData.GetKey(); + ASSERT_TRUE(MetaDataManager::GetInstance().LoadMeta(key, matrixMetaData, true)); + EXPECT_EQ(matrixMetaData.statics & 0xFFF0, 3 << 4); } /** @@ -416,9 +374,10 @@ HWTEST_F(WaterVersionManagerTest, GenerateWaterVersionTest1, TestSize.Level0) HWTEST_F(WaterVersionManagerTest, GenerateWaterVersionTest2, TestSize.Level0) { auto executorPool = std::make_shared(5, 5); - for (int i = 0; i < 10; ++i) { - executorPool->Execute([] { - WvManager::GetInstance().GenerateWaterVersion(stores_[0].first, stores_[0].second, WvManager::DYNAMIC); + auto len = dynamicStores_.size(); + for (size_t i = 0; i < 10; ++i) { + executorPool->Execute([index = i % len] { + WvManager::GetInstance().GenerateWaterVersion(dynamicStores_[index].first, dynamicStores_[index].second); }); } std::this_thread::sleep_for(std::chrono::milliseconds(1000)); @@ -426,6 +385,35 @@ HWTEST_F(WaterVersionManagerTest, GenerateWaterVersionTest2, TestSize.Level0) auto [success, version] = WvManager::GetInstance().GetVersion(DMAdapter::GetInstance().GetLocalDevice().uuid, WvManager::DYNAMIC); EXPECT_EQ(version, 10); + + MatrixMetaData matrixMetaData; + matrixMetaData.deviceId = DMAdapter::GetInstance().GetLocalDevice().uuid; + auto key = matrixMetaData.GetKey(); + ASSERT_TRUE(MetaDataManager::GetInstance().LoadMeta(key, matrixMetaData, true)); + EXPECT_EQ(matrixMetaData.dynamic & 0xFFF0, version << 4); +} + +/** +* @tc.name: GetWaterVersionTest1 +* @tc.desc: GetWaterVersion by different key +* @tc.type: FUNC +* @tc.require: +* @tc.author: ht +*/ +HWTEST_F(WaterVersionManagerTest, GetWaterVersionTest1, TestSize.Level0) +{ + auto len = staticStores_.size(); + for (size_t i = 0; i < 10; ++i) { + auto bundle = staticStores_[i % len].first; + auto store = staticStores_[i % len].second; + ASSERT_FALSE(WvManager::GetInstance().GenerateWaterVersion(bundle, store).empty()); + } + for (size_t i = 0; i < len; i++) { + auto waterVersion = WvManager::GetInstance().GetWaterVersion(staticStores_[i].first, staticStores_[i].second); + WvManager::WaterVersionMetaData meta; + ASSERT_TRUE(Serializable::Unmarshall(waterVersion, meta)) << "waterVersion: " << waterVersion; + EXPECT_EQ(meta.waterVersion, 10 / len * len + i + 1 - len * (10 % len <= i ? 1 : 0)); + } } /** @@ -438,14 +426,14 @@ HWTEST_F(WaterVersionManagerTest, GenerateWaterVersionTest2, TestSize.Level0) HWTEST_F(WaterVersionManagerTest, MixCallTest1, TestSize.Level0) { std::string waterVersion = - WvManager::GetInstance().GenerateWaterVersion(stores_[0].first, stores_[0].second, WvManager::STATIC); + WvManager::GetInstance().GenerateWaterVersion(staticStores_[0].first, staticStores_[0].second); WvManager::WaterVersionMetaData meta; ASSERT_TRUE(Serializable::Unmarshall(waterVersion, meta)) << "waterVersion: " << waterVersion; EXPECT_EQ(meta.waterVersion, 1) << "waterVersion: " << waterVersion; meta.deviceId = TEST_DEVICE; - EXPECT_TRUE( - WvManager::GetInstance().SetWaterVersion(stores_[0].first, stores_[0].second, Serializable::Marshall(meta))); + EXPECT_TRUE(WvManager::GetInstance().SetWaterVersion(staticStores_[0].first, staticStores_[0].second, + Serializable::Marshall(meta))); auto [_, version] = WvManager::GetInstance().GetVersion(TEST_DEVICE, WvManager::STATIC); EXPECT_EQ(version, 1) << "version: " << version; @@ -464,13 +452,13 @@ HWTEST_F(WaterVersionManagerTest, MixCallTest2, TestSize.Level0) uint64_t version = 0; for (int i = 1; i < 11; ++i) { int index = i % dynamicMeta_.keys.size(); - std::string waterVersion = WvManager::GetInstance().GenerateWaterVersion(stores_[index].first, - stores_[index].second, WvManager::DYNAMIC); + std::string waterVersion = + WvManager::GetInstance().GenerateWaterVersion(dynamicStores_[index].first, dynamicStores_[index].second); WvManager::WaterVersionMetaData meta; ASSERT_TRUE(Serializable::Unmarshall(waterVersion, meta)) << "waterVersion: " << waterVersion; EXPECT_EQ(meta.waterVersion, i) << "waterVersion: " << waterVersion; meta.deviceId = TEST_DEVICE; - EXPECT_TRUE(WvManager::GetInstance().SetWaterVersion(stores_[index].first, stores_[index].second, + EXPECT_TRUE(WvManager::GetInstance().SetWaterVersion(dynamicStores_[index].first, dynamicStores_[index].second, Serializable::Marshall(meta))); std::tie(success, version) = WvManager::GetInstance().GetVersion(TEST_DEVICE, WvManager::DYNAMIC); diff --git a/datamgr_service/services/distributeddataservice/service/udmf/BUILD.gn b/datamgr_service/services/distributeddataservice/service/udmf/BUILD.gn index 469554e7..e64eb69f 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/BUILD.gn +++ b/datamgr_service/services/distributeddataservice/service/udmf/BUILD.gn @@ -27,8 +27,6 @@ config("module_public_config") { "${data_service_path}/service/udmf/utd", "${data_service_path}/service/udmf", "${data_service_path}/service/bootstrap/include", - "${device_manager_path}/interfaces/inner_kits/native_cpp/include", - "${file_service_path}/interfaces/innerkits/native/remote_file_share/include", "${kv_store_path}/interfaces/innerkits/distributeddata/include", "${kv_store_path}/framework/libs/distributeddb/interfaces/include", "${kv_store_common_path}", @@ -41,6 +39,8 @@ config("module_public_config") { ohos_shared_library("udmf_server") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false @@ -73,11 +73,13 @@ ohos_shared_library("udmf_server") { "ability_base:zuri", "ability_runtime:uri_permission_mgr", "access_token:libaccesstoken_sdk", + "access_token:libtokenid_sdk", "app_file_service:remote_file_share_native", "bundle_framework:appexecfwk_base", "bundle_framework:appexecfwk_core", "c_utils:utils", "hilog:libhilog", + "hisysevent:libhisysevent", "image_framework:image", "ipc:ipc_core", "kv_store:distributeddb", @@ -85,7 +87,7 @@ ohos_shared_library("udmf_server") { "samgr:samgr_proxy", "udmf:udmf_client", ] - + cflags_cc = [ "-fvisibility=hidden" ] subsystem_name = "distributeddatamgr" part_name = "datamgr_service" diff --git a/datamgr_service/services/distributeddataservice/service/udmf/permission/uri_permission_manager.cpp b/datamgr_service/services/distributeddataservice/service/udmf/permission/uri_permission_manager.cpp index 1fc6fab2..c6215277 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/permission/uri_permission_manager.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/permission/uri_permission_manager.cpp @@ -16,10 +16,11 @@ #include "uri_permission_manager.h" -#include "want.h" +#include "log_print.h" +#include "preprocess_utils.h" #include "uri_permission_manager_client.h" +#include "want.h" -#include "log_print.h" namespace OHOS { namespace UDMF { constexpr const std::uint32_t GRANT_URI_PERMISSION_MAX_SIZE = 500; @@ -30,22 +31,88 @@ UriPermissionManager &UriPermissionManager::GetInstance() } Status UriPermissionManager::GrantUriPermission( - const std::vector &allUri, const std::string &bundleName, const std::string &queryKey) + const std::vector &allUri, uint32_t tokenId, const std::string &queryKey) { + std::string bundleName; + if (!PreProcessUtils::GetHapBundleNameByToken(tokenId, bundleName)) { + ZLOGE("Get BundleName fail, key:%{public}s, tokenId:%{public}u.", queryKey.c_str(), tokenId); + return E_ERROR; + } + int32_t instIndex = -1; + if (!PreProcessUtils::GetInstIndex(tokenId, instIndex)) { + ZLOGE("Get InstIndex fail, key:%{public}s, tokenId:%{public}u.", queryKey.c_str(), tokenId); + return E_ERROR; + } + // GrantUriPermission is time-consuming, need recording the begin,end time in log. - ZLOGI("GrantUriPermission begin, url size:%{public}zu, queryKey:%{public}s.", allUri.size(), queryKey.c_str()); + ZLOGI("GrantUriPermission begin, url size:%{public}zu, queryKey:%{public}s, instIndex:%{public}d.", + allUri.size(), queryKey.c_str(), instIndex); for (size_t index = 0; index < allUri.size(); index += GRANT_URI_PERMISSION_MAX_SIZE) { std::vector uriLst( allUri.begin() + index, allUri.begin() + std::min(index + GRANT_URI_PERMISSION_MAX_SIZE, allUri.size())); auto status = AAFwk::UriPermissionManagerClient::GetInstance().GrantUriPermissionPrivileged( - uriLst, AAFwk::Want::FLAG_AUTH_READ_URI_PERMISSION, bundleName); + uriLst, AAFwk::Want::FLAG_AUTH_READ_URI_PERMISSION, bundleName, instIndex); if (status != ERR_OK) { - ZLOGE("GrantUriPermission failed, status:%{public}d, queryKey:%{public}s", status, queryKey.c_str()); + ZLOGE("GrantUriPermission failed, status:%{public}d, queryKey:%{public}s, instIndex:%{public}d.", + status, queryKey.c_str(), instIndex); return E_NO_PERMISSION; } + auto time = std::chrono::steady_clock::now() + std::chrono::minutes(INTERVAL); + std::for_each(uriLst.begin(), uriLst.end(), [&](const Uri &uri) { + uriTimeout_[std::make_pair(uri.ToString(), tokenId)] = time; + }); } ZLOGI("GrantUriPermission end, url size:%{public}zu, queryKey:%{public}s.", allUri.size(), queryKey.c_str()); + + std::unique_lock lock(taskMutex_); + if (taskId_ == ExecutorPool::INVALID_TASK_ID && executorPool_ != nullptr) { + taskId_ = executorPool_->Schedule( + std::chrono::minutes(INTERVAL), std::bind(&UriPermissionManager::RevokeUriPermission, this)); + } return E_OK; } + +void UriPermissionManager::RevokeUriPermission() +{ + auto current = std::chrono::steady_clock::now(); + uriTimeout_.EraseIf([&](auto &key, Time &time) { + if (time > current) { + return false; + } + Uri uri(key.first); + uint32_t tokenId = key.second; + std::string bundleName; + if (!PreProcessUtils::GetHapBundleNameByToken(tokenId, bundleName)) { + ZLOGE("Get BundleName fail, tokenId:%{public}u.", tokenId); + return true; + } + int32_t instIndex = -1; + if (!PreProcessUtils::GetInstIndex(tokenId, instIndex)) { + ZLOGE("Get InstIndex fail, tokenId:%{public}u.", tokenId); + return true; + } + int status = AAFwk::UriPermissionManagerClient::GetInstance().RevokeUriPermissionManually( + uri, bundleName, instIndex); + if (status != E_OK) { + ZLOGE("RevokeUriPermission error, permissionCode:%{public}d, bundleName:%{public}s, instIndex:%{public}d", + status, bundleName.c_str(), instIndex); + } + return true; + }); + + std::unique_lock lock(taskMutex_); + if (!uriTimeout_.Empty() && executorPool_ != nullptr) { + ZLOGD("RevokeUriPermission, uriTimeout size:%{public}zu", uriTimeout_.Size()); + taskId_ = executorPool_->Schedule( + std::chrono::minutes(INTERVAL), std::bind(&UriPermissionManager::RevokeUriPermission, this)); + } else { + taskId_ = ExecutorPool::INVALID_TASK_ID; + } +} + +void UriPermissionManager::SetThreadPool(std::shared_ptr executors) +{ + executorPool_ = executors; +} } // namespace UDMF } // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/service/udmf/permission/uri_permission_manager.h b/datamgr_service/services/distributeddataservice/service/udmf/permission/uri_permission_manager.h index a372b112..87be83cd 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/permission/uri_permission_manager.h +++ b/datamgr_service/services/distributeddataservice/service/udmf/permission/uri_permission_manager.h @@ -19,16 +19,33 @@ #include #include +#include "concurrent_map.h" #include "error_code.h" +#include "executor_pool.h" #include "uri.h" namespace OHOS { namespace UDMF { class UriPermissionManager { public: + using Time = std::chrono::steady_clock::time_point; static UriPermissionManager &GetInstance(); - Status GrantUriPermission( - const std::vector &allUri, const std::string &bundleName, const std::string &queryKey); + Status GrantUriPermission(const std::vector &allUri, uint32_t tokenId, const std::string &queryKey); + void SetThreadPool(std::shared_ptr executors); + +private: + UriPermissionManager() {} + ~UriPermissionManager() {} + UriPermissionManager(const UriPermissionManager &mgr) = delete; + UriPermissionManager &operator=(const UriPermissionManager &mgr) = delete; + + void RevokeUriPermission(); + + ConcurrentMap, Time> uriTimeout_; + static constexpr int64_t INTERVAL = 60; // 60 min + ExecutorPool::TaskId taskId_ = ExecutorPool::INVALID_TASK_ID; + std::mutex taskMutex_; + std::shared_ptr executorPool_; }; } // namespace UDMF } // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.cpp b/datamgr_service/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.cpp index 8499ce7a..64885ff0 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.cpp @@ -26,6 +26,7 @@ #include "file.h" #include "ipc_skeleton.h" #include "log_print.h" +#include "udmf_radar_reporter.h" #include "remote_file_share.h" #include "uri.h" #include "utils/crypto.h" @@ -40,6 +41,7 @@ const char SPECIAL = '^'; static constexpr uint32_t VERIFY_URI_PERMISSION_MAX_SIZE = 500; using namespace Security::AccessToken; using namespace OHOS::AppFileService::ModuleRemoteFileShare; +using namespace RadarReporter; int32_t PreProcessUtils::RuntimeDataImputation(UnifiedData &data, CustomOption &option) { @@ -61,6 +63,7 @@ int32_t PreProcessUtils::RuntimeDataImputation(UnifiedData &data, CustomOption & runtime.createPackage = bundleName; runtime.deviceId = GetLocalDeviceId(); runtime.recordTotalNum = static_cast(data.GetRecords().size()); + runtime.tokenId = option.tokenId; data.SetRuntime(runtime); return E_OK; } @@ -178,10 +181,14 @@ int32_t PreProcessUtils::SetRemoteUri(uint32_t tokenId, UnifiedData &data) if (!CheckUriAuthorization(uris, tokenId)) { ZLOGE("CheckUriAuthorization failed, bundleName:%{public}s, tokenId: %{public}d, uris size:%{public}zu.", data.GetRuntime()->createPackage.c_str(), tokenId, uris.size()); + RADAR_REPORT(BizScene::SET_DATA, SetDataStage::VERIFY_SHARE_PERMISSIONS, StageRes::FAILED, + ERROR_CODE, E_NO_PERMISSION); return E_NO_PERMISSION; } int ret = GetDfsUrisFromLocal(uris, userId, data); if (ret != E_OK) { + RADAR_REPORT(BizScene::SET_DATA, SetDataStage::GERERATE_DFS_URI, StageRes::FAILED, + ERROR_CODE, E_FS_ERROR); ZLOGE("Get remoteUri failed, ret = %{public}d, userId: %{public}d, uri size:%{public}zu.", ret, userId, uris.size()); return E_FS_ERROR; @@ -225,5 +232,21 @@ bool PreProcessUtils::CheckUriAuthorization(const std::vector& uris } return true; } + +bool PreProcessUtils::GetInstIndex(uint32_t tokenId, int32_t &instIndex) +{ + if (AccessTokenKit::GetTokenTypeFlag(tokenId) != TOKEN_HAP) { + instIndex = 0; + return true; + } + HapTokenInfo tokenInfo; + int errCode = AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo); + if (errCode != RET_SUCCESS) { + ZLOGE("Get Hap TokenInfo error:%{public}d, tokenId:0x%{public}x", errCode, tokenId); + return false; + } + instIndex = tokenInfo.instIndex; + return true; +} } // namespace UDMF } // namespace OHOS \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.h b/datamgr_service/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.h index c2ea25f3..70e9c6ee 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.h +++ b/datamgr_service/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.h @@ -37,6 +37,7 @@ public: static void SetRemoteData(UnifiedData &data); static bool IsFileType(UDType udType); static int32_t SetRemoteUri(uint32_t tokenId, UnifiedData &data); + static bool GetInstIndex(uint32_t tokenId, int32_t &instIndex); private: static bool CheckUriAuthorization(const std::vector& uris, uint32_t tokenId); static int32_t GetDfsUrisFromLocal(const std::vector &uris, int32_t userId, UnifiedData &data); diff --git a/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.cpp b/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.cpp index 52a916f0..d6dd6a0d 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include "log_print.h" #include "ipc_skeleton.h" @@ -30,10 +31,13 @@ #include "device_manager_adapter.h" #include "bootstrap.h" #include "directory/directory_manager.h" - +#include "utils/anonymous.h" +#include "udmf_radar_reporter.h" namespace OHOS { namespace UDMF { +using namespace RadarReporter; using namespace DistributedDB; +using Anonymous = OHOS::DistributedData::Anonymous; using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; const std::string TEMP_UNIFIED_DATA_FLAG = "temp_udmf_file_flag"; @@ -42,12 +46,57 @@ static constexpr size_t TEMP_UDATA_RECORD_SIZE = 1; RuntimeStore::RuntimeStore(const std::string &storeId) : storeId_(storeId) { UpdateTime(); - ZLOGD("Construct runtimeStore: %{public}s.", storeId_.c_str()); + ZLOGD("Construct runtimeStore: %{public}s.", Anonymous::Change(storeId_).c_str()); } RuntimeStore::~RuntimeStore() { - ZLOGD("Destruct runtimeStore: %{public}s.", storeId_.c_str()); + ZLOGD("Destruct runtimeStore: %{public}s.", Anonymous::Change(storeId_).c_str()); +} + +Status RuntimeStore::PutLocal(const std::string &key, const std::string &value) +{ + UpdateTime(); + std::vector keyBytes = {key.begin(), key.end()}; + std::vector valueBytes = {value.begin(), value.end()}; + + auto status = kvStore_->PutLocal(keyBytes, valueBytes); + if (status != DBStatus::OK) { + ZLOGE("KvStore PutLocal failed, status: %{public}d.", status); + return E_DB_ERROR; + } + return E_OK; +} + +Status RuntimeStore::GetLocal(const std::string &key, std::string &value) +{ + UpdateTime(); + std::vector valueBytes; + std::vector keyBytes = {key.begin(), key.end()}; + DBStatus status = kvStore_->GetLocal(keyBytes, valueBytes); + if (status != DBStatus::OK && status != DBStatus::NOT_FOUND) { + ZLOGE("GetLocal entry failed, key: %{public}s.", key.c_str()); + return E_DB_ERROR; + } + if (valueBytes.empty()) { + ZLOGW("GetLocal entry is empty, key: %{public}s", key.c_str()); + return E_NOT_FOUND; + } + value = {valueBytes.begin(), valueBytes.end()}; + return E_OK; +} + +Status RuntimeStore::DeleteLocal(const std::string &key) +{ + UpdateTime(); + std::vector valueBytes; + std::vector keyBytes = {key.begin(), key.end()}; + DBStatus status = kvStore_->DeleteLocal(keyBytes); + if (status != DBStatus::OK && status != DBStatus::NOT_FOUND) { + ZLOGE("DeleteLocal failed, key: %{public}s.", key.c_str()); + return E_DB_ERROR; + } + return E_OK; } Status RuntimeStore::Put(const UnifiedData &unifiedData) @@ -149,7 +198,7 @@ Status RuntimeStore::GetSummary(const std::string &key, Summary &summary) } for (const auto &record : unifiedData.GetRecords()) { int64_t recordSize = record->GetSize(); - auto udType = UD_TYPE_MAP.at(record->GetType()); + auto udType = UtdUtils::GetUtdIdFromUtdEnum(record->GetType()); auto it = summary.summary.find(udType); if (it == summary.summary.end()) { summary.summary[udType] = recordSize; @@ -219,11 +268,26 @@ Status RuntimeStore::Sync(const std::vector &devices) return E_INVALID_PARAMETERS; } std::vector syncDevices = DmAdapter::ToUUID(devices); - auto onComplete = [this](const std::map &) { - ZLOGI("sync complete, %{public}s.", storeId_.c_str()); + auto onComplete = [this](const std::map &devsSyncStatus) { + DBStatus dbStatus = DBStatus::OK; + for (const auto &[originDeviceId, status] : devsSyncStatus) { // only one device. + if (status != DBStatus::OK) { + dbStatus = status; + break; + } + } + if (dbStatus != DBStatus::OK) { + RADAR_REPORT(BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::FAILED, ERROR_CODE, dbStatus); + } else { + RADAR_REPORT(BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::SUCCESS, + BIZ_STATE, BizState::DFX_NORMAL_END); + } + + ZLOGI("sync complete, %{public}s, status:%{public}d.", Anonymous::Change(storeId_).c_str(), dbStatus); }; DBStatus status = kvStore_->Sync(syncDevices, SyncMode::SYNC_MODE_PULL_ONLY, onComplete); if (status != DBStatus::OK) { + RADAR_REPORT(BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::FAILED, ERROR_CODE, status); ZLOGE("Sync kvStore failed, status: %{public}d.", status); return E_DB_ERROR; } @@ -312,7 +376,7 @@ bool RuntimeStore::Init() return true; } -bool RuntimeStore::SaveMetaData() +bool RuntimeStore::BuildMetaDataParam(DistributedData::StoreMetaData &metaData) { auto localDeviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; if (localDeviceId.empty()) { @@ -322,26 +386,43 @@ bool RuntimeStore::SaveMetaData() uint32_t token = IPCSkeleton::GetSelfTokenID(); const std::string userId = std::to_string(DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(token)); + metaData.appType = "harmony"; + metaData.deviceId = localDeviceId; + metaData.storeId = storeId_; + metaData.isAutoSync = false; + metaData.isBackup = false; + metaData.isEncrypt = false; + metaData.bundleName = DistributedData::Bootstrap::GetInstance().GetProcessLabel(); + metaData.appId = DistributedData::Bootstrap::GetInstance().GetProcessLabel(); + metaData.user = userId; + metaData.account = DistributedKv::AccountDelegate::GetInstance()->GetCurrentAccountId(); + metaData.tokenId = token; + metaData.securityLevel = DistributedKv::SecurityLevel::S1; + metaData.area = DistributedKv::Area::EL1; + metaData.uid = static_cast(getuid()); + metaData.storeType = DistributedKv::KvStoreType::SINGLE_VERSION; + metaData.dataType = DistributedKv::DataType::TYPE_DYNAMICAL; + metaData.dataDir = DistributedData::DirectoryManager::GetInstance().GetStorePath(metaData); + + return true; +} + +bool RuntimeStore::SaveMetaData() +{ DistributedData::StoreMetaData saveMeta; - saveMeta.appType = "harmony"; - saveMeta.deviceId = localDeviceId; - saveMeta.storeId = storeId_; - saveMeta.isAutoSync = false; - saveMeta.isBackup = false; - saveMeta.isEncrypt = false; - saveMeta.bundleName = DistributedData::Bootstrap::GetInstance().GetProcessLabel(); - saveMeta.appId = DistributedData::Bootstrap::GetInstance().GetProcessLabel(); - saveMeta.user = userId; - saveMeta.account = DistributedKv::AccountDelegate::GetInstance()->GetCurrentAccountId(); - saveMeta.tokenId = token; - saveMeta.securityLevel = DistributedKv::SecurityLevel::S1; - saveMeta.area = DistributedKv::Area::EL1; - saveMeta.uid = static_cast(getuid()); - saveMeta.storeType = DistributedKv::KvStoreType::SINGLE_VERSION; - saveMeta.dataType = DistributedKv::DataType::TYPE_DYNAMICAL; - saveMeta.dataDir = DistributedData::DirectoryManager::GetInstance().GetStorePath(saveMeta); - - SetDelegateManager(saveMeta.dataDir, saveMeta.appId, userId); + if (!BuildMetaDataParam(saveMeta)) { + return false; + } + + int foregroundUserId = 0; + DistributedKv::AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId); + saveMeta.dataDir.append("/").append(std::to_string(foregroundUserId)); + if (!DistributedData::DirectoryManager::GetInstance().CreateDirectory(saveMeta.dataDir)) { + ZLOGE("Create directory error"); + return false; + } + + SetDelegateManager(saveMeta.dataDir, saveMeta.appId, saveMeta.user, std::to_string(foregroundUserId)); DistributedData::StoreMetaData loadLocal; DistributedData::StoreMetaData syncMeta; @@ -368,9 +449,10 @@ bool RuntimeStore::SaveMetaData() return true; } -void RuntimeStore::SetDelegateManager(const std::string &dataDir, const std::string &appId, const std::string &userId) +void RuntimeStore::SetDelegateManager(const std::string &dataDir, const std::string &appId, const std::string &userId, + const std::string &subUser) { - delegateManager_ = std::make_shared(appId, userId); + delegateManager_ = std::make_shared(appId, userId, subUser); DistributedDB::KvStoreConfig kvStoreConfig { dataDir }; delegateManager_->SetKvStoreConfig(kvStoreConfig); } diff --git a/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.h b/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.h index 1163805b..303b4b08 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.h +++ b/datamgr_service/services/distributeddataservice/service/udmf/store/runtime_store.h @@ -18,10 +18,12 @@ #include "store.h" #include "kv_store_delegate_manager.h" +#include "metadata/store_meta_data.h" +#include "visibility.h" namespace OHOS { namespace UDMF { -class RuntimeStore final : public Store { +class API_EXPORT RuntimeStore final : public Store { public: explicit RuntimeStore(const std::string &storeId); ~RuntimeStore(); @@ -34,6 +36,9 @@ public: Status Sync(const std::vector &devices) override; Status Clear() override; Status GetBatchData(const std::string &dataPrefix, std::vector &unifiedDataSet) override; + Status PutLocal(const std::string &key, const std::string &value) override; + Status GetLocal(const std::string &key, std::string &value) override; + Status DeleteLocal(const std::string &key) override; void Close() override; bool Init() override; @@ -44,7 +49,8 @@ private: std::shared_ptr delegateManager_ = nullptr; std::shared_ptr kvStore_; std::string storeId_; - void SetDelegateManager(const std::string &dataDir, const std::string &appId, const std::string &userId); + void SetDelegateManager(const std::string &dataDir, const std::string &appId, const std::string &userId, + const std::string &subUser); bool SaveMetaData(); Status GetEntries(const std::string &dataPrefix, std::vector &entries); Status PutEntries(const std::vector &entries); @@ -53,6 +59,7 @@ private: const std::string &key, std::vector &entries, UnifiedData &unifiedData); bool GetDetailsFromUData(UnifiedData &data, UDDetails &details); Status GetSummaryFromDetails(const UDDetails &details, Summary &summary); + bool BuildMetaDataParam(DistributedData::StoreMetaData &metaData); }; } // namespace UDMF } // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/service/udmf/store/store.h b/datamgr_service/services/distributeddataservice/service/udmf/store/store.h index 61f65dfb..11a41da5 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/store/store.h +++ b/datamgr_service/services/distributeddataservice/service/udmf/store/store.h @@ -38,9 +38,12 @@ public: virtual Status DeleteBatch(const std::vector &unifiedKeys) = 0; virtual Status Sync(const std::vector &devices) = 0; virtual Status Clear() = 0; + virtual Status GetBatchData(const std::string &dataPrefix, std::vector &unifiedDataSet) = 0; + virtual Status PutLocal(const std::string &key, const std::string &value) = 0; + virtual Status GetLocal(const std::string &key, std::string &value) = 0; + virtual Status DeleteLocal(const std::string &key) = 0; virtual bool Init() = 0; virtual void Close() = 0; - virtual Status GetBatchData(const std::string &dataPrefix, std::vector &unifiedDataSet) = 0; bool operator<(const Time &time) const { diff --git a/datamgr_service/services/distributeddataservice/service/udmf/store/store_cache.cpp b/datamgr_service/services/distributeddataservice/service/udmf/store/store_cache.cpp index 8e69522f..9d4d9014 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/store/store_cache.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/store/store_cache.cpp @@ -13,13 +13,14 @@ * limitations under the License. */ #define LOG_TAG "StoreCache" - #include "store_cache.h" #include +#include #include "log_print.h" #include "runtime_store.h" #include "unified_meta.h" +#include "account/account_delegate.h" namespace OHOS { namespace UDMF { @@ -32,7 +33,12 @@ StoreCache &StoreCache::GetInstance() std::shared_ptr StoreCache::GetStore(std::string intention) { std::shared_ptr store; - stores_.Compute(intention, [&store](const auto &intention, std::shared_ptr &storePtr) -> bool { + int foregroundUserId = 0; + DistributedKv::AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId); + std::string key = intention; + key.append(std::to_string(foregroundUserId)); + + stores_.Compute(key, [&store, intention](const auto &key, std::shared_ptr &storePtr) -> bool { if (storePtr != nullptr) { store = storePtr; return true; 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 44583e48..ec9febfc 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.cpp @@ -17,7 +17,10 @@ #include "udmf_service_impl.h" #include "iservice_registry.h" +#include "ipc_skeleton.h" +#include "tokenid_kit.h" +#include "accesstoken_kit.h" #include "checker_manager.h" #include "dfx_types.h" #include "distributed_kv_data_manager.h" @@ -29,14 +32,18 @@ #include "uri_permission_manager.h" #include "uri.h" #include "utd/custom_utd_installer.h" +#include "udmf_radar_reporter.h" namespace OHOS { namespace UDMF { +using namespace Security::AccessToken; using FeatureSystem = DistributedData::FeatureSystem; using UdmfBehaviourMsg = OHOS::DistributedDataDfx::UdmfBehaviourMsg; using Reporter = OHOS::DistributedDataDfx::Reporter; +using namespace RadarReporter; constexpr const char *DRAG_AUTHORIZED_PROCESSES[] = {"msdp_sa", "collaboration_service"}; constexpr const char *DATA_PREFIX = "udmf://"; +constexpr const char *PRIVILEGE_READ_AND_KEEP = "readAndKeep"; __attribute__((used)) UdmfServiceImpl::Factory UdmfServiceImpl::factory_; UdmfServiceImpl::Factory::Factory() { @@ -191,6 +198,8 @@ int32_t UdmfServiceImpl::RetrieveData(const QueryOption &query, UnifiedData &uni return E_DB_ERROR; } if (!CheckerManager::GetInstance().IsValid(runtime->privileges, info) && !IsPermissionInCache(query)) { + RADAR_REPORT(BizScene::GET_DATA, GetDataStage::VERIFY_PRIVILEGE, StageRes::FAILED, + ERROR_CODE, E_NO_PERMISSION); return E_NO_PERMISSION; } @@ -201,11 +210,13 @@ int32_t UdmfServiceImpl::RetrieveData(const QueryOption &query, UnifiedData &uni return E_NO_PERMISSION; } } - - if (LifeCycleManager::GetInstance().OnGot(key) != E_OK) { - ZLOGE("Remove data failed, intention: %{public}s.", key.intention.c_str()); - return E_DB_ERROR; + if (!IsReadAndKeep(runtime->privileges, query)) { + if (LifeCycleManager::GetInstance().OnGot(key) != E_OK) { + ZLOGE("Remove data failed, intention: %{public}s.", key.intention.c_str()); + return E_DB_ERROR; + } } + privilegeCache_.erase(query.key); PreProcessUtils::SetRemoteData(unifiedData); @@ -221,6 +232,22 @@ bool UdmfServiceImpl::IsPermissionInCache(const QueryOption &query) return false; } +bool UdmfServiceImpl::IsReadAndKeep(const std::vector &privileges, const QueryOption &query) +{ + for (const auto &privilege : privileges) { + if (privilege.tokenId == query.tokenId && privilege.readPermission == PRIVILEGE_READ_AND_KEEP) { + return true; + } + } + + auto iter = privilegeCache_.find(query.key); + if (iter != privilegeCache_.end() && iter->second.tokenId == query.tokenId && + iter->second.readPermission == PRIVILEGE_READ_AND_KEEP) { + return true; + } + return false; +} + int32_t UdmfServiceImpl::ProcessUri(const QueryOption &query, UnifiedData &unifiedData) { std::string localDeviceId = PreProcessUtils::GetLocalDeviceId(); @@ -232,18 +259,15 @@ int32_t UdmfServiceImpl::ProcessUri(const QueryOption &query, UnifiedData &unifi if (localDeviceId != sourceDeviceId) { SetRemoteUri(query, records); } - std::string bundleName; if (!PreProcessUtils::GetHapBundleNameByToken(query.tokenId, bundleName)) { ZLOGE("GetHapBundleNameByToken fail, key=%{public}s, tokenId=%{private}d.", query.key.c_str(), query.tokenId); return E_ERROR; } - - if (localDeviceId == sourceDeviceId && bundleName == unifiedData.GetRuntime()->sourcePackage) { + if (localDeviceId == sourceDeviceId && query.tokenId == unifiedData.GetRuntime()->tokenId) { ZLOGW("No need to grant uri permissions, queryKey=%{public}s.", query.key.c_str()); return E_OK; } - std::vector allUri; for (auto record : records) { if (record != nullptr && PreProcessUtils::IsFileType(record->GetType())) { @@ -260,7 +284,9 @@ int32_t UdmfServiceImpl::ProcessUri(const QueryOption &query, UnifiedData &unifi allUri.push_back(uri); } } - if (UriPermissionManager::GetInstance().GrantUriPermission(allUri, bundleName, query.key) != E_OK) { + if (UriPermissionManager::GetInstance().GrantUriPermission(allUri, query.tokenId, query.key) != E_OK) { + RADAR_REPORT(BizScene::GET_DATA, GetDataStage::GRANT_URI_PERMISSION, StageRes::FAILED, + ERROR_CODE, E_NO_PERMISSION); ZLOGE("GrantUriPermission fail, bundleName=%{public}s, key=%{public}s.", bundleName.c_str(), query.key.c_str()); return E_NO_PERMISSION; @@ -458,6 +484,7 @@ int32_t UdmfServiceImpl::AddPrivilege(const QueryOption &query, Privilege &privi int32_t UdmfServiceImpl::Sync(const QueryOption &query, const std::vector &devices) { ZLOGD("start"); + RADAR_REPORT(BizScene::SYNC_DATA, SyncDataStage::SYNC_BEGIN, StageRes::IDLE, BIZ_STATE, BizState::DFX_BEGIN); UnifiedKey key(query.key); if (!key.IsValid()) { ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str()); @@ -472,8 +499,11 @@ int32_t UdmfServiceImpl::Sync(const QueryOption &query, const std::vectorSync(devices) != E_OK) { ZLOGE("Store sync failed, intention: %{public}s.", key.intention.c_str()); + RADAR_REPORT(BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::FAILED, ERROR_CODE, E_DB_ERROR, + BIZ_STATE, BizState::DFX_ABNORMAL_END); return E_DB_ERROR; } + RADAR_REPORT(BizScene::SYNC_DATA, SyncDataStage::SYNC_BEGIN, StageRes::SUCCESS); return E_OK; } @@ -509,6 +539,89 @@ int32_t UdmfServiceImpl::IsRemoteData(const QueryOption &query, bool &result) return E_OK; } +int32_t UdmfServiceImpl::SetAppShareOption(const std::string &intention, int32_t shareOption) +{ + if (intention.empty() || shareOption >= SHARE_OPTIONS_BUTT || shareOption < IN_APP) { + ZLOGE("SetAppShareOption : para is invalid, intention: %{public}s, shareOption:%{public}d.", + intention.c_str(), shareOption); + return E_INVALID_PARAMETERS; + } + + uint64_t accessTokenIDEx = IPCSkeleton::GetCallingFullTokenID(); + bool isSystemApp = TokenIdKit::IsSystemAppByFullTokenID(accessTokenIDEx); + if (!isSystemApp) { + ZLOGE("no system permission, intention: %{public}s.", intention.c_str()); + return E_NO_PERMISSION; + } + auto store = StoreCache::GetInstance().GetStore(intention); + if (store == nullptr) { + ZLOGE("Get store failed, intention: %{public}s.", intention.c_str()); + return E_DB_ERROR; + } + + std::string shareOptionTmp; + if (store->GetLocal(std::to_string(accessTokenIDEx), shareOptionTmp) == E_OK) { + ZLOGE("SetAppShareOption failed, shareOption has already been set, %{public}s.", shareOptionTmp.c_str()); + return E_SETTINGS_EXISTED; + } + + if (store->PutLocal(std::to_string(accessTokenIDEx), ShareOptionsUtil::GetEnumStr(shareOption)) != E_OK) { + ZLOGE("Store get unifiedData failed, intention: %{public}d.", shareOption); + return E_DB_ERROR; + } + return E_OK; +} + +int32_t UdmfServiceImpl::GetAppShareOption(const std::string &intention, int32_t &shareOption) +{ + if (intention.empty()) { + ZLOGE("GetAppShareOption : para is invalid, %{public}s is invalid.", intention.c_str()); + return E_INVALID_PARAMETERS; + } + uint64_t accessTokenIDEx = IPCSkeleton::GetCallingFullTokenID(); + auto store = StoreCache::GetInstance().GetStore(intention); + if (store == nullptr) { + ZLOGE("Get store failed, intention: %{public}s.", intention.c_str()); + return E_DB_ERROR; + } + std::string appShareOption; + int32_t ret = store->GetLocal(std::to_string(accessTokenIDEx), appShareOption); + if (ret != E_OK) { + ZLOGE("GetAppShareOption empty, intention: %{public}s.", intention.c_str()); + return ret; + } + ZLOGI("GetAppShareOption, intention: %{public}s, appShareOption:%{public}s.", + intention.c_str(), appShareOption.c_str()); + shareOption = ShareOptionsUtil::GetEnumNum(appShareOption); + return E_OK; +} + +int32_t UdmfServiceImpl::RemoveAppShareOption(const std::string &intention) +{ + if (intention.empty()) { + ZLOGE("intention: %{public}s is invalid.", intention.c_str()); + return E_INVALID_PARAMETERS; + } + uint64_t accessTokenIDEx = IPCSkeleton::GetCallingFullTokenID(); + bool isSystemApp = TokenIdKit::IsSystemAppByFullTokenID(accessTokenIDEx); + if (!isSystemApp) { + ZLOGE("no system permission, intention: %{public}s.", intention.c_str()); + return E_NO_PERMISSION; + } + auto store = StoreCache::GetInstance().GetStore(intention); + if (store == nullptr) { + ZLOGE("Get store failed, intention: %{public}s.", intention.c_str()); + return E_DB_ERROR; + } + + UnifiedData unifiedData; + if (store->DeleteLocal(std::to_string(accessTokenIDEx)) != E_OK) { + ZLOGE("Store DeleteLocal failed, intention: %{public}s.", intention.c_str()); + return E_DB_ERROR; + } + return E_OK; +} + int32_t UdmfServiceImpl::OnInitialize() { ZLOGD("start"); @@ -557,6 +670,7 @@ int32_t UdmfServiceImpl::OnBind(const BindInfo &bindInfo) executors_ = bindInfo.executors; StoreCache::GetInstance().SetThreadPool(bindInfo.executors); LifeCycleManager::GetInstance().SetThreadPool(bindInfo.executors); + UriPermissionManager::GetInstance().SetThreadPool(bindInfo.executors); return 0; } 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 c1225340..e172fe22 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.h +++ b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.h @@ -26,13 +26,13 @@ #include "udmf_service_stub.h" #include "unified_data.h" #include "unified_types.h" - +#include "visibility.h" namespace OHOS { namespace UDMF { /* * UDMF server implementation */ -class UdmfServiceImpl final : public UdmfServiceStub { +class API_EXPORT UdmfServiceImpl final : public UdmfServiceStub { public: UdmfServiceImpl(); ~UdmfServiceImpl() = default; @@ -46,6 +46,9 @@ public: int32_t AddPrivilege(const QueryOption &query, Privilege &privilege) override; int32_t Sync(const QueryOption &query, const std::vector &devices) override; int32_t IsRemoteData(const QueryOption &query, bool &result) override; + int32_t SetAppShareOption(const std::string &intention, int32_t shareOption) override; + int32_t GetAppShareOption(const std::string &intention, int32_t &shareOption) override; + int32_t RemoveAppShareOption(const std::string &intention) override; int32_t OnInitialize() override; int32_t OnBind(const BindInfo &bindInfo) override; @@ -56,6 +59,7 @@ private: int32_t ProcessUri(const QueryOption &query, UnifiedData &unifiedData); void SetRemoteUri(const QueryOption &query, std::vector> &records); bool IsPermissionInCache(const QueryOption &query); + bool IsReadAndKeep(const std::vector &privileges, const QueryOption &query); using StaticActs = DistributedData::StaticActs; class UdmfStatic : public StaticActs { diff --git a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.cpp b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.cpp index 94a4f6af..c71b3572 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.cpp @@ -216,5 +216,52 @@ int32_t UdmfServiceStub::OnIsRemoteData(MessageParcel &data, MessageParcel &repl } return E_OK; } + +int32_t UdmfServiceStub::OnSetAppShareOption(MessageParcel &data, MessageParcel &reply) +{ + std::string intention; + int32_t shareOption; + if (!ITypesUtil::Unmarshal(data, intention, shareOption)) { + ZLOGE("Unmarshal query failed"); + return E_READ_PARCEL_ERROR; + } + int32_t status = SetAppShareOption(intention, shareOption); + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal OnSetAppShareOption status failed, status: %{public}d", status); + return E_WRITE_PARCEL_ERROR; + } + return E_OK; +} + +int32_t UdmfServiceStub::OnGetAppShareOption(MessageParcel &data, MessageParcel &reply) +{ + std::string intention; + int32_t shareOption = SHARE_OPTIONS_BUTT; + if (!ITypesUtil::Unmarshal(data, intention)) { + ZLOGE("Unmarshal query failed"); + return E_READ_PARCEL_ERROR; + } + int32_t status = GetAppShareOption(intention, shareOption); + if (!ITypesUtil::Marshal(reply, status, shareOption)) { + ZLOGE("Marshal OnGetAppShareOption status failed, status: %{public}d", status); + return E_WRITE_PARCEL_ERROR; + } + return E_OK; +} + +int32_t UdmfServiceStub::OnRemoveAppShareOption(MessageParcel &data, MessageParcel &reply) +{ + std::string intention; + if (!ITypesUtil::Unmarshal(data, intention)) { + ZLOGE("Unmarshal query failed"); + return E_READ_PARCEL_ERROR; + } + int32_t status = RemoveAppShareOption(intention); + if (!ITypesUtil::Marshal(reply, status)) { + ZLOGE("Marshal OnRemoveAppShareOption status failed, status: %{public}d", status); + return E_WRITE_PARCEL_ERROR; + } + return E_OK; +} } // namespace UDMF } // namespace OHOS \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.h b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.h index 90967b43..0cd2879f 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.h +++ b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_stub.h @@ -45,6 +45,9 @@ private: int32_t OnAddPrivilege(MessageParcel &data, MessageParcel &reply); int32_t OnSync(MessageParcel &data, MessageParcel &reply); int32_t OnIsRemoteData(MessageParcel &data, MessageParcel &reply); + int32_t OnSetAppShareOption(MessageParcel &data, MessageParcel &reply); + int32_t OnGetAppShareOption(MessageParcel &data, MessageParcel &reply); + int32_t OnRemoveAppShareOption(MessageParcel &data, MessageParcel &reply); using Handler = int32_t (UdmfServiceStub::*)(MessageParcel &data, MessageParcel &reply); static constexpr Handler HANDLERS[static_cast(UdmfServiceInterfaceCode::CODE_BUTT)] = { @@ -56,7 +59,10 @@ private: &UdmfServiceStub::OnGetSummary, &UdmfServiceStub::OnAddPrivilege, &UdmfServiceStub::OnSync, - &UdmfServiceStub::OnIsRemoteData + &UdmfServiceStub::OnIsRemoteData, + &UdmfServiceStub::OnSetAppShareOption, + &UdmfServiceStub::OnGetAppShareOption, + &UdmfServiceStub::OnRemoveAppShareOption }; }; } // namespace UDMF 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 31944b77..548472b9 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 @@ -57,6 +57,7 @@ sptr CustomUtdInstaller::GetBundleManager() auto bmsProxy = samgrProxy->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); if (bmsProxy == nullptr) { ZLOGE("failed to get bms from samgrProxy."); + return nullptr; } return iface_cast(bmsProxy); } @@ -139,6 +140,10 @@ int32_t CustomUtdInstaller::UninstallUtd(const std::string &bundleName, int32_t std::vector CustomUtdInstaller::GetHapModules(const std::string &bundleName, int32_t user) { auto bundlemgr = GetBundleManager(); + if (bundlemgr == nullptr) { + ZLOGE("Get bms service failed, bundleName: %{public}s.", bundleName.c_str()); + return {}; + } AppExecFwk::BundleInfo bundleInfo; if (!bundlemgr->GetBundleInfo(bundleName, AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, bundleInfo, user)) { ZLOGE("Get local bundle info failed, bundleName: %{public}s.", bundleName.c_str()); @@ -152,6 +157,10 @@ CustomUtdCfgs CustomUtdInstaller::GetModuleCustomUtdTypes(const std::string &bun auto bundlemgr = GetBundleManager(); std::string jsonStr; CustomUtdCfgs typeCfgs; + if (bundlemgr == nullptr) { + ZLOGE("Get bms service failed, bundleName: %{public}s.", bundleName.c_str()); + return typeCfgs; + } auto status = bundlemgr->GetJsonProfile(AppExecFwk::ProfileType::UTD_SDT_PROFILE, bundleName, moduleName, jsonStr, user); if (status != NO_ERROR) { diff --git a/datamgr_service/services/distributeddataservice/service/waterversion/water_version_manager.cpp b/datamgr_service/services/distributeddataservice/service/waterversion/water_version_manager.cpp index c2547e76..3a41a383 100644 --- a/datamgr_service/services/distributeddataservice/service/waterversion/water_version_manager.cpp +++ b/datamgr_service/services/distributeddataservice/service/waterversion/water_version_manager.cpp @@ -17,10 +17,12 @@ #include "checker/checker_manager.h" #include "cloud/cloud_sync_finished_event.h" +#include "device_matrix.h" #include "store/auto_cache.h" #include "device_manager_adapter.h" #include "eventcenter/event_center.h" #include "log_print.h" +#include "metadata/matrix_meta_data.h" #include "metadata/meta_data_manager.h" #include "metadata/store_meta_data.h" #include "utils/anonymous.h" @@ -41,6 +43,7 @@ WaterVersionManager::WaterVersionManager() : waterVersions_(BUTT) waterVersions_[i].SetType(static_cast(i)); } } +WaterVersionManager::~WaterVersionManager() {} void WaterVersionManager::Init() { @@ -75,9 +78,18 @@ void WaterVersionManager::Init() }); } -std::string WaterVersionManager::GenerateWaterVersion(const std::string &bundleName, const std::string &storeName, - Type type) +std::string WaterVersionManager::GenerateWaterVersion(const std::string &bundleName, const std::string &storeName) { + auto type = BUTT; + CheckerManager::StoreInfo info; + info.bundleName = bundleName; + info.storeId = storeName; + if (CheckerManager::GetInstance().IsDynamic(info)) { + type = DYNAMIC; + } + if (CheckerManager::GetInstance().IsStatic(info)) { + type = STATIC; + } if (type < 0 || type >= BUTT || bundleName.empty() || storeName.empty()) { ZLOGE("invalid args. bundleName:%{public}s, storeName:%{public}s, type:%{public}d", bundleName.c_str(), Anonymous::Change(storeName).c_str(), type); @@ -87,6 +99,41 @@ std::string WaterVersionManager::GenerateWaterVersion(const std::string &bundleN return success ? Serializable::Marshall(meta) : ""; } +std::string WaterVersionManager::GetWaterVersion(const std::string &bundleName, const std::string &storeName) +{ + auto type = BUTT; + CheckerManager::StoreInfo info; + info.bundleName = bundleName; + info.storeId = storeName; + if (CheckerManager::GetInstance().IsDynamic(info)) { + type = DYNAMIC; + } + if (CheckerManager::GetInstance().IsStatic(info)) { + type = STATIC; + } + if (type < 0 || type >= BUTT || bundleName.empty() || storeName.empty()) { + ZLOGE("invalid args. bundleName:%{public}s, storeName:%{public}s, type:%{public}d", bundleName.c_str(), + Anonymous::Change(storeName).c_str(), type); + return ""; + } + auto [success, meta] = waterVersions_[type].GetWaterVersion(DMAdapter::GetInstance().GetLocalDevice().uuid); + if (!success) { + return ""; + } + auto target = Merge(bundleName, storeName); + int i = 0; + for (auto &key : meta.keys) { + if (key == target) { + meta.waterVersion = meta.infos[i][i]; + return Serializable::Marshall(meta); + } + i++; + } + ZLOGE("invalid args. bundleName:%{public}s, storeName:%{public}s, meta:%{public}d", bundleName.c_str(), + Anonymous::Change(storeName).c_str(), type); + return ""; +} + std::pair WaterVersionManager::GetVersion(const std::string &deviceId, WaterVersionManager::Type type) { @@ -112,12 +159,14 @@ bool WaterVersionManager::SetWaterVersion(const std::string &bundleName, const s const std::string &waterVersion) { WaterVersionMetaData metaData; - if (!Serializable::Unmarshall(waterVersion, metaData) || metaData.deviceId.empty() || !metaData.IsValid() || - metaData.deviceId == DMAdapter::GetInstance().GetLocalDevice().uuid) { + if (!Serializable::Unmarshall(waterVersion, metaData) || metaData.deviceId.empty() || !metaData.IsValid()) { ZLOGE("invalid args. meta:%{public}s, bundleName:%{public}s, storeName:%{public}s", metaData.ToAnonymousString().c_str(), bundleName.c_str(), Anonymous::Change(storeName).c_str()); return false; } + if (metaData.deviceId == DMAdapter::GetInstance().GetLocalDevice().uuid) { + return false; + } return waterVersions_[metaData.type].SetWaterVersion(Merge(bundleName, storeName), metaData); } @@ -171,17 +220,26 @@ bool WaterVersionManager::InitMeta(WaterVersionMetaData &metaData) void WaterVersionManager::UpdateWaterVersion(WaterVersionMetaData &metaData) { ZLOGI("before update meta:%{public}s", metaData.ToAnonymousString().c_str()); + uint64_t maxVersion = 0; + uint64_t consistentVersion = 0; for (size_t i = 0; i < metaData.keys.size(); ++i) { for (size_t j = 0; j < metaData.keys.size(); ++j) { + maxVersion = std::max(maxVersion, metaData.infos[j][j]); if (metaData.infos[i][j] > metaData.infos[j][j]) { break; } - if (j == metaData.keys.size() - 1 && metaData.infos[i][i] > metaData.waterVersion) { - metaData.waterVersion = metaData.infos[i][i]; + if (j == metaData.keys.size() - 1 && metaData.infos[i][i] > consistentVersion) { + consistentVersion = metaData.infos[i][i]; } } } - ZLOGI("after update meta:%{public}s", metaData.ToAnonymousString().c_str()); + if (consistentVersion > metaData.waterVersion || maxVersion < metaData.waterVersion) { + metaData.waterVersion = consistentVersion; + SaveMatrix(metaData); + ZLOGI("after update meta:%{public}s", metaData.ToAnonymousString().c_str()); + } else { + ZLOGD("after update meta:%{public}s", metaData.ToAnonymousString().c_str()); + } } std::string WaterVersionManager::Merge(const std::string &bundleName, const std::string &storeName) @@ -220,7 +278,7 @@ WaterVersionMetaData WaterVersionManager::Upgrade(const std::vector newMeta.waterVersion = meta.waterVersion; newMeta.type = meta.type; newMeta.infos = { keys.size(), std::vector(keys.size(), 0) }; - std::map mp; + std::map mp; for (size_t i = 0; i < keys.size(); ++i) { for (size_t j = 0; j < meta.keys.size(); ++j) { if (meta.keys[j] == keys[i]) { @@ -243,6 +301,13 @@ WaterVersionMetaData WaterVersionManager::Upgrade(const std::vector return newMeta; } +void WaterVersionManager::SaveMatrix(const WaterVersionMetaData &metaData) +{ + auto localUuid = DMAdapter::GetInstance().GetLocalDevice().uuid; + DeviceMatrix::GetInstance().UpdateLevel(metaData.deviceId, metaData.GetLevel(), + metaData.type == STATIC ? DeviceMatrix::STATICS : DeviceMatrix::DYNAMIC, metaData.deviceId != localUuid); +} + bool WaterVersionMetaData::Marshal(Serializable::json &node) const { SetValue(node[GET_NAME(deviceId)], deviceId); @@ -283,7 +348,7 @@ std::string WaterVersionMetaData::GetKey() const return Constant::Join(KEY_PREFIX, Constant::KEY_SEPARATOR, { deviceId, std::to_string(type) }); } -uint64_t WaterVersionMetaData::GetVersion() +uint64_t WaterVersionMetaData::GetVersion() const { return waterVersion; } @@ -316,6 +381,11 @@ void WaterVersionManager::WaterVersion::SetType(WaterVersionManager::Type type) void WaterVersionManager::WaterVersion::AddKey(const std::string &key) { + for (auto &tmp : keys_) { + if (tmp == key) { + return; + } + } keys_.push_back(key); } @@ -351,9 +421,12 @@ std::pair WaterVersionManager::WaterVersion::Generat metaData.infos[i][j] = metaData.infos[j][j]; } ZLOGI("generate meta:%{public}s", metaData.ToAnonymousString().c_str()); - return { MetaDataManager::GetInstance().SaveMeta(metaData.GetKey(), metaData, true) && - versions_.Set(DMAdapter::GetInstance().GetLocalDevice().uuid, metaData), - metaData }; + if (MetaDataManager::GetInstance().SaveMeta(metaData.GetKey(), metaData, true) && + versions_.Set(metaData.deviceId, metaData)) { + SaveMatrix(metaData); + return { true, metaData }; + } + return { false, metaData }; } return { false, metaData }; } @@ -370,6 +443,7 @@ std::pair WaterVersionManager::WaterVersion::GetWate versions_.Set(deviceId, meta); return { true, meta }; } + ZLOGW("no meta. deviceId:%{public}s", Anonymous::Change(deviceId).c_str()); return { false, meta }; } @@ -385,26 +459,29 @@ bool WaterVersionManager::WaterVersion::SetWaterVersion(const std::string &key, std::lock_guard lock(mutex_); if (!versions_.Get(metaData.deviceId, oldMeta) && !MetaDataManager::GetInstance().LoadMeta(metaData.GetKey(), oldMeta, true)) { - ZLOGI("save meta:%{public}s", metaData.ToAnonymousString().c_str()); - oldMeta = metaData; - UpdateWaterVersion(oldMeta); - return MetaDataManager::GetInstance().SaveMeta(oldMeta.GetKey(), oldMeta, true) && - versions_.Set(metaData.deviceId, oldMeta); - } - if (oldMeta.keys.size() != metaData.keys.size() || oldMeta.version != metaData.version) { - ZLOGI("upgrade meta. old:%{public}s, new:%{public}s", oldMeta.ToAnonymousString().c_str(), - metaData.ToAnonymousString().c_str()); - oldMeta = metaData; - for (size_t i = 0; i < metaData.keys.size(); ++i) { - // Set all unSync items to 0 - if (metaData.keys[i] != key) { - oldMeta.infos[i] = std::vector(metaData.keys.size(), 0); + ZLOGI("no meta. deviceId:%{public}s", Anonymous::Change(metaData.deviceId).c_str()); + oldMeta.version = WaterVersionMetaData::DEFAULT_VERSION; + oldMeta.deviceId = metaData.deviceId; + oldMeta.keys = keys_; + oldMeta.type = metaData.type; + oldMeta.waterVersion = 0; + oldMeta.infos = { keys_.size(), std::vector(keys_.size(), 0) }; + } + + if (keys_ == metaData.keys) { + for (size_t i = 0; i < oldMeta.keys.size(); ++i) { + if (oldMeta.keys[i] == key) { + oldMeta.infos[i] = metaData.infos[i]; + break; } } } else { + auto upgradeMeta = Upgrade(keys_, metaData); + ZLOGI("upgrade meta. before:%{public}s, after:%{public}s", metaData.ToAnonymousString().c_str(), + upgradeMeta.ToAnonymousString().c_str()); for (size_t i = 0; i < oldMeta.keys.size(); ++i) { if (oldMeta.keys[i] == key) { - oldMeta.infos[i] = metaData.infos[i]; + oldMeta.infos[i] = upgradeMeta.infos[i]; break; } } @@ -427,10 +504,9 @@ bool WaterVersionManager::WaterVersion::InitWaterVersion(const WaterVersionMetaD { if (keys_ != metaData.keys || metaData.version != WaterVersionMetaData::DEFAULT_VERSION) { auto meta = Upgrade(keys_, metaData); - MetaDataManager::GetInstance().SaveMeta(meta.GetKey(), meta, true); - versions_.Set(meta.deviceId, meta); + return MetaDataManager::GetInstance().SaveMeta(meta.GetKey(), meta, true) && + versions_.Set(meta.deviceId, meta); } - versions_.Set(metaData.deviceId, metaData); - return true; + return versions_.Set(metaData.deviceId, metaData); } } // namespace OHOS::DistributedData diff --git a/datamgr_service/services/distributeddataservice/service/waterversion/water_version_manager.h b/datamgr_service/services/distributeddataservice/service/waterversion/water_version_manager.h index 640f31da..bdf83e9f 100644 --- a/datamgr_service/services/distributeddataservice/service/waterversion/water_version_manager.h +++ b/datamgr_service/services/distributeddataservice/service/waterversion/water_version_manager.h @@ -43,16 +43,21 @@ public: bool IsValid(); std::string ToAnonymousString() const; std::string GetKey() const; - uint64_t GetVersion(); + uint64_t GetVersion() const; + uint16_t GetLevel() const + { + // low 4 bit is mask + return (waterVersion & 0xFFF) << 4; + } static std::string GetPrefix(); private: static constexpr const char *KEY_PREFIX = "WaterVersionMeta"; }; - static WaterVersionManager &GetInstance(); - WaterVersionManager(); - void Init(); - std::string GenerateWaterVersion(const std::string &bundleName, const std::string &storeName, Type type); + API_EXPORT static WaterVersionManager &GetInstance(); + API_EXPORT void Init(); + API_EXPORT std::string GenerateWaterVersion(const std::string &bundleName, const std::string &storeName); + std::string GetWaterVersion(const std::string &bundleName, const std::string &storeName); std::pair GetVersion(const std::string &deviceId, Type type); std::string GetWaterVersion(const std::string &deviceId, Type type); bool SetWaterVersion(const std::string &bundleName, const std::string &storeName, @@ -60,6 +65,12 @@ public: bool DelWaterVersion(const std::string &deviceId); private: + WaterVersionManager(); + ~WaterVersionManager(); + WaterVersionManager(const WaterVersionManager &) = delete; + WaterVersionManager(WaterVersionManager &&) noexcept = delete; + WaterVersionManager& operator=(const WaterVersionManager &) = delete; + WaterVersionManager& operator=(WaterVersionManager &&) = delete; static constexpr size_t MAX_DEVICES = 16; class WaterVersion { public: @@ -78,13 +89,14 @@ private: std::vector keys_; LRUBucket versions_{ MAX_DEVICES }; }; - static bool InitMeta(WaterVersionMetaData &); + static bool InitMeta(WaterVersionMetaData &metaData); static WaterVersionMetaData Upgrade(const std::vector &keys, const WaterVersionMetaData& meta); static std::string Merge(const std::string &bundleName, const std::string &storeName); static std::pair Split(const std::string &key); static void UpdateWaterVersion(WaterVersionMetaData &metaData); + static void SaveMatrix(const WaterVersionMetaData &metaData); std::vector waterVersions_; }; } // namespace DistributedData } // namespace OHOS -#endif //OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_WATER_MANAGER_H +#endif //OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_WATER_MANAGER_H \ No newline at end of file diff --git a/interface_sdk/api/@ohos.application.DataShareExtensionAbility.d.ts b/interface_sdk/api/@ohos.application.DataShareExtensionAbility.d.ts index 8b80c648..72557ae3 100644 --- a/interface_sdk/api/@ohos.application.DataShareExtensionAbility.d.ts +++ b/interface_sdk/api/@ohos.application.DataShareExtensionAbility.d.ts @@ -29,6 +29,7 @@ import dataShare from './@ohos.data.dataShare'; * Struct for a batch update operation. * * @syscap SystemCapability.DistributedDataManager.DataShare.Provider + * @systemapi * @stagemodelonly * @since 12 */ diff --git a/interface_sdk/api/@ohos.data.cloudData.d.ts b/interface_sdk/api/@ohos.data.cloudData.d.ts index 886dc281..22288866 100644 --- a/interface_sdk/api/@ohos.data.cloudData.d.ts +++ b/interface_sdk/api/@ohos.data.cloudData.d.ts @@ -89,7 +89,7 @@ declare namespace cloudData { /** * Extra data, which contains the following fields. - * { + * '{ * "data": "{ * "accountId": "aaa", * "bundleName": "com.bbb.xxx", @@ -97,7 +97,7 @@ declare namespace cloudData { * "databaseScopes": ["private", "shared"], * "recordTypes": ["xxx", "yyy", "zzz"] * }" - * } + * }' * All fields are mandatory. * * @type { string } @@ -373,8 +373,7 @@ declare namespace cloudData { * @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 } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2. Incorrect parameter types; * 3. Parameter verification failed. * @throws { BusinessError } 801 - Capability not supported. @@ -394,8 +393,7 @@ declare namespace cloudData { * to return the data changes. * @throws { BusinessError } 201 - Permission verification failed, which * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2. Incorrect parameter types; * 3. Parameter verification failed. * @throws { BusinessError } 801 - Capability not supported. @@ -416,8 +414,7 @@ declare namespace cloudData { * to return the data changes. * @throws { BusinessError } 201 - Permission verification failed, which * is usually returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2. Incorrect parameter types; * 3. Parameter verification failed. * @throws { BusinessError } 801 - Capability not supported. @@ -472,7 +469,7 @@ declare namespace cloudData { * @param { string } [storeId] - Indicates the store ID. * @returns { Promise>> } Promise used to return the result. * @throws { BusinessError } 201 - Permission verification failed, usually the result returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission denied. The application is not a system application. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2. Incorrect parameter types; * 3. Parameter verification failed. * @throws { BusinessError } 801 - Capability not supported. @@ -495,8 +492,9 @@ declare namespace cloudData { * @param { string } [storeId] - Indicates the store ID. * @returns { Promise> } Promise used to return the result. * @throws { BusinessError } 201 - Permission verification failed, usually the result returned by VerifyAccessToken. - * @throws { BusinessError } 202 - Permission denied. The application is not a system application. - * @throws { BusinessError } 401 - Parameter error. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. + * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2. Incorrect parameter types; + * 3. Parameter verification failed. * @throws { BusinessError } 801 - Capability not supported. * @syscap SystemCapability.DistributedDataManager.CloudSync.Config * @systemapi @@ -1064,8 +1062,7 @@ declare namespace cloudData { * @param { Array } participants - Participants to share. * @param { Array } [columns] - Columns to be shared. * @returns { Promise } - Promise used to return {@link relationalStore.ResultSet}. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2. Incorrect parameter types; * 3. Parameter verification failed. * @throws { BusinessError } 801 - Capability not supported. @@ -1089,8 +1086,7 @@ declare namespace cloudData { * @param { Array } participants - Participants to share. * @param { AsyncCallback } callback - Indicates the * callback invoked to return the {@link relationalStore.ResultSet}. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2. Incorrect parameter types; * 3. Parameter verification failed. * @throws { BusinessError } 801 - Capability not supported. @@ -1115,8 +1111,7 @@ declare namespace cloudData { * @param { Array } columns - Columns to be shared. * @param { AsyncCallback } callback - Indicates the * callback invoked to return the {@link relationalStore.ResultSet}. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2. Incorrect parameter types; * 3. Parameter verification failed. * @throws { BusinessError } 801 - Capability not supported. @@ -1140,8 +1135,7 @@ declare namespace cloudData { * involved in the data sharing. * @param { AsyncCallback>>> } callback - Indicates the * callback invoked to return the result. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2. Incorrect parameter types; * 3. Parameter verification failed. * @throws { BusinessError } 801 - Capability not supported. @@ -1162,8 +1156,7 @@ declare namespace cloudData { * @param { Array } participants - Indicates the participants * involved in the data sharing. * @returns { Promise>>> } - Promise used to return the result. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2. Incorrect parameter types; * 3. Parameter verification failed. * @throws { BusinessError } 801 - Capability not supported. @@ -1184,8 +1177,7 @@ declare namespace cloudData { * involved. * @param { AsyncCallback>>> } callback - Indicates the callback invoked * to return the result. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2. Incorrect parameter types; * 3. Parameter verification failed. * @throws { BusinessError } 801 - Capability not supported. @@ -1206,8 +1198,7 @@ declare namespace cloudData { * @param { Array } participants - Indicates the participants * involved. * @returns { Promise>>> } - Promise used to return the result. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2. Incorrect parameter types; * 3. Parameter verification failed. * @throws { BusinessError } 801 - Capability not supported. @@ -1225,8 +1216,7 @@ declare namespace cloudData { * * @param { string } sharingResource - Indicates the sharing resource. * @param { AsyncCallback> } callback - The callback of exit. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2. Incorrect parameter types; * 3. Parameter verification failed. * @throws { BusinessError } 801 - Capability not supported. @@ -1241,8 +1231,7 @@ declare namespace cloudData { * * @param { string } sharingResource - Indicates the sharing resource. * @returns { Promise> } - The promise returned by the function. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2. Incorrect parameter types; * 3. Parameter verification failed. * @throws { BusinessError } 801 - Capability not supported. @@ -1260,8 +1249,7 @@ declare namespace cloudData { * whose permissions are to be changed. * @param { AsyncCallback>>> } callback - Indicates the * callback invoked to return the result. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2. Incorrect parameter types; * 3. Parameter verification failed. * @throws { BusinessError } 801 - Capability not supported. @@ -1282,8 +1270,7 @@ declare namespace cloudData { * @param { Array } participants - Indicates the participants * whose permissions are to be changed. * @returns { Promise>>> } - Promise used to return the result. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2. Incorrect parameter types; * 3. Parameter verification failed. * @throws { BusinessError } 801 - Capability not supported. @@ -1302,8 +1289,7 @@ declare namespace cloudData { * @param { string } sharingResource - Indicates the sharing resource. * @param { AsyncCallback>> } callback - Indicates the * callback invoked to return the participants obtained. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2. Incorrect parameter types; * 3. Parameter verification failed. * @throws { BusinessError } 801 - Capability not supported. @@ -1318,8 +1304,7 @@ declare namespace cloudData { * * @param { string } sharingResource - Indicates the sharing resource. * @returns { Promise>> } - Promise used to return the result. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2. Incorrect parameter types; * 3. Parameter verification failed. * @throws { BusinessError } 801 - Capability not supported. @@ -1335,8 +1320,7 @@ declare namespace cloudData { * @param { string } invitationCode - Indicates the invitation code. * @param { AsyncCallback>> } callback - Indicates the * callback invoked to return the participants obtained. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2. Incorrect parameter types; * 3. Parameter verification failed. * @throws { BusinessError } 801 - Capability not supported. @@ -1354,8 +1338,7 @@ declare namespace cloudData { * * @param { string } invitationCode - Indicates the invitation code. * @returns { Promise>> } - Promise used to return the result. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2. Incorrect parameter types; * 3. Parameter verification failed. * @throws { BusinessError } 801 - Capability not supported. @@ -1372,8 +1355,7 @@ declare namespace cloudData { * @param { State } state - Indicates the state of invitation. * @param { AsyncCallback> } callback - Indicates the callback * invoked to return the sharing resource. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2. Incorrect parameter types; * 3. Parameter verification failed. * @throws { BusinessError } 801 - Capability not supported. @@ -1389,8 +1371,7 @@ declare namespace cloudData { * @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 } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2. Incorrect parameter types; * 3. Parameter verification failed. * @throws { BusinessError } 801 - Capability not supported. @@ -1406,8 +1387,7 @@ declare namespace cloudData { * @param { string } sharingResource - Indicates the sharing resource. * @param { State } state - Indicates the state of invitation. * @param { AsyncCallback> } callback - Indicates the callback. - * @throws { BusinessError } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2. Incorrect parameter types; * 3. Parameter verification failed. * @throws { BusinessError } 801 - Capability not supported. @@ -1423,8 +1403,7 @@ declare namespace cloudData { * @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 } 202 - Permission verification failed, which is - * returned when the system API is not called by a system application. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2. Incorrect parameter types; * 3. Parameter verification failed. * @throws { BusinessError } 801 - Capability not supported. diff --git a/interface_sdk/api/@ohos.data.commonType.d.ts b/interface_sdk/api/@ohos.data.commonType.d.ts index 18b0c1a5..112b97db 100644 --- a/interface_sdk/api/@ohos.data.commonType.d.ts +++ b/interface_sdk/api/@ohos.data.commonType.d.ts @@ -107,7 +107,14 @@ declare namespace commonType { * @crossplatform * @since 11 */ - name: string; + /** + * The name of asset. + * @type { string | undefined } + * @syscap SystemCapability.DistributedDataManager.CommonType + * @crossplatform + * @since 12 + */ + name: string | undefined; /** * The uri of asset. @@ -117,7 +124,15 @@ declare namespace commonType { * @crossplatform * @since 11 */ - uri: string; + /** + * The uri of asset. + * + * @type { string | undefined } + * @syscap SystemCapability.DistributedDataManager.CommonType + * @crossplatform + * @since 12 + */ + uri: string | undefined; /** * The path of asset. @@ -127,7 +142,15 @@ declare namespace commonType { * @crossplatform * @since 11 */ - path: string; + /** + * The path of asset. + * + * @type { string | undefined } + * @syscap SystemCapability.DistributedDataManager.CommonType + * @crossplatform + * @since 12 + */ + path: string | undefined; /** * The created time of asset. @@ -137,7 +160,15 @@ declare namespace commonType { * @crossplatform * @since 11 */ - createTime: string; + /** + * The created time of asset. + * + * @type { string | undefined } + * @syscap SystemCapability.DistributedDataManager.CommonType + * @crossplatform + * @since 12 + */ + createTime: string | undefined; /** * The modified time of asset. If this field changes, the asset is considered to have changed. @@ -147,7 +178,15 @@ declare namespace commonType { * @crossplatform * @since 11 */ - modifyTime: string; + /** + * The modified time of asset. If this field changes, the asset is considered to have changed. + * + * @type { string | undefined } + * @syscap SystemCapability.DistributedDataManager.CommonType + * @crossplatform + * @since 12 + */ + modifyTime: string | undefined; /** * The size of asset. If this field changes, the asset is considered to have changed. @@ -157,7 +196,15 @@ declare namespace commonType { * @crossplatform * @since 11 */ - size: string; + /** + * The size of asset. If this field changes, the asset is considered to have changed. + * + * @type { string | undefined } + * @syscap SystemCapability.DistributedDataManager.CommonType + * @crossplatform + * @since 12 + */ + size: string | undefined; /** * The status of asset. @@ -167,7 +214,15 @@ declare namespace commonType { * @crossplatform * @since 11 */ - status?: AssetStatus; + /** + * The status of asset. + * + * @type { ?(AssetStatus | undefined) } + * @syscap SystemCapability.DistributedDataManager.CommonType + * @crossplatform + * @since 12 + */ + status?: AssetStatus | undefined; } /** diff --git a/interface_sdk/api/@ohos.data.dataShare.d.ts b/interface_sdk/api/@ohos.data.dataShare.d.ts index 13508da7..93316ad3 100644 --- a/interface_sdk/api/@ohos.data.dataShare.d.ts +++ b/interface_sdk/api/@ohos.data.dataShare.d.ts @@ -137,7 +137,7 @@ declare namespace dataShare { * @returns { Promise } The promise returned by the function. * @throws { BusinessError } 401 - Parameter error.Possible causes: 1. Mandatory parameters are left unspecified; * 2. Incorrect parameters types. - * @throws { BusinessError } 15700011 - The uri is not exist. + * @throws { BusinessError } 15700011 - The URI is not exist. * @syscap SystemCapability.DistributedDataManager.DataShare.Consumer * @systemapi * @stagemodelonly @@ -153,7 +153,7 @@ declare namespace dataShare { * @returns { Promise } The promise returned by the function. * @throws { BusinessError } 401 - Parameter error.Possible causes: 1. Mandatory parameters are left unspecified; * 2. Incorrect parameters types. - * @throws { BusinessError } 15700011 - The uri is not exist. + * @throws { BusinessError } 15700011 - The URI is not exist. * @syscap SystemCapability.DistributedDataManager.DataShare.Consumer * @systemapi * @stagemodelonly @@ -622,7 +622,7 @@ declare namespace dataShare { * @param { Template } template - The template to add. * @throws { BusinessError } 401 - Parameter error.Possible causes: 1. Mandatory parameters are left unspecified; * 2. Incorrect parameters types. - * @throws { BusinessError } 15700011 - The uri is not exist. + * @throws { BusinessError } 15700011 - The URI is not exist. * @syscap SystemCapability.DistributedDataManager.DataShare.Consumer * @systemapi * @stagemodelonly @@ -636,7 +636,7 @@ declare namespace dataShare { * @param { Template } template - The template to add. * @throws { BusinessError } 401 - Parameter error.Possible causes: 1. Mandatory parameters are left unspecified; * 2. Incorrect parameters types. - * @throws { BusinessError } 15700011 - The uri is not exist. + * @throws { BusinessError } 15700011 - The URI is not exist. * @throws { BusinessError } 15700013 - The DataShareHelper instance is already closed. * @throws { BusinessError } 202 - Not System Application. * @syscap SystemCapability.DistributedDataManager.DataShare.Consumer @@ -653,7 +653,7 @@ declare namespace dataShare { * @param { string } subscriberId - The subscribe id. * @throws { BusinessError } 401 - Parameter error.Possible causes: 1. Mandatory parameters are left unspecified; * 2. Incorrect parameters types. - * @throws { BusinessError } 15700011 - The uri is not exist. + * @throws { BusinessError } 15700011 - The URI is not exist. * @syscap SystemCapability.DistributedDataManager.DataShare.Consumer * @systemapi * @stagemodelonly @@ -666,7 +666,7 @@ declare namespace dataShare { * @param { string } subscriberId - The subscribe id. * @throws { BusinessError } 401 - Parameter error.Possible causes: 1. Mandatory parameters are left unspecified; * 2. Incorrect parameters types. - * @throws { BusinessError } 15700011 - The uri is not exist. + * @throws { BusinessError } 15700011 - The URI is not exist. * @throws { BusinessError } 15700013 - The DataShareHelper instance is already closed. * @throws { BusinessError } 202 - Not System Application. * @syscap SystemCapability.DistributedDataManager.DataShare.Consumer diff --git a/interface_sdk/api/@ohos.data.preferences.d.ts b/interface_sdk/api/@ohos.data.preferences.d.ts index 2a840d5c..f45788e1 100644 --- a/interface_sdk/api/@ohos.data.preferences.d.ts +++ b/interface_sdk/api/@ohos.data.preferences.d.ts @@ -105,7 +105,16 @@ declare namespace preferences { * @atomicservice * @since 11 */ - const MAX_KEY_LENGTH: 80; + /** + * Maximum length of a key. + * + * @constant + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @crossplatform + * @atomicservice + * @since 12 + */ + const MAX_KEY_LENGTH: number; /** * Indicates the maximum length of a string (8192 characters). @@ -131,7 +140,16 @@ declare namespace preferences { * @atomicservice * @since 11 */ - const MAX_VALUE_LENGTH: 8192; + /** + * Maximum length of a value. + * + * @constant + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @crossplatform + * @atomicservice + * @since 12 + */ + const MAX_VALUE_LENGTH: number; /** * Manages preferences file configurations. diff --git a/interface_sdk/api/@ohos.data.relationalStore.d.ts b/interface_sdk/api/@ohos.data.relationalStore.d.ts index 60d8efcd..3c8f47e3 100644 --- a/interface_sdk/api/@ohos.data.relationalStore.d.ts +++ b/interface_sdk/api/@ohos.data.relationalStore.d.ts @@ -367,6 +367,16 @@ declare namespace relationalStore { * @since 12 */ vector?: boolean; + + /** + * Specifies whether the database opened is read-only. + * If isReadOnly is true, other configuration items will become invalid. + * + * @type { ?boolean } + * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core + * @since 12 + */ + isReadOnly?: boolean; } /** @@ -581,6 +591,60 @@ declare namespace relationalStore { details: Record; } + /** + * Defines information about the SQL statements executed. + * + * @interface SqlExecutionInfo + * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core + * @since 12 + */ + interface SqlExecutionInfo { + /** + * Array of SQL statements executed. When the args of batchInsert is too large, there may be more than one SQL. + * + * @type { Array } + * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core + * @since 12 + */ + sql: Array; + + /** + * Total time used for executing the SQL statements, in μs. + * + * @type { number } + * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core + * @since 12 + */ + totalTime: number; + + /** + * Maximum time allowed to obtain the SQL file handle, in μs. + * + * @type { number } + * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core + * @since 12 + */ + waitTime: number; + + /** + * Time used to prepare SQL and args, in μs. + * + * @type { number } + * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core + * @since 12 + */ + prepareTime: number; + + /** + * Time used to execute the SQL statements, in μs. + * + * @type { number } + * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core + * @since 12 + */ + executeTime: number; + } + /** * Describes the {@code RdbStore} type. * @@ -1063,7 +1127,7 @@ declare namespace relationalStore { */ enum RebuildType { /** - * The database is not rebuilt. + * The database is not rebuilt or repaired. * * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core * @since 12 @@ -1076,7 +1140,15 @@ declare namespace relationalStore { * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core * @since 12 */ - REBUILT + REBUILT, + + /** + * The database is repaired. + * + * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core + * @since 12 + */ + REPAIRED } /** @@ -3037,7 +3109,7 @@ declare namespace relationalStore { * @throws { BusinessError } 801 - Capability not supported. * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. * @throws { BusinessError } 14800024 - SQLite: The database file is locked. @@ -3100,7 +3172,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -3149,7 +3221,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -3208,7 +3280,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -3257,7 +3329,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -3291,7 +3363,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -3350,7 +3422,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -3409,7 +3481,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -3442,7 +3514,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -3504,7 +3576,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -3555,7 +3627,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -3622,7 +3694,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -3673,7 +3745,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -3708,7 +3780,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -3782,7 +3854,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -3862,7 +3934,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -3919,7 +3991,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -3975,7 +4047,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -4007,7 +4079,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -4074,7 +4146,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -4143,7 +4215,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -4187,7 +4259,7 @@ declare namespace relationalStore { *
2. Incorrect parameter types. * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core * @crossplatform * @since 12 @@ -4229,7 +4301,7 @@ declare namespace relationalStore { *
2. Incorrect parameter types. * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core * @crossplatform * @since 12 @@ -4271,7 +4343,7 @@ declare namespace relationalStore { *
2. Incorrect parameter types. * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core * @crossplatform * @since 12 @@ -4306,7 +4378,7 @@ declare namespace relationalStore { *
2. Incorrect parameter types. * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core * @systemapi * @StageModelOnly @@ -4344,7 +4416,7 @@ declare namespace relationalStore { *
2. Incorrect parameter types. * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core * @systemapi * @StageModelOnly @@ -4387,7 +4459,7 @@ declare namespace relationalStore { *
2. Incorrect parameter types. * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core * @systemapi * @StageModelOnly @@ -4422,7 +4494,7 @@ declare namespace relationalStore { *
2. Incorrect parameter types. * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core * @crossplatform * @since 12 @@ -4450,7 +4522,7 @@ declare namespace relationalStore { *
2. Incorrect parameter types. * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core * @crossplatform * @since 12 @@ -4492,7 +4564,7 @@ declare namespace relationalStore { *
2. Incorrect parameter types. * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core * @crossplatform * @since 12 @@ -4534,7 +4606,7 @@ declare namespace relationalStore { *
2. Incorrect parameter types. * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core * @crossplatform * @since 12 @@ -4551,7 +4623,7 @@ declare namespace relationalStore { *
2. Incorrect parameter types. * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core * @crossplatform * @since 12 @@ -4587,7 +4659,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -4636,7 +4708,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -4690,7 +4762,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -4733,7 +4805,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -4784,7 +4856,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -4832,7 +4904,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -4879,7 +4951,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -4928,7 +5000,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -4973,7 +5045,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -5033,7 +5105,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -5076,7 +5148,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800047 - The WAL file size exceeds the default limit. * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; *
2. Incorrect parameter types. - * @throws { BusinessError } 14800000 - Inner error.+ + * @throws { BusinessError } 14800000 - Inner error. * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core * @crossplatform * @since 10 @@ -5093,7 +5165,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -5127,7 +5199,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -5161,7 +5233,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -5193,7 +5265,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -5240,7 +5312,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -5271,7 +5343,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -5314,7 +5386,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -5345,7 +5417,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -5387,7 +5459,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -5417,7 +5489,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -5470,7 +5542,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800010 - Invalid database path. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -5524,7 +5596,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -5578,7 +5650,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -5632,7 +5704,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. @@ -6364,6 +6436,19 @@ declare namespace relationalStore { */ on(event: 'autoSyncProgress', progress: Callback): void; + /** + * Subscribes to the SQL statistics. + * @param { 'statistics' } event - Indicates the event type, which must be 'statistics'. + * @param { Callback } observer - Indicates the callback used to return the SQL execution statistics {@link SqlExeInfo} in the database. + * @throws { BusinessError } 401 - Parameter error. Possible causes: 1.Mandatory parameters are left unspecified; 2.Incorrect parameter types. + * @throws { BusinessError } 801 - Capability not supported. + * @throws { BusinessError } 14800000 - Inner error. + * @throws { BusinessError } 14800014 - Already closed. + * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core + * @since 12 + */ + on(event: 'statistics', observer: Callback ): void; + /** * Remove specified observer of specified type from the database. * @@ -6486,6 +6571,19 @@ declare namespace relationalStore { */ off(event: 'autoSyncProgress', progress?: Callback): void; + /** + * Unsubscribes from the SQL statistics. + * @param { 'statistics' } event - Indicates the event type, which must be 'statistics'. + * @param { Callback } observer - Indicates the callback to unregister. + * @throws { BusinessError } 401 - Parameter error. + * @throws { BusinessError } 801 - Capability not supported. + * @throws { BusinessError } 14800000 - Inner error. + * @throws { BusinessError } 14800014 - Already closed. + * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core + * @since 12 + */ + off(event: 'statistics', observer?: Callback ): void; + /** * Notifies the registered observers of a change to the data resource specified by Uri. * @@ -6638,7 +6736,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800018 - No data meets the condition. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. @@ -6670,7 +6768,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800018 - No data meets the condition. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. @@ -6703,7 +6801,7 @@ declare namespace relationalStore { * @throws { BusinessError } 14800000 - Inner error. * @throws { BusinessError } 14800011 - Database corrupted. * @throws { BusinessError } 14800014 - Already closed. - * @throws { BusinessError } 14800015 - The database is busy. + * @throws { BusinessError } 14800015 - The database does not respond. * @throws { BusinessError } 14800021 - SQLite: Generic error. * @throws { BusinessError } 14800022 - SQLite: Callback routine requested an abort. * @throws { BusinessError } 14800023 - SQLite: Access permission denied. diff --git a/interface_sdk/api/@ohos.data.sendablePreferences.d.ets b/interface_sdk/api/@ohos.data.sendablePreferences.d.ets new file mode 100644 index 00000000..b0fa633f --- /dev/null +++ b/interface_sdk/api/@ohos.data.sendablePreferences.d.ets @@ -0,0 +1,508 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * @kit ArkData + */ + +import { Callback } from './@ohos.base'; +import Context from './application/BaseContext'; +import collections from '../arkts/@arkts.collections'; +import lang from '../arkts/@arkts.lang'; + +/** + * Provides interfaces to obtain and modify preferences data. + * + * @namespace sendablePreferences + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @atomicservice + * @since 12 + * @name sendablePreferences + */ +declare namespace sendablePreferences { + /** + * Maximum length of a key. + * + * @constant + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @atomicservice + * @since 12 + */ + const MAX_KEY_LENGTH: number; + + /** + * Maximum length of a value. + * + * @constant + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @atomicservice + * @since 12 + */ + const MAX_VALUE_LENGTH: number; + + /** + * Defines the configuration of a preferences file. + * + * @interface Options + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @atomicservice + * @since 12 + */ + interface Options { + /** + * Name of the preferences file. + * + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @atomicservice + * @since 12 + */ + name: string; + + /** + * Application group ID. + * + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @StageModelOnly + * @atomicservice + * @since 12 + */ + dataGroupId?: string | null; + } + + /** + * Obtains a {@link Preferences} instance matching the specified preferences file name. + *

The {@link references} instance loads all data of the preferences file and + * resides in the cache. You can use removePreferencesFromCache to remove the instance from the cache. + * + * @param { Context } context - Indicates the context of application or capability. + * @param { Options } options - Indicates information about the preferences file. For details, see {@link Options}. + * @returns { Promise } Promise used to return the {@link Preferences}. + * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; + * 2. Incorrect parameter types; + * 3. Parameter verification failed. + * @throws { BusinessError } 801 - Capability not supported. + * @throws { BusinessError } 15500000 - Inner error. + * @throws { BusinessError } 15501001 - Only supported in stage mode. + * @throws { BusinessError } 15501002 - The data group id is not valid. + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @atomicservice + * @since 12 + */ + function getPreferences(context: Context, options: Options): Promise; + + /** + * Obtains a {@link Preferences} instance matching a specified preferences file name. + * This API returns the result synchronously. + *

The {@link references} instance loads all data of the preferences file and + * resides in the cache. You can use removePreferencesFromCache to remove the instance from the cache. + * + * @param { Context } context - Indicates the context of application or capability. + * @param { Options } options - Indicates information about the preferences file. For details, see {@link Options}. + * @returns { Preferences } return the {@link Preferences}. + * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; + * 2. Incorrect parameter types; + * 3. Parameter verification failed. + * @throws { BusinessError } 801 - Capability not supported. + * @throws { BusinessError } 15500000 - Inner error. + * @throws { BusinessError } 15501001 - Only supported in stage mode. + * @throws { BusinessError } 15501002 - The data group id is not valid. + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @atomicservice + * @since 12 + */ + function getPreferencesSync(context: Context, options: Options): Preferences; + + /** + * Deletes a {@link Preferences} instance matching the specified preferences file name + * from the cache (which is equivalent to calling removePreferencesFromCache) and deletes + * the preferences file. + *

When deleting a {@link Preferences} instance, you must release all references + * of the instance. In addition, do not use the instance to perform data operations. Otherwise, data inconsistency + * will occur. + * + * @param { Context } context - Indicates the context of application or capability. + * @param { Options } options - Indicates information about the preferences file. For details, see {@link Options}. + * @returns { Promise } Promise that returns no value. + * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; + * 2. Incorrect parameter types; + * 3. Parameter verification failed. + * @throws { BusinessError } 801 - Capability not supported. + * @throws { BusinessError } 15500000 - Inner error. + * @throws { BusinessError } 15500010 - Failed to delete preferences file. + * @throws { BusinessError } 15501001 - Only supported in stage mode. + * @throws { BusinessError } 15501002 - The data group id is not valid. + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @atomicservice + * @since 12 + */ + function deletePreferences(context: Context, options: Options): Promise; + + /** + * Removes a {@link Preferences} instance matching the specified preferences file name + * from the cache. + *

When removing a {@link Preferences} instance, you must release all references + * of the instance. In addition, do not use the instance to perform data operations. Otherwise, data inconsistency + * will occur. + * + * @param { Context } context - Indicates the context of application or capability. + * @param { Options } options - Indicates information about the preferences file. For details, see {@link Options}. + * @returns { Promise } Promise that returns no value. + * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; + * 2. Incorrect parameter types; + * 3. Parameter verification failed. + * @throws { BusinessError } 801 - Capability not supported. + * @throws { BusinessError } 15500000 - Inner error. + * @throws { BusinessError } 15501001 - Only supported in stage mode. + * @throws { BusinessError } 15501002 - The data group id is not valid. + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @atomicservice + * @since 12 + */ + function removePreferencesFromCache(context: Context, options: Options): Promise; + + /** + * Removes a {@link Preferences} instance matching the specified preferences file name + * from the cache. This API returns the result synchronously. + *

When removing a {@link Preferences} instance, you must release all references + * of the instance. In addition, do not use the instance to perform data operations. Otherwise, data inconsistency + * will occur. + * + * @param { Context } context - Indicates the context of application or capability. + * @param { Options } options - Indicates information about the preferences file. For details, see {@link Options}. + * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; + * 2. Incorrect parameter types; + * 3. Parameter verification failed. + * @throws { BusinessError } 801 - Capability not supported. + * @throws { BusinessError } 15500000 - Inner error. + * @throws { BusinessError } 15501001 - Only supported in stage mode. + * @throws { BusinessError } 15501002 - The data group id is not valid. + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @atomicservice + * @since 12 + */ + function removePreferencesFromCacheSync(context: Context, options: Options): void; + + /** + * Provides interfaces to obtain and modify preferences data. + *

The preferences data is stored in a file, which matches only one {@link Preferences} instance in the cache. + * You can use getPreferences to obtain the {@link Preferences} instance matching + * the file that stores preferences data, and use removePreferencesFromCache + * to remove the {@link Preferences} instance from the cache. + * + * @interface Preferences + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @atomicservice + * @since 12 + */ + interface Preferences extends lang.ISendable { + /** + * Obtains the value of a preferences instance. + *

If the value is {@code null} or not in the lang.ISendable 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 { lang.ISendable } defValue - Indicates the default value to return. + * @returns { Promise } Promise used to return the result. If a value matching the specified key + * is found, the value is returned. Otherwise, the default value is returned. + * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; + * 2. Incorrect parameter types; + * 3. Parameter verification failed. + * @throws { BusinessError } 15500000 - Inner error. + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @atomicservice + * @since 12 + */ + get(key: string, defValue: lang.ISendable): Promise; + + /** + * Obtains the value of a preferences instance. This API returns the result synchronously. + *

If the value is {@code null} or not in the lang.ISendable 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 { lang.ISendable } defValue - Indicates the default value to return. + * @returns { lang.ISendable } If a value matching the specified key is found, the value is returned. Otherwise, + * the default value is returned. + * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; + * 2. Incorrect parameter types; + * 3. Parameter verification failed. + * @throws { BusinessError } 15500000 - Inner error. + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @atomicservice + * @since 12 + */ + getSync(key: string, defValue: lang.ISendable): lang.ISendable; + + /** + * Obtains all the keys and values of a preferences instance in an object. + * + * @returns { Promise } Promise used to return the values and keys obtained in an object. + * @throws { BusinessError } 15500000 - Inner error. + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @atomicservice + * @since 12 + */ + getAll(): Promise; + + /** + * Obtains all the keys and values of a preferences instance. This API returns the result synchronously. + * + * @returns { lang.ISendable } Returns the values and keys obtained in an object. + * @throws { BusinessError } 15500000 - Inner error. + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @atomicservice + * @since 12 + */ + getAllSync(): lang.ISendable; + + /** + * Checks whether the {@link Preferences} instance contains a value matching the specified key. + * + * @param { string } key - Indicates the key of the value to check. It cannot be {@code null} or empty. + * MAX_KEY_LENGTH. + * @returns { Promise } Promise used to return the result. {@code true} is returned if the + * {@link Preferences} object contains a value matching the specified key; {@code false} is returned otherwise. + * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; + * 2. Incorrect parameter types; + * 3. Parameter verification failed. + * @throws { BusinessError } 15500000 - Inner error. + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @atomicservice + * @since 12 + */ + has(key: string): Promise; + + /** + * Checks whether the {@link Preferences} instance contains a value matching the specified key. + * This API returns the result synchronously. + * + * @param { string } key - Indicates the key of the value to check. It cannot be {@code null} or empty. + * MAX_KEY_LENGTH. + * @returns { boolean } {@code true} is returned if the {@link Preferences} object contains a value matching + * the specified key; {@code false} is returned otherwise. + * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; + * 2. Incorrect parameter types; + * 3. Parameter verification failed. + * @throws { BusinessError } 15500000 - Inner error. + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @atomicservice + * @since 12 + */ + hasSync(key: string): boolean; + + /** + * Sets an lang.ISendable value for the key in the {@link Preferences} object. + *

You can call the {@link #flush} method to save the {@link Preferences} object to the file. + * + * @param { string } key - Indicates the key of the preferences to set. It cannot be {@code null} or empty. + * MAX_KEY_LENGTH. + * @param { lang.ISendable } value - Indicates the value of the preferences. + * MAX_VALUE_LENGTH. + * @returns { Promise } Promise that returns no value. + * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; + * 2. Incorrect parameter types; + * 3. Parameter verification failed. + * @throws { BusinessError } 15500000 - Inner error. + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @atomicservice + * @since 12 + */ + put(key: string, value: lang.ISendable): Promise; + + /** + * Sets an lang.ISendable value for the key in the {@link Preferences} object. + * This API returns the result synchronously. + *

You can call the {@link #flush} method to save the {@link Preferences} object to the file. + * + * @param { string } key - Indicates the key of the preferences to set. It cannot be {@code null} or empty. + * MAX_KEY_LENGTH. + * @param { lang.ISendable } value - Indicates the value of the preferences. + * MAX_VALUE_LENGTH. + * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; + * 2. Incorrect parameter types; + * 3. Parameter verification failed. + * @throws { BusinessError } 15500000 - Inner error. + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @atomicservice + * @since 12 + */ + putSync(key: string, value: lang.ISendable): void; + + /** + * Deletes the preferences with a specified key from the {@link Preferences} object. + *

You can call the {@link #flush} method to save the {@link Preferences} object to the file. + * + * @param { string } key - Indicates the key of the preferences to delete. It cannot be {@code null} or empty. + * MAX_KEY_LENGTH. + * @returns { Promise } Promise that returns no value. + * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; + * 2. Incorrect parameter types; + * 3. Parameter verification failed. + * @throws { BusinessError } 15500000 - Inner error. + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @atomicservice + * @since 12 + */ + delete(key: string): Promise; + + /** + * Deletes the preferences with a specified key from the {@link Preferences} object. This API returns the result + * synchronously. + *

You can call the {@link #flush} method to save the {@link Preferences} object to the file. + * + * @param { string } key - Indicates the key of the preferences to delete. It cannot be {@code null} or empty. + * MAX_KEY_LENGTH. + * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; + * 2. Incorrect parameter types; + * 3. Parameter verification failed. + * @throws { BusinessError } 15500000 - Inner error. + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @atomicservice + * @since 12 + */ + deleteSync(key: string): void; + + /** + * Clears all preferences from the {@link Preferences} object. + *

You can call the {@link #flush} method to save the {@link Preferences} object to the file. + * + * @returns { Promise } Promise that returns no value. + * @throws { BusinessError } 15500000 - Inner error. + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @atomicservice + * @since 12 + */ + clear(): Promise; + + /** + * Clears all preferences from the {@link Preferences} object. This API returns the result synchronously. + *

You can call the {@link #flush} method to save the {@link Preferences} object to the file. + * + * @throws { BusinessError } 15500000 - Inner error. + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @atomicservice + * @since 12 + */ + clearSync(): void; + + /** + * Flushes the {@link Preferences} object to the file. + * + * @returns { Promise } Promise that returns no value. + * @throws { BusinessError } 15500000 - Inner error. + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @atomicservice + * @since 12 + */ + flush(): Promise; + + /** + * Registers an observer to listen for the change of a {@link Preferences} object. + * + * @param { 'change' } type - Indicates the type of the event to observe. + * @param { Callback } callback - Indicates the callback used to return the preferences changes. + * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; + * 2. Incorrect parameter types; + * 3. Parameter verification failed. + * @throws { BusinessError } 15500000 - Inner error. + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @atomicservice + * @since 12 + */ + on(type: 'change', callback: Callback): void; + + /** + * Registers an observer to listen for the change of a {@link Preferences} object in multiple processes. + * + * @param { 'multiProcessChange' } type - Indicates the type of the event to observe. + * @param { Callback } callback - Indicates the callback used to return the preferences changed + * in multiple processes. + * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; + * 2. Incorrect parameter types; + * 3. Parameter verification failed. + * @throws { BusinessError } 15500000 - Inner error. + * @throws { BusinessError } 15500019 - Failed to obtain subscription service. + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @atomicservice + * @since 12 + */ + on(type: 'multiProcessChange', callback: Callback): void; + + /** + * Registers an observer to listen for changes to the {@link Preferences} object. + * + * @param { 'dataChange' } type - Indicates the type of the event to observe. + * @param { Array } keys - Indicates one or more keys to listen for. + * @param { Callback } callback - Indicates the callback used to return the data change. + * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; + * 2. Incorrect parameter types; + * 3. Parameter verification failed. + * @throws { BusinessError } 15500000 - Inner error. + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @atomicservice + * @since 12 + */ + on(type: 'dataChange', keys: Array, callback: Callback): void; + + /** + * Unregisters an observer used to listen for changes to the {@link Preferences} object. + * + * @param { 'change' } type - Indicates the event type. + * @param { Callback } callback - Indicates the callback to unregister. + * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; + * 2. Incorrect parameter types; + * 3. Parameter verification failed. + * @throws { BusinessError } 15500000 - Inner error. + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @atomicservice + * @since 12 + */ + off(type: 'change', callback?: Callback): void; + + /** + * Unregisters an observer used to listen for the preferences changed in multiple processes. + * + * @param { 'multiProcessChange' } type - Indicates the event type. + * @param { Callback } callback - Indicates the callback to unregister. + * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; + * 2. Incorrect parameter types; + * 3. Parameter verification failed. + * @throws { BusinessError } 15500000 - Inner error. + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @atomicservice + * @since 12 + */ + off(type: 'multiProcessChange', callback?: Callback): void; + + /** + * Unregisters an observer for changes to the {@ link Preferences} object. + * + * @param { 'dataChange' } type - Indicates the event type. + * @param { Array } keys - Indicates the data whose changes are not observed. + * @param { Callback } callback - Indicates the callback to unregister. + * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; + * 2. Incorrect parameter types; + * 3. Parameter verification failed. + * @throws { BusinessError } 15500000 - Inner error. + * @syscap SystemCapability.DistributedDataManager.Preferences.Core + * @atomicservice + * @since 12 + */ + off(type: 'dataChange', keys: Array, callback?: Callback): void; + } +} + +export default sendablePreferences; diff --git a/interface_sdk/api/@ohos.data.unifiedDataChannel.d.ts b/interface_sdk/api/@ohos.data.unifiedDataChannel.d.ts index 162cf9b9..4f5f87e0 100644 --- a/interface_sdk/api/@ohos.data.unifiedDataChannel.d.ts +++ b/interface_sdk/api/@ohos.data.unifiedDataChannel.d.ts @@ -64,6 +64,7 @@ declare namespace unifiedDataChannel { /** * Indicated delay get UnifiedData + * * @typedef {function} GetDelayData * @param { string } type - the type of UnifiedData required. * @returns { UnifiedData } Return the UnifiedData required. @@ -115,7 +116,7 @@ declare namespace unifiedDataChannel { * @atomicservice * @since 12 */ - timestamp?: Date; + readonly timestamp?: Date; /** * Indicates the scope of clipboard data which can be used. * If it is not set or is incorrectly set, The default value is CrossDevice. @@ -1040,7 +1041,17 @@ declare namespace unifiedDataChannel { * @atomicservice * @since 11 */ - DATA_HUB = 'DataHub' + DATA_HUB = 'DataHub', + + /** + * Indicates the intention of drag + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @systemapi + * @StageModelOnly + * @since 12 + */ + DRAG = 'Drag' } /** @@ -1295,6 +1306,36 @@ declare namespace unifiedDataChannel { * @since 11 */ function deleteData(options: Options): Promise>; + + /** + * Set app sharing options. + * + * @param { intention } Describe the sharing channel that UDMF support. + * @param { shareOptions } Types of scope that UnifiedData can be used. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. + * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; + * 2. Incorrect parameter types. + * @throws { BusinessError } 20400001 - Settings already exist. + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @systemapi + * @StageModelOnly + * @since 12 + */ + function setAppShareOptions(intention: Intention, shareOptions: ShareOptions): void; + + /** + * Remove app sharing options. + * + * @param { intention } Describe the sharing channel that UDMF support. + * @throws { BusinessError } 202 - Permission verification failed, application which is not a system application uses system API. + * @throws { BusinessError } 401 - Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; + * 2. Incorrect parameter types. + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @systemapi + * @StageModelOnly + * @since 12 + */ + function removeAppShareOptions(intention: Intention): void; } export default unifiedDataChannel; diff --git a/interface_sdk/api/@ohos.data.uniformTypeDescriptor.d.ts b/interface_sdk/api/@ohos.data.uniformTypeDescriptor.d.ts index 3849e6f5..64e93dac 100644 --- a/interface_sdk/api/@ohos.data.uniformTypeDescriptor.d.ts +++ b/interface_sdk/api/@ohos.data.uniformTypeDescriptor.d.ts @@ -142,6 +142,22 @@ declare namespace uniformTypeDescriptor { */ XML = 'general.xml', + /** + * Xhtml data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + XHTML = 'general.xhtml', + + /** + * Rss data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + RSS = 'general.rss', + /** * Real synchronized multimedia integration language. * @@ -230,6 +246,14 @@ declare namespace uniformTypeDescriptor { */ JAVA_SCRIPT = 'general.java-script', + /** + * Css data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + CSS = 'general.css', + /** * C header data type. * @@ -270,6 +294,14 @@ declare namespace uniformTypeDescriptor { */ JAVA_SOURCE = 'general.java-source', + /** + * Tex source code data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + TEX = 'general.tex', + /** * Markdown format. * @@ -278,6 +310,46 @@ declare namespace uniformTypeDescriptor { */ MARKDOWN = 'general.markdown', + /** + * Asc text data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + ASC_TEXT = 'general.asc-text', + + /** + * Rich text data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + RICH_TEXT = 'general.rich-text', + + /** + * Delimited values text data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + DELIMITED_VALUES_TEXT = 'general.delimited-values-text', + + /** + * Comma separated values text data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + COMMA_SEPARATED_VALUES_TEXT = 'general.comma-separated-values-text', + + /** + * Tab separated values text data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + TAB_SEPARATED_VALUES_TEXT = 'general.tab-separated-values-text', + /** * Ebook data type. * @@ -445,6 +517,14 @@ declare namespace uniformTypeDescriptor { */ XBITMAP_IMAGE = 'general.xbitmap-image', + /** + * Gif image format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + GIF = 'general.gif', + /** * Tagged Graphics (TGA), a type of image format. * @@ -501,6 +581,46 @@ declare namespace uniformTypeDescriptor { */ PPT = 'com.microsoft.powerpoint.ppt', + /** + * Microsoft Word dot data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + WORD_DOT = 'com.microsoft.word.dot', + + /** + * Microsoft Powerpoint pps data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + POWERPOINT_PPS = 'com.microsoft.powerpoint.pps', + + /** + * Microsoft Powerpoint pot data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + POWERPOINT_POT = 'com.microsoft.powerpoint.pot', + + /** + * Microsoft Excel xlt data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + EXCEL_XLT = 'com.microsoft.excel.xlt', + + /** + * Microsoft Visio vsd data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + VISIO_VSD = 'com.microsoft.visio.vsd', + /** * PDF data type. * @@ -580,6 +700,22 @@ declare namespace uniformTypeDescriptor { */ VIDEO_3GPP2 = 'general.3gpp2', + /** + * Ts video format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + TS = 'general.ts', + + /** + * Mpegurl video format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + MPEGURL_VIDEO = 'general.mpegurl-video', + /** * Windows WM video format data type. * @@ -628,6 +764,22 @@ declare namespace uniformTypeDescriptor { */ REALMEDIA = 'com.real.realmedia', + /** + * Matroska video format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + MATROSKA_VIDEO = 'org.matroska.mkv', + + /** + * Flash data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + FLASH = 'com.adobe.flash', + /** * Audio data type. * @@ -739,6 +891,46 @@ declare namespace uniformTypeDescriptor { */ AIFC_AUDIO = 'general.aifc-audio', + /** + * Mpegurl audio format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + MPEGURL_AUDIO = 'general.mpegurl-audio', + + /** + * Mpeg-4 audio format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + MPEG_4_AUDIO = 'general.mpeg-4-audio', + + /** + * Mp2 audio format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + MP2 = 'general.mp2', + + /** + * Mpeg audio format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + MPEG_AUDIO = 'general.mpeg-audio', + + /** + * Ulaw audio format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + ULAW_AUDIO = 'general.ulaw-audio', + /** * Digidesign Sound Designer II audio. * @@ -755,6 +947,14 @@ declare namespace uniformTypeDescriptor { */ REALAUDIO = 'com.real.realaudio', + /** + * Matroska audio format data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + MATROSKA_AUDIO = 'org.matroska.mka', + /** * File data type. * @@ -817,6 +1017,30 @@ declare namespace uniformTypeDescriptor { */ BZ2_ARCHIVE = 'general.bz2-archive', + /** + * Opg archive data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + OPG = 'general.opg', + + /** + * Taz archive data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + TAZ_ARCHIVE = 'general.taz-archive', + + /** + * Web archive data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + WEB_ARCHIVE = 'general.web-archive', + /** * Disk image archive file data type. * @@ -825,6 +1049,14 @@ declare namespace uniformTypeDescriptor { */ DISK_IMAGE = 'general.disk-image', + /** + * Iso data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + ISO = 'general.iso', + /** * Tar archive data type. * @@ -905,6 +1137,54 @@ declare namespace uniformTypeDescriptor { */ PRESENTATIONML_PRESENTATION = 'org.openxmlformats.presentationml.presentation', + /** + * Office Open XML Drawingml visio. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + DRAWINGML_VISIO = 'org.openxmlformats.drawingml.visio', + + /** + * Office Open XML Drawingml template. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + DRAWINGML_TEMPLATE = 'org.openxmlformats.drawingml.template', + + /** + * Office Open XML Wordprocessingml template. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + WORDPROCESSINGML_TEMPLATE = 'org.openxmlformats.wordprocessingml.template', + + /** + * Office Open XML Presentationml template. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + PRESENTATIONML_TEMPLATE = 'org.openxmlformats.presentationml.template', + + /** + * Office Open XML Presentationml slideshow. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + PRESENTATIONML_SLIDESHOW = 'org.openxmlformats.presentationml.slideshow', + + /** + * Office Open XML Spreadsheetml template. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + SPREADSHEETML_TEMPLATE = 'org.openxmlformats.spreadsheetml.template', + /** * Open Document Format for Office Applications. * @@ -961,6 +1241,22 @@ declare namespace uniformTypeDescriptor { */ STUFFIT_ARCHIVE = 'com.allume.stuffit-archive', + /** + * Rar archive. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + RAR_ARCHIVE = 'com.rarlab.rar-archive', + + /** + * 7-zip archive. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + SEVEN_ZIP_ARCHIVE = 'org.7-zip.7-zip-archive', + /** * Calendar data type. * @@ -1213,7 +1509,31 @@ declare namespace uniformTypeDescriptor { * @syscap SystemCapability.DistributedDataManager.UDMF.Core * @since 12 */ - OPENHARMONY_WANT = 'openharmony.want' + OPENHARMONY_WANT = 'openharmony.want', + + /** + * Ofd data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + OFD = 'general.ofd', + + /** + * Cad data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + CAD = 'general.cad', + + /** + * Octet stream data type. + * + * @syscap SystemCapability.DistributedDataManager.UDMF.Core + * @since 12 + */ + OCTET_STREAM = 'general.octet-stream' } /** diff --git a/kv_store/bundle.json b/kv_store/bundle.json index 24e256fc..81de0310 100644 --- a/kv_store/bundle.json +++ b/kv_store/bundle.json @@ -74,7 +74,8 @@ "ipc", "napi", "safwk", - "samgr" + "samgr", + "file_api" ] }, "build": { @@ -87,6 +88,7 @@ "//foundation/distributeddatamgr/kv_store/interfaces/jskits/distributedkvstore:build_module", "//foundation/distributeddatamgr/kv_store/kvstoremock/interfaces/jskits/distributedkvstore:build_module", "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata:distributeddata_client_sync", + "//foundation/distributeddatamgr/kv_store/interfaces/cj:cj_distributed_kv_store_ffi", "//foundation/distributeddatamgr/kv_store/databaseutils:database_utils" ], "inner_kits": [ diff --git a/kv_store/databaseutils/BUILD.gn b/kv_store/databaseutils/BUILD.gn index a5842847..f89fe877 100644 --- a/kv_store/databaseutils/BUILD.gn +++ b/kv_store/databaseutils/BUILD.gn @@ -31,6 +31,8 @@ base_sources = [ "src/acl.cpp" ] ohos_shared_library("database_utils") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false diff --git a/kv_store/databaseutils/src/acl.cpp b/kv_store/databaseutils/src/acl.cpp index b2a95bfc..456ceda9 100644 --- a/kv_store/databaseutils/src/acl.cpp +++ b/kv_store/databaseutils/src/acl.cpp @@ -65,8 +65,10 @@ void Acl::CompareInsertEntry(const AclXattrEntry &entry) auto it = entries_.find(entry); entries_.erase(it); } - if (entry.perm_.IsReadable() || entry.perm_.IsWritable() || - entry.perm_.IsExecutable()) { + bool isNecessary = (entry.tag_ == ACL_TAG::USER_OBJ || + entry.tag_ == ACL_TAG::GROUP_OBJ || + entry.tag_ == ACL_TAG::OTHER); + if (isNecessary || entry.perm_.IsReadable() || entry.perm_.IsWritable() || entry.perm_.IsExecutable()) { entries_.insert(entry); } } diff --git a/kv_store/frameworks/cj/include/distributed_kv_store_ffi.h b/kv_store/frameworks/cj/include/distributed_kv_store_ffi.h new file mode 100644 index 00000000..69168862 --- /dev/null +++ b/kv_store/frameworks/cj/include/distributed_kv_store_ffi.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DISTRIBUTED_KV_STORE_FFI_H +#define DISTRIBUTED_KV_STORE_FFI_H + +#include +#include "napi_base_context.h" +#include "ffi_remote_data.h" +#include "cj_common_ffi.h" +#include "data_query.h" + +#include "distributed_kv_store_log.h" +#include "distributed_kv_store_impl.h" + +namespace OHOS { +namespace DistributedKVStore { + +extern "C" { + FFI_EXPORT int64_t FfiOHOSDistributedKVStoreCreateKVManager(const char* boudleName, + OHOS::AbilityRuntime::Context* context); + + FFI_EXPORT int64_t FfiOHOSDistributedKVStoreGetKVStore(int64_t id, const char* storeId, + CJOptions options, int32_t* errCode); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreCloseKVStore(int64_t id, const char* appId, const char* storeId); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreDeleteKVStore(int64_t id, const char* appId, const char* storeId); + + FFI_EXPORT CArrStr FfiOHOSDistributedKVStoreGetAllKVStoreId(int64_t id, const char* appId, int32_t* errCode); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStorePut(int64_t id, const char* key, ValueType value); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStorePutBatch(int64_t id, const CArrEntry cArrEntry); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStoreDelete(int64_t id, const char* key); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStoreDeleteBatch(int64_t id, const CArrStr cArrStr); + + FFI_EXPORT ValueType FfiOHOSDistributedKVStoreSingleKVStoreGet(int64_t id, const char* key, int32_t* errCode); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStoreBackup(int64_t id, const char* file); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStoreRestore(int64_t id, const char* file); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStoreStartTransaction(int64_t id); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStoreCommit(int64_t id); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStoreRollback(int64_t id); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStoreEnableSync(int64_t id, bool enabled); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStoreSetSyncParam(int64_t id, uint32_t defaultAllowedDelayMs); + + FFI_EXPORT int64_t FfiOHOSDistributedKVStoreQueryConstructor(); + + FFI_EXPORT void FfiOHOSDistributedKVStoreQueryReset(int64_t id); + + FFI_EXPORT void FfiOHOSDistributedKVStoreQueryEqualTo(int64_t id, const char* field, ValueType value); + + FFI_EXPORT ValueType FfiOHOSDistributedKVStoreDeviceKVStoreGet(int64_t id, const char* deviceId, const char* key, + int32_t* errCode); + + FFI_EXPORT CArrEntry FfiOHOSDistributedKVStoreDeviceKVStoreGetEntries(int64_t id, const char* deviceId, + const char* keyPrefix, int32_t* errCode); + + FFI_EXPORT CArrEntry FfiOHOSDistributedKVStoreDeviceKVStoreGetEntriesQuery(int64_t id, const char* deviceId, + int64_t queryId, int32_t* errCode); + + FFI_EXPORT int64_t FfiOHOSDistributedKVStoreDeviceKVStoreGetResultSet(int64_t id, const char* deviceId, + const char* keyPrefix, int32_t* errCode); + + FFI_EXPORT int64_t FfiOHOSDistributedKVStoreDeviceKVStoreGetResultSetQuery(int64_t id, const char* deviceId, + int64_t queryId, int32_t* errCode); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreDeviceKVStoreGetResultSize(int64_t id, const char* deviceId, + int64_t queryId, int32_t* errCode); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreKVStoreResultSetGetCount(int64_t id); +} + +} +} + +#endif \ No newline at end of file diff --git a/kv_store/frameworks/cj/include/distributed_kv_store_impl.h b/kv_store/frameworks/cj/include/distributed_kv_store_impl.h new file mode 100644 index 00000000..a09ba1e9 --- /dev/null +++ b/kv_store/frameworks/cj/include/distributed_kv_store_impl.h @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DISTRIBUTED_KV_STORE_IMPL_H +#define DISTRIBUTED_KV_STORE_IMPL_H + +#include +#include +#include "distributed_kv_data_manager.h" +#include "kvstore_death_recipient.h" +#include "distributed_kv_store_log.h" +#include "ability_context_impl.h" +#include "kvstore_result_set.h" + +namespace OHOS { +namespace DistributedKVStore { +using namespace OHOS::DistributedKv; + +struct ContextParam { + std::string baseDir = ""; + std::string hapName = ""; + int32_t area = DistributedKv::Area::EL1; +}; + +struct CJFieldNode { + bool nullable; + char* defaultString; + int32_t type; +}; + +struct CJSchema { + CJFieldNode root; + char** indexes; + int32_t indexesSize; + int32_t mode; + int32_t skip; +}; + +struct CJOptions { + bool createIfMissing; + bool encrypt; + bool backup; + bool autoSync; + int32_t kvStoreType; + int32_t securityLevel; + CJSchema schema; +}; + +struct CArrByte { + u_int8_t* head; + int64_t size; +}; + +struct CArrStr { + char** head; + int64_t size; +}; + +struct ValueType { + char* string; + int32_t integer; + float flo; + CArrByte byteArray; + bool boolean; + double dou; + uint8_t tag; +}; + +struct CEntry { + char *key; + ValueType value; +}; + +struct CArrEntry { + CEntry* head; + int64_t size; +}; + +class CJKVManager : public OHOS::FFI::FFIData { +public: + OHOS::FFI::RuntimeType* GetRuntimeType() override + { + return GetClassType(); + } + + CJKVManager(); + CJKVManager(const char* boudleName, OHOS::AbilityRuntime::Context* context); + + uint64_t GetKVStore(const char* cStoreId, const CJOptions cjOptions, int32_t& errCode); + int32_t CloseKVStore(const char* appId, const char* storeId); + int32_t DeleteKVStore(const char* appId, const char* storeId); + CArrStr GetAllKVStoreId(const char* appId, int32_t& errCode); +private: + DistributedKv::DistributedKvDataManager kvDataManager_ {}; + std::string bundleName_ {}; + std::shared_ptr param_; + friend class OHOS::FFI::RuntimeType; + friend class OHOS::FFI::TypeBase; + static OHOS::FFI::RuntimeType* GetClassType() + { + static OHOS::FFI::RuntimeType runtimeType = OHOS::FFI::RuntimeType::Create("CJKVManager"); + return &runtimeType; + } +}; + +class CJSingleKVStore : public OHOS::FFI::FFIData { +public: + OHOS::FFI::RuntimeType* GetRuntimeType() override + { + return GetClassType(); + } + + explicit CJSingleKVStore(const std::string& storeId); + + std::shared_ptr GetKvStorePtr(); + void SetKvStorePtr(std::shared_ptr kvStore); + void SetContextParam(std::shared_ptr param); + int32_t Put(const std::string &key, const ValueType &value); + int32_t PutBatch(const CArrEntry &cArrEntry); + int32_t Delete(const std::string &key); + int32_t DeleteBatch(const CArrStr &cArrStr); + ValueType Get(const std::string &key, int32_t& errCode); + int32_t Backup(const std::string &file); + int32_t Restore(const std::string &file); + int32_t StartTransaction(); + int32_t Commit(); + int32_t Rollback(); + int32_t EnableSync(bool enabled); + int32_t SetSyncParam(uint32_t defaultAllowedDelayMs); + +private: + /* private non-static members */ + std::shared_ptr kvStore_ = nullptr; + std::string storeId_; + std::shared_ptr param_ = nullptr; + friend class OHOS::FFI::RuntimeType; + friend class OHOS::FFI::TypeBase; + static OHOS::FFI::RuntimeType* GetClassType() + { + static OHOS::FFI::RuntimeType runtimeType = + OHOS::FFI::RuntimeType::Create("CJSingleKVStore"); + return &runtimeType; + } +}; + +class CQuery : public OHOS::FFI::FFIData { +public: + OHOS::FFI::RuntimeType* GetRuntimeType() override + { + return GetClassType(); + } + + CQuery() {}; + + const DistributedKv::DataQuery& GetDataQuery() const; + + void Reset(); + + void EqualTo(const std::string &field, ValueType &value); + +private: + DistributedKv::DataQuery query_; + friend class OHOS::FFI::RuntimeType; + friend class OHOS::FFI::TypeBase; + static OHOS::FFI::RuntimeType* GetClassType() + { + static OHOS::FFI::RuntimeType runtimeType = OHOS::FFI::RuntimeType::Create("CQuery"); + return &runtimeType; + } +}; + +class CJDeviceKVStore : public CJSingleKVStore { +public: + OHOS::FFI::RuntimeType* GetRuntimeType() override + { + return GetClassType(); + } + + explicit CJDeviceKVStore(const std::string& storeId); + + ValueType Get(const std::string &deviceId, const std::string &key, int32_t& errCode); + + CArrEntry GetEntriesByDataQuery(DistributedKVStore::DataQuery dataQuery, int32_t& errCode); + + CArrEntry GetEntries(const std::string &deviceId, const std::string &keyPrefix, int32_t& errCode); + + CArrEntry GetEntries(const std::string &deviceId, OHOS::sptr query, int32_t& errCode); + + int64_t GetResultSet(const std::string &deviceId, const std::string &keyPrefix, int32_t& errCode); + + int64_t GetResultSetQuery(const std::string &deviceId, OHOS::sptr query, int32_t& errCode); + + int32_t GetResultSize(const std::string &deviceId, OHOS::sptr query, int32_t& errCode); + +private: + friend class OHOS::FFI::RuntimeType; + friend class OHOS::FFI::TypeBase; + static OHOS::FFI::RuntimeType* GetClassType() + { + static OHOS::FFI::RuntimeType runtimeType = + OHOS::FFI::RuntimeType::Create("CJDeviceKVStore"); + return &runtimeType; + } +}; + +class CKvStoreResultSet : public OHOS::FFI::FFIData { +public: + OHOS::FFI::RuntimeType* GetRuntimeType() override + { + return GetClassType(); + } + + explicit CKvStoreResultSet(std::shared_ptr kvResultSet); + + std::shared_ptr GetKvStoreResultSet(); + + int32_t GetCount(); + +private: + std::shared_ptr kvResultSet; + friend class OHOS::FFI::RuntimeType; + friend class OHOS::FFI::TypeBase; + static OHOS::FFI::RuntimeType* GetClassType() + { + static OHOS::FFI::RuntimeType runtimeType = + OHOS::FFI::RuntimeType::Create("CKvStoreResultSet"); + return &runtimeType; + } +}; +} +} // namespace OHOS::DistributedKVStore + +#endif \ No newline at end of file diff --git a/kv_store/frameworks/cj/include/distributed_kv_store_log.h b/kv_store/frameworks/cj/include/distributed_kv_store_log.h new file mode 100644 index 00000000..e7e96a41 --- /dev/null +++ b/kv_store/frameworks/cj/include/distributed_kv_store_log.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DISTRIBUTED_KV_STORE_LOG_H +#define DISTRIBUTED_KV_STORE_LOG_H + +#include "hilog/log.h" + +#undef LOG_DOMAIN +#undef LOG_TAG +#define LOG_DOMAIN 0xD002B25 +#define LOG_TAG "DistributedKVStoreCffi" + +#define LOGI(...) \ +if (HiLogIsLoggable(LOG_DOMAIN, LOG_TAG, LOG_INFO)) { \ + HILOG_INFO(LOG_CORE, ##__VA_ARGS__); \ +} + +#define LOGE(...) \ +if (HiLogIsLoggable(LOG_DOMAIN, LOG_TAG, LOG_ERROR)) { \ + HILOG_ERROR(LOG_CORE, __VA_ARGS__); \ +} + +#endif diff --git a/kv_store/frameworks/cj/include/distributed_kv_store_utils.h b/kv_store/frameworks/cj/include/distributed_kv_store_utils.h new file mode 100644 index 00000000..39113482 --- /dev/null +++ b/kv_store/frameworks/cj/include/distributed_kv_store_utils.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef DISTRIBUTED_KV_STORE_UTILS_H +#define DISTRIBUTED_KV_STORE_UTILS_H + +#include +#include +#include + +namespace OHOS { +namespace DistributedKVStore { + char* MallocCString(const std::string& origin); + enum CJErrorCode { + CJ_ERROR_PERMISSION_DENIED = 202, + + CJ_ERROR_INVALID_ARGUMENT = 401, + + CJ_ERROR_OVER_MAX_LIMITS = 15100001, + + CJ_ERROR_STORE_META_CHANGED = 15100002, + + CJ_ERROR_CRYPT_ERROR = 15100003, + + CJ_ERROR_NOT_FOUND = 15100004, + + CJ_ERROR_ALREADY_CLOSED = 15100005, + }; + + enum TypeSymbol { + /* Blob's first byte is the blob's data ValueType */ + STRING = 0, + INTEGER = 1, + FLOAT = 2, + BYTE_ARRAY = 3, + BOOLEAN = 4, + DOUBLE = 5, + INVALID = 255 + }; +} +} +#endif \ No newline at end of file diff --git a/kv_store/frameworks/cj/src/distributed_kv_store_ffi.cpp b/kv_store/frameworks/cj/src/distributed_kv_store_ffi.cpp new file mode 100644 index 00000000..d7b69c83 --- /dev/null +++ b/kv_store/frameworks/cj/src/distributed_kv_store_ffi.cpp @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "distributed_kv_store_ffi.h" +#include "distributed_kv_store_impl.h" +#include "distributed_kv_store_utils.h" + +using namespace OHOS::FFI; +using namespace OHOS::DistributedKVStore; + +namespace OHOS { +namespace DistributedKVStore { +extern "C" { +int64_t FfiOHOSDistributedKVStoreCreateKVManager(const char* boudleName, OHOS::AbilityRuntime::Context* context) +{ + if (context == nullptr) { + return -1; + } + auto nativeCJKVManager = FFIData::Create(boudleName, context); + if (nativeCJKVManager == nullptr) { + return -1; + } + return nativeCJKVManager->GetID(); +} + +int64_t FfiOHOSDistributedKVStoreGetKVStore(int64_t id, const char* storeId, CJOptions options, int32_t* errCode) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + *errCode = -1; + return -1; + } + return instance->GetKVStore(storeId, options, *errCode); +} + +int32_t FfiOHOSDistributedKVStoreCloseKVStore(int64_t id, const char* appId, const char* storeId) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->CloseKVStore(appId, storeId); +} + +int32_t FfiOHOSDistributedKVStoreDeleteKVStore(int64_t id, const char* appId, const char* storeId) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->DeleteKVStore(appId, storeId); +} + +CArrStr FfiOHOSDistributedKVStoreGetAllKVStoreId(int64_t id, const char* appId, int32_t* errCode) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + *errCode = -1; + return CArrStr{}; + } + return instance->GetAllKVStoreId(appId, *errCode); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStorePut(int64_t id, const char* key, ValueType value) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->Put(key, value); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStorePutBatch(int64_t id, const CArrEntry cArrEntry) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->PutBatch(cArrEntry); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStoreDelete(int64_t id, const char* key) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->Delete(key); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStoreDeleteBatch(int64_t id, const CArrStr cArrStr) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->DeleteBatch(cArrStr); +} + +ValueType FfiOHOSDistributedKVStoreSingleKVStoreGet(int64_t id, const char* key, int32_t* errCode) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + *errCode = -1; + return ValueType{}; + } + return instance->Get(key, *errCode); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStoreBackup(int64_t id, const char* file) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->Backup(file); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStoreRestore(int64_t id, const char* file) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->Restore(file); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStoreStartTransaction(int64_t id) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->StartTransaction(); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStoreCommit(int64_t id) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->Commit(); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStoreRollback(int64_t id) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->Rollback(); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStoreEnableSync(int64_t id, bool enabled) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->EnableSync(enabled); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStoreSetSyncParam(int64_t id, uint32_t defaultAllowedDelayMs) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->SetSyncParam(defaultAllowedDelayMs); +} + + +int64_t FfiOHOSDistributedKVStoreQueryConstructor() +{ + auto nativeCJQuery = FFIData::Create(); + if (nativeCJQuery == nullptr) { + return -1; + } + return nativeCJQuery->GetID(); +} + +void FfiOHOSDistributedKVStoreQueryReset(int64_t id) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return; + } + return instance->Reset(); +} + +void FfiOHOSDistributedKVStoreQueryEqualTo(int64_t id, const char* field, ValueType value) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return; + } + return instance->EqualTo(field, value); +} + +ValueType FfiOHOSDistributedKVStoreDeviceKVStoreGet(int64_t id, const char* deviceId, const char* key, int32_t* errCode) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + *errCode = -1; + return ValueType{}; + } + return instance->Get(deviceId, key, *errCode); +} + +CArrEntry FfiOHOSDistributedKVStoreDeviceKVStoreGetEntries(int64_t id, const char* deviceId, const char* keyPrefix, + int32_t* errCode) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + *errCode = -1; + return CArrEntry{}; + } + return instance->GetEntries(deviceId, keyPrefix, *errCode); +} + +CArrEntry FfiOHOSDistributedKVStoreDeviceKVStoreGetEntriesQuery(int64_t id, const char* deviceId, int64_t queryId, + int32_t* errCode) +{ + auto instance = FFIData::GetData(id); + auto query = FFIData::GetData(queryId); + if (instance == nullptr || query == nullptr) { + *errCode = -1; + return CArrEntry{}; + } + return instance->GetEntries(deviceId, query, *errCode); +} + +int64_t FfiOHOSDistributedKVStoreDeviceKVStoreGetResultSet(int64_t id, const char* deviceId, const char* keyPrefix, + int32_t* errCode) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + *errCode = -1; + return -1; + } + return instance->GetResultSet(deviceId, keyPrefix, *errCode); +} + +int64_t FfiOHOSDistributedKVStoreDeviceKVStoreGetResultSetQuery(int64_t id, const char* deviceId, int64_t queryId, + int32_t* errCode) +{ + auto instance = FFIData::GetData(id); + auto query = FFIData::GetData(queryId); + if (instance == nullptr || query == nullptr) { + *errCode = -1; + return -1; + } + return instance->GetResultSetQuery(deviceId, query, *errCode); +} + +int32_t FfiOHOSDistributedKVStoreDeviceKVStoreGetResultSize(int64_t id, const char* deviceId, int64_t queryId, + int32_t* errCode) +{ + auto instance = FFIData::GetData(id); + auto query = FFIData::GetData(queryId); + if (instance == nullptr || query == nullptr) { + *errCode = -1; + return -1; + } + return instance->GetResultSize(deviceId, query, *errCode); +} + +int32_t FfiOHOSDistributedKVStoreKVStoreResultSetGetCount(int64_t id) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->GetCount(); +} +} +} +} diff --git a/kv_store/frameworks/cj/src/distributed_kv_store_impl.cpp b/kv_store/frameworks/cj/src/distributed_kv_store_impl.cpp new file mode 100644 index 00000000..307a3b0f --- /dev/null +++ b/kv_store/frameworks/cj/src/distributed_kv_store_impl.cpp @@ -0,0 +1,568 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include "securec.h" +#include "ffi_remote_data.h" + +#include "distributed_kv_store_impl.h" +#include "distributed_kv_store_utils.h" + +using namespace OHOS::FFI; + +namespace OHOS::DistributedKVStore { + +static int32_t ConvertCJErrCode(Status status) +{ + switch (status) { + case PERMISSION_DENIED: + // 202 + return CJ_ERROR_PERMISSION_DENIED; + case INVALID_ARGUMENT: + // 401 + return CJ_ERROR_INVALID_ARGUMENT; + case OVER_MAX_LIMITS: + // 15100001 + return CJ_ERROR_OVER_MAX_LIMITS; + case STORE_META_CHANGED: + case SECURITY_LEVEL_ERROR: + // 15100002 + return CJ_ERROR_STORE_META_CHANGED; + case CRYPT_ERROR: + // 15100003 + return CJ_ERROR_CRYPT_ERROR; + case NOT_FOUND: + case DB_ERROR: + // 15100004 + return CJ_ERROR_NOT_FOUND; + case ALREADY_CLOSED: + // 15100005 + return CJ_ERROR_ALREADY_CLOSED; + default: + return static_cast(status); + } +} + +static CArrByte VectorToByteArray(std::vector bytes) +{ + uint8_t* head = static_cast(malloc(bytes.size() * sizeof(uint8_t))); + if (head == nullptr) { + return CArrByte{}; + } + for (unsigned long i = 0; i < bytes.size(); i++) { + head[i] = bytes[i]; + } + CArrByte byteArray = { head, bytes.size() }; + return byteArray; +} + +static ValueType KVValueToValueType(const DistributedKv::Blob& blob) +{ + auto& data = blob.Data(); + ValueType v = { 0 }; + // number 2 means: valid Blob must have more than 2 bytes. + if (data.size() < 1) { + LOGI("Blob have no data!"); + return {0}; + } + // number 1 means: skip the first byte, byte[0] is real data type. + std::vector real(data.begin() + 1, data.end()); + if (data[0] == STRING) { + v.string = MallocCString(std::string(real.begin(), real.end())); + v.tag = STRING; + } else if (data[0] == INTEGER) { + uint32_t tmp4int = be32toh(*reinterpret_cast(&(real[0]))); + v.integer = *reinterpret_cast(&tmp4int); + v.tag = INTEGER; + } else if (data[0] == FLOAT) { + uint32_t tmp4flt = be32toh(*reinterpret_cast(&(real[0]))); + v.flo = *reinterpret_cast((void*)(&tmp4flt)); + v.tag = FLOAT; + } else if (data[0] == BYTE_ARRAY) { + v.byteArray = VectorToByteArray(std::vector(real.begin(), real.end())); + v.tag = BYTE_ARRAY; + } else if (data[0] == BOOLEAN) { + v.boolean = static_cast(real[0]); + v.tag = BOOLEAN; + } else if (data[0] == DOUBLE) { + uint64_t tmp4dbl = be64toh(*reinterpret_cast(&(real[0]))); + v.dou = *reinterpret_cast((void*)(&tmp4dbl)); + v.tag = DOUBLE; + } else { + // for schema-db, if (data[0] == STRING), no beginning byte! + v.string = MallocCString(std::string(data.begin(), data.end())); + v.tag = STRING; + } + return v; +} + +static void PushData(const ValueType &value, std::vector &data, uint8_t tag) +{ + switch (tag) { + case INTEGER: { + int32_t tmp = value.integer; // copy value, and make it available in stack space. + uint32_t tmp32 = htobe32(*reinterpret_cast(&tmp)); + uint8_t *res = reinterpret_cast(&tmp32); + data.push_back(INTEGER); + data.insert(data.end(), res, res + sizeof(int32_t) / sizeof(uint8_t)); + break; + } + case FLOAT: { + float tmp = value.flo; // copy value, and make it available in stack space. + uint32_t tmp32 = htobe32(*reinterpret_cast(&tmp)); + uint8_t *res = reinterpret_cast(&tmp32); + data.push_back(FLOAT); + data.insert(data.end(), res, res + sizeof(float) / sizeof(uint8_t)); + break; + } + case DOUBLE: { + double tmp = value.dou; // copy value, and make it available in stack space. + uint64_t tmp64 = htobe64(*reinterpret_cast(&tmp)); + uint8_t *res = reinterpret_cast(&tmp64); + data.push_back(DOUBLE); + data.insert(data.end(), res, res + sizeof(double) / sizeof(uint8_t)); + break; + } + default: + break; + } +} + +static DistributedKv::Value ValueTypeToKVValue(const ValueType &value) +{ + std::vector data; + switch (value.tag) { + case STRING: { + std::string str = value.string; + data.push_back(STRING); + data.insert(data.end(), str.begin(), str.end()); + break; + } + case INTEGER: { + PushData(value, data, value.tag); + break; + } + case FLOAT: { + PushData(value, data, value.tag); + break; + } + case BYTE_ARRAY: { + std::vector bytes = std::vector(); + for (int64_t i = 0; i < value.byteArray.size; i++) { + bytes.push_back(value.byteArray.head[i]); + } + data.push_back(BYTE_ARRAY); + data.insert(data.end(), bytes.begin(), bytes.end()); + break; + } + case BOOLEAN: { + data.push_back(BOOLEAN); + data.push_back(static_cast(value.boolean)); + break; + } + case DOUBLE: { + PushData(value, data, value.tag); + break; + } + default: + break; + } + return DistributedKv::Blob(data); +} + +CJKVManager::CJKVManager() {}; +CJKVManager::CJKVManager(const char* boudleName, OHOS::AbilityRuntime::Context* context) +{ + ContextParam param; + param.area = context->GetArea(); + param.baseDir = context->GetDatabaseDir(); + auto hapInfo = context->GetHapModuleInfo(); + if (hapInfo != nullptr) { + param.hapName = hapInfo->moduleName; + } + param_ = std::make_shared(std::move(param)); + bundleName_ = boudleName; +} + +uint64_t CJKVManager::GetKVStore(const char* cStoreId, const CJOptions cjOptions, int32_t& errCode) +{ + Options options; + options.createIfMissing = cjOptions.createIfMissing; + options.encrypt = cjOptions.encrypt; + options.backup = cjOptions.backup; + options.autoSync = cjOptions.autoSync; + options.kvStoreType = static_cast(cjOptions.kvStoreType); + options.securityLevel = cjOptions.securityLevel; + AppId appId = { bundleName_ }; + std::string sStoreId = cStoreId; + StoreId storeId = { sStoreId }; + options.baseDir = param_->baseDir; + options.area = param_->area + 1; + options.hapName = param_->hapName; + std::shared_ptr kvStore; + Status status = kvDataManager_.GetSingleKvStore(options, appId, storeId, kvStore); + if (status == CRYPT_ERROR) { + options.rebuild = true; + status = kvDataManager_.GetSingleKvStore(options, appId, storeId, kvStore); + LOGE("Data has corrupted, rebuild db"); + } + errCode = ConvertCJErrCode(status); + if (errCode != 0) { + return 0; + } + if (cjOptions.kvStoreType == 1) { + auto nativeKVStore = FFIData::Create(sStoreId); + nativeKVStore->SetKvStorePtr(kvStore); + nativeKVStore->SetContextParam(param_); + return nativeKVStore->GetID(); + } + auto nativeKVStore = FFIData::Create(sStoreId); + nativeKVStore->SetKvStorePtr(kvStore); + nativeKVStore->SetContextParam(param_); + return nativeKVStore->GetID(); +} + +int32_t CJKVManager::CloseKVStore(const char* appId, const char* storeId) +{ + std::string sAppId = appId; + std::string sStoreId = storeId; + AppId appIdBox = { sAppId }; + StoreId storeIdBox { sStoreId }; + Status status = kvDataManager_.CloseKvStore(appIdBox, storeIdBox); + if ((status == Status::SUCCESS) || (status == Status::STORE_NOT_FOUND) || (status == Status::STORE_NOT_OPEN)) { + status = Status::SUCCESS; + } + return ConvertCJErrCode(status); +} + +int32_t CJKVManager::DeleteKVStore(const char* appId, const char* storeId) +{ + std::string sAppId = appId; + std::string sStoreId = storeId; + AppId appIdBox = { sAppId }; + StoreId storeIdBox { sStoreId }; + std::string databaseDir = param_->baseDir; + Status status = kvDataManager_.DeleteKvStore(appIdBox, storeIdBox, databaseDir); + return ConvertCJErrCode(status); +} + +static CArrStr VectorAppIdToCArr(const std::vector& storeIdList) +{ + CArrStr strArray; + strArray.size = static_cast(storeIdList.size()); + strArray.head = static_cast(malloc(strArray.size * sizeof(char*))); + if (strArray.head == nullptr) { + return CArrStr{0}; + } + for (int64_t i = 0; i < strArray.size; i++) { + strArray.head[i] = MallocCString(storeIdList[i].storeId); + } + return strArray; +} + +CArrStr CJKVManager::GetAllKVStoreId(const char* appId, int32_t& errCode) +{ + std::string sAppId = appId; + AppId appIdBox = { sAppId }; + std::vector storeIdList; + Status status = kvDataManager_.GetAllKvStoreId(appIdBox, storeIdList); + errCode = ConvertCJErrCode(status); + return VectorAppIdToCArr(storeIdList); +} + +CJSingleKVStore::CJSingleKVStore(const std::string& storeId) +{ + storeId_ = storeId; +} + +std::shared_ptr CJSingleKVStore::GetKvStorePtr() +{ + return kvStore_; +} + +void CJSingleKVStore::SetKvStorePtr(std::shared_ptr kvStore) +{ + kvStore_ = kvStore; +} + +void CJSingleKVStore::SetContextParam(std::shared_ptr param) +{ + param_ = param; +} + +int32_t CJSingleKVStore::Put(const std::string &key, const ValueType &value) +{ + auto tempKey = DistributedKv::Key(key); + Status status = kvStore_->Put(tempKey, ValueTypeToKVValue(value)); + return ConvertCJErrCode(status); +} + +static Entry CEntryToEntry(const CEntry &cEntry) +{ + std::string key = cEntry.key; + Entry entry = {DistributedKv::Key(key), ValueTypeToKVValue(cEntry.value)}; + return entry; +} + +static std::vector CArrayEntryToEntries(const CArrEntry &cArrEntry) +{ + std::vector entrys; + int64_t arrSize = cArrEntry.size; + + for (int64_t i = 0; i < arrSize; i++) { + Entry entry = CEntryToEntry(cArrEntry.head[i]); + entrys.push_back(entry); + } + return entrys; +} + +int32_t CJSingleKVStore::PutBatch(const CArrEntry &cArrEntry) +{ + Status status = kvStore_->PutBatch(CArrayEntryToEntries(cArrEntry)); + return ConvertCJErrCode(status); +} + +int32_t CJSingleKVStore::Delete(const std::string &key) +{ + auto tempKey = DistributedKv::Key(key); + Status status = kvStore_->Delete(tempKey); + return ConvertCJErrCode(status); +} + +static std::vector CArrStrToVectorKey(const CArrStr &cArrStr) +{ + std::vector keys; + int64_t size = cArrStr.size; + for (int64_t i = 0; i < size; i++) { + std::string str = cArrStr.head[i]; + keys.push_back(DistributedKv::Key(str)); + } + return keys; +} + +int32_t CJSingleKVStore::DeleteBatch(const CArrStr &cArrStr) +{ + Status status = kvStore_->DeleteBatch(CArrStrToVectorKey(cArrStr)); + return ConvertCJErrCode(status); +} + +ValueType CJSingleKVStore::Get(const std::string &key, int32_t& errCode) +{ + auto s_key = DistributedKv::Key(key); + OHOS::DistributedKv::Value value; + Status status = kvStore_->Get(key, value); + errCode = ConvertCJErrCode(status); + return KVValueToValueType(value); +} + +int32_t CJSingleKVStore::Backup(const std::string &file) +{ + Status status = kvStore_->Backup(file, param_->baseDir); + return ConvertCJErrCode(status); +} + +int32_t CJSingleKVStore::Restore(const std::string &file) +{ + Status status = kvStore_->Restore(file, param_->baseDir); + return ConvertCJErrCode(status); +} + +int32_t CJSingleKVStore::StartTransaction() +{ + Status status = kvStore_->StartTransaction(); + return ConvertCJErrCode(status); +} + +int32_t CJSingleKVStore::Commit() +{ + Status status = kvStore_->Commit(); + return ConvertCJErrCode(status); +} + +int32_t CJSingleKVStore::Rollback() +{ + Status status = kvStore_->Rollback(); + return ConvertCJErrCode(status); +} + +int32_t CJSingleKVStore::EnableSync(bool enabled) +{ + Status status = kvStore_->SetCapabilityEnabled(enabled); + return ConvertCJErrCode(status); +} + +int32_t CJSingleKVStore::SetSyncParam(uint32_t defaultAllowedDelayMs) +{ + KvSyncParam syncParam { defaultAllowedDelayMs }; + Status status = kvStore_->SetSyncParam(syncParam); + return ConvertCJErrCode(status); +} + +constexpr int DEVICEID_WIDTH = 4; + +static std::string GetDeviceKey(const std::string& deviceId, const std::string& key) +{ + std::ostringstream oss; + if (!deviceId.empty()) { + oss << std::setfill('0') << std::setw(DEVICEID_WIDTH) << deviceId.length() << deviceId; + } + oss << key; + return oss.str(); +} + +CJDeviceKVStore::CJDeviceKVStore(const std::string& storeId) + : CJSingleKVStore(storeId) +{ +} + +ValueType CJDeviceKVStore::Get(const std::string &deviceId, const std::string &key, int32_t& errCode) +{ + std::string deviceKey = GetDeviceKey(deviceId, key); + auto s_key = DistributedKv::Key(deviceKey); + OHOS::DistributedKv::Value value; + Status status = GetKvStorePtr()->Get(key, value); + errCode = ConvertCJErrCode(status); + return KVValueToValueType(value); +} + +CArrEntry CJDeviceKVStore::GetEntriesByDataQuery(DistributedKVStore::DataQuery dataQuery, int32_t& errCode) +{ + std::vector entries; + Status status = GetKvStorePtr()->GetEntries(dataQuery, entries); + errCode = ConvertCJErrCode(status); + CEntry *cEntries = static_cast(malloc(entries.size() * sizeof(CEntry))); + if (cEntries == nullptr) { + errCode = -1; + return CArrEntry{}; + } + for (size_t i = 0; i < entries.size(); i++) { + cEntries[i].key = MallocCString(entries[i].key.ToString()); + cEntries[i].value = KVValueToValueType(entries[i].value); + } + return CArrEntry{.head = cEntries, .size = int64_t(entries.size())}; +} + +CArrEntry CJDeviceKVStore::GetEntries(const std::string &deviceId, const std::string &keyPrefix, int32_t& errCode) +{ + DistributedKVStore::DataQuery dataQuery; + dataQuery.KeyPrefix(keyPrefix); + dataQuery.DeviceId(deviceId); + + return GetEntriesByDataQuery(dataQuery, errCode); +} + +CArrEntry CJDeviceKVStore::GetEntries(const std::string &deviceId, OHOS::sptr query, int32_t& errCode) +{ + DistributedKVStore::DataQuery dataQuery = query->GetDataQuery(); + dataQuery.DeviceId(deviceId); + + return GetEntriesByDataQuery(dataQuery, errCode); +} + +int64_t CJDeviceKVStore::GetResultSet(const std::string &deviceId, const std::string &keyPrefix, int32_t& errCode) +{ + DistributedKVStore::DataQuery dataQuery; + dataQuery.KeyPrefix(keyPrefix); + dataQuery.DeviceId(deviceId); + + std::shared_ptr kvResultSet; + Status status = GetKvStorePtr()->GetResultSet(dataQuery, kvResultSet); + errCode = ConvertCJErrCode(status); + auto nativeCKvStoreResultSet = FFIData::Create(kvResultSet); + return nativeCKvStoreResultSet->GetID(); +} + +int64_t CJDeviceKVStore::GetResultSetQuery(const std::string &deviceId, OHOS::sptr query, int32_t& errCode) +{ + DistributedKVStore::DataQuery dataQuery = query->GetDataQuery(); + dataQuery.DeviceId(deviceId); + + std::shared_ptr kvResultSet; + Status status = GetKvStorePtr()->GetResultSet(dataQuery, kvResultSet); + errCode = ConvertCJErrCode(status); + auto nativeCKvStoreResultSet = FFIData::Create(kvResultSet); + return nativeCKvStoreResultSet->GetID(); +} + +int32_t CJDeviceKVStore::GetResultSize(const std::string &deviceId, OHOS::sptr query, int32_t& errCode) +{ + DistributedKVStore::DataQuery dataQuery = query->GetDataQuery(); + dataQuery.DeviceId(deviceId); + + int32_t resultSize = 0; + Status status = GetKvStorePtr()->GetCount(dataQuery, resultSize); + errCode = ConvertCJErrCode(status); + return resultSize; +} + +CKvStoreResultSet::CKvStoreResultSet(std::shared_ptr cKvResultSet) +{ + kvResultSet = cKvResultSet; +} + +std::shared_ptr CKvStoreResultSet::GetKvStoreResultSet() +{ + return kvResultSet; +} + +int32_t CKvStoreResultSet::GetCount() +{ + return kvResultSet->GetCount(); +} + +const DistributedKv::DataQuery& CQuery::GetDataQuery() const +{ + return query_; +} + +void CQuery::Reset() +{ + query_.Reset(); +} + +void CQuery::EqualTo(const std::string &field, ValueType &value) +{ + switch (value.tag) { + case STRING: { + query_.EqualTo(field, value.string); + break; + } + case INTEGER: { + query_.EqualTo(field, value.integer); + break; + } + case FLOAT: { + query_.EqualTo(field, value.flo); + break; + } + case BOOLEAN: { + query_.EqualTo(field, value.boolean); + break; + } + case DOUBLE: { + query_.EqualTo(field, value.dou); + break; + } + default: { + break; + } + } +} +} diff --git a/kv_store/frameworks/cj/src/distributed_kv_store_utils.cpp b/kv_store/frameworks/cj/src/distributed_kv_store_utils.cpp new file mode 100644 index 00000000..e7cd8296 --- /dev/null +++ b/kv_store/frameworks/cj/src/distributed_kv_store_utils.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "distributed_kv_store_utils.h" + +namespace OHOS { +namespace DistributedKVStore { + char* MallocCString(const std::string& origin) + { + if (origin.empty()) { + return nullptr; + } + auto len = origin.length() + 1; + char* res = static_cast(malloc(sizeof(char) * len)); + if (res == nullptr) { + return nullptr; + } + return std::char_traits::copy(res, origin.c_str(), len); + } +} +} \ No newline at end of file diff --git a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/include/ikvdb_notifier.h b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/include/ikvdb_notifier.h index 7da4230d..fcef94e7 100644 --- a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/include/ikvdb_notifier.h +++ b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/include/ikvdb_notifier.h @@ -30,7 +30,8 @@ class IKVDBNotifier : public IRemoteBroker { public: DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.DistributedKv.IKvStoreSyncCallback"); virtual void SyncCompleted(const std::map &results, uint64_t sequenceId) = 0; - virtual void OnRemoteChange(const std::map &mask) = 0; + virtual void SyncCompleted(uint64_t seqNum, ProgressDetail &&detail) = 0; + virtual void OnRemoteChange(const std::map &mask, int32_t dataType) = 0; virtual void OnSwitchChange(const SwitchNotification ¬ification) = 0; }; } // namespace DistributedKv diff --git a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/src/distributed_kv_data_manager.cpp b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/src/distributed_kv_data_manager.cpp index bcec4d6f..5951b47e 100644 --- a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/src/distributed_kv_data_manager.cpp +++ b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/src/distributed_kv_data_manager.cpp @@ -198,7 +198,7 @@ Status DistributedKvDataManager::SetEndpoint(std::shared_ptr endpoint) ZLOGW("Endpoint already set"); return SUCCESS; } - + auto dbStatus = DistributedDB::KvStoreDelegateManager::SetProcessLabel("default", "default"); auto status = StoreUtil::ConvertStatus(dbStatus); if (status != SUCCESS) { @@ -229,7 +229,7 @@ Status DistributedKvDataManager::SetEndpoint(std::shared_ptr endpoint) }; return endpoint->HasDataSyncPermission(params, flag); }; - + dbStatus = DistributedDB::RuntimeConfig::SetPermissionCheckCallback(permissionCallback); status = StoreUtil::ConvertStatus(dbStatus); if (status != SUCCESS) { diff --git a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/src/ikvstore_observer.cpp b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/src/ikvstore_observer.cpp index a4562596..cab13bfe 100644 --- a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/src/ikvstore_observer.cpp +++ b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/src/ikvstore_observer.cpp @@ -92,11 +92,6 @@ void KvStoreObserverProxy::OnChange(const DataOrigin &origin, Keys &&keys) ZLOGE("write descriptor failed"); return; } - int64_t insertSize = keys[OP_INSERT].size(); - int64_t updateSize = keys[OP_UPDATE].size(); - int64_t deleteSize = keys[OP_DELETE].size(); - ZLOGD("I(%" PRId64 ") U(%" PRId64 ") D(%" PRId64 ")", insertSize, updateSize, deleteSize); - if (!ITypesUtil::Marshal(data, origin.store, keys[OP_INSERT], keys[OP_UPDATE], keys[OP_DELETE])) { ZLOGE("WriteChangeInfo to Parcel failed."); return; diff --git a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/src/kvdb_notifier_client.cpp b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/src/kvdb_notifier_client.cpp index 75354458..3fe3488d 100644 --- a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/src/kvdb_notifier_client.cpp +++ b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/src/kvdb_notifier_client.cpp @@ -43,15 +43,44 @@ void KVDBNotifierClient::SyncCompleted(const std::map &resu } } -void KVDBNotifierClient::OnRemoteChange(const std::map &mask) +void KVDBNotifierClient::SyncCompleted(uint64_t seqNum, ProgressDetail &&detail) { - ZLOGD("remote changed mask:%{public}zu", mask.size()); - for (const auto &[device, value] : mask) { + DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__), TraceSwitch::BYTRACE_ON); + cloudSyncCallbacks_.ComputeIfPresent(seqNum, [&detail](const auto &key, const AsyncDetail &callback) { + auto finished = (detail.progress == SYNC_FINISH); + ZLOGD("Sync complete, seqNum%{public}" PRIu64, key); + if (callback != nullptr) { + callback(std::move(detail)); + } + return !finished; + }); +} + +void KVDBNotifierClient::OnRemoteChange(const std::map &mask, int32_t dataType) +{ + ZLOGD("remote changed mask:%{public}zu dataType:%{public}d", mask.size(), dataType); + DataType type = static_cast(dataType); + for (const auto &[device, changed] : mask) { auto clientUuid = DevManager::GetInstance().ToUUID(device); if (clientUuid.empty()) { continue; } - remotes_.InsertOrAssign(clientUuid, value); + if (!remotes_.Contains(clientUuid)) { + remotes_.InsertOrAssign(clientUuid, std::make_pair(true, true)); + } + remotes_.Compute(clientUuid, [isChange = changed, type](const auto &key, auto &value) -> bool { + switch (type) { + case DataType::TYPE_STATICS: + value.first = isChange; + break; + case DataType::TYPE_DYNAMICAL: + value.second = isChange; + break; + default: + break; + } + return true; + }); } } @@ -64,11 +93,23 @@ void KVDBNotifierClient::OnSwitchChange(const SwitchNotification ¬ification) }); } -bool KVDBNotifierClient::IsChanged(const std::string &deviceId) +bool KVDBNotifierClient::IsChanged(const std::string &deviceId, DataType dataType) { auto [exist, value] = remotes_.Find(deviceId); - ZLOGD("exist:%{public}d, changed:%{public}d", exist, value); - return exist ? value : true; // no exist, need to sync. + ZLOGD("exist:%{public}d, statics:%{public}d dynamic:%{public}d", + exist, value.first, value.second); + if (!exist) { + return true; + } + switch (dataType) { + case DataType::TYPE_STATICS: + return value.first; + case DataType::TYPE_DYNAMICAL: + return value.second; + default: + break; + } + return true; } void KVDBNotifierClient::AddSyncCallback( @@ -89,6 +130,20 @@ void KVDBNotifierClient::DeleteSyncCallback(uint64_t sequenceId) syncCallbackInfo_.Erase(sequenceId); } +void KVDBNotifierClient::AddCloudSyncCallback(uint64_t sequenceId, const AsyncDetail &async) +{ + if (async == nullptr) { + ZLOGE("Cloud sync callback is nullptr"); + return; + } + cloudSyncCallbacks_.Insert(sequenceId, async); +} + +void KVDBNotifierClient::DeleteCloudSyncCallback(uint64_t sequenceId) +{ + cloudSyncCallbacks_.Erase(sequenceId); +} + void KVDBNotifierClient::AddSwitchCallback(const std::string &appId, std::shared_ptr observer) { if (observer == nullptr) { diff --git a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/src/kvdb_notifier_client.h b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/src/kvdb_notifier_client.h index 9b5a630f..9f55f4f8 100644 --- a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/src/kvdb_notifier_client.h +++ b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/src/kvdb_notifier_client.h @@ -29,8 +29,9 @@ public: virtual ~KVDBNotifierClient(); void SyncCompleted(const std::map &results, uint64_t sequenceId) override; + void SyncCompleted(uint64_t seqNum, ProgressDetail &&detail) override; - void OnRemoteChange(const std::map &mask) override; + void OnRemoteChange(const std::map &mask, int32_t dataType) override; void OnSwitchChange(const SwitchNotification ¬ification) override; @@ -42,12 +43,16 @@ public: void DeleteSwitchCallback(const std::string &appId, std::shared_ptr observer); - bool IsChanged(const std::string &deviceId); + void AddCloudSyncCallback(uint64_t sequenceId, const AsyncDetail &async); + void DeleteCloudSyncCallback(uint64_t sequenceId); + + bool IsChanged(const std::string &deviceId, DataType dataType); private: ConcurrentMap> syncCallbackInfo_; - ConcurrentMap remotes_; + ConcurrentMap> remotes_; ConcurrentMap> switchObservers_; + ConcurrentMap cloudSyncCallbacks_; }; } // namespace DistributedKv } // namespace OHOS diff --git a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/src/kvdb_notifier_stub.cpp b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/src/kvdb_notifier_stub.cpp index 3b7d3588..22f81088 100644 --- a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/src/kvdb_notifier_stub.cpp +++ b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/src/kvdb_notifier_stub.cpp @@ -33,6 +33,7 @@ namespace DistributedKv { const KVDBNotifierStub::Handler KVDBNotifierStub::HANDLERS[static_cast(KVDBNotifierCode::TRANS_BUTT)] = { &KVDBNotifierStub::OnSyncCompleted, + &KVDBNotifierStub::OnCloudSyncCompleted, &KVDBNotifierStub::OnOnRemoteChange, &KVDBNotifierStub::OnOnSwitchChange, }; @@ -68,14 +69,31 @@ int32_t KVDBNotifierStub::OnSyncCompleted(MessageParcel& data, MessageParcel& re return ERR_NONE; } +int32_t KVDBNotifierStub::OnCloudSyncCompleted(MessageParcel& data, MessageParcel& reply) +{ + ProgressDetail detail; + uint64_t sequenceId; + if (!ITypesUtil::Unmarshal(data, sequenceId, detail)) { + ZLOGE("Unmarshal sequenceId:%{public}" PRIu64, sequenceId); + return IPC_STUB_INVALID_DATA_ERR; + } + SyncCompleted(sequenceId, std::move(detail)); + return ERR_NONE; +} + int32_t KVDBNotifierStub::OnOnRemoteChange(MessageParcel& data, MessageParcel& reply) { std::map mask; - if (!ITypesUtil::Unmarshal(data, mask)) { + int32_t dataType; + if (!ITypesUtil::Unmarshal(data, mask, dataType)) { ZLOGE("Unmarshal fail mask size:%{public}zu", mask.size()); return IPC_STUB_INVALID_DATA_ERR; } - OnRemoteChange(std::move(mask)); + if (dataType < static_cast(DataType::TYPE_STATICS) || dataType > static_cast(DataType::TYPE_DYNAMICAL)) { + ZLOGE("Invalid dataType:%{public}d", dataType); + return IPC_STUB_INVALID_DATA_ERR; + } + OnRemoteChange(std::move(mask), dataType); return ERR_NONE; } diff --git a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/src/kvdb_notifier_stub.h b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/src/kvdb_notifier_stub.h index 7521e384..c0912281 100644 --- a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/src/kvdb_notifier_stub.h +++ b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/src/kvdb_notifier_stub.h @@ -31,6 +31,7 @@ public: private: using Handler = int32_t (KVDBNotifierStub::*)(MessageParcel &data, MessageParcel &reply); int32_t OnSyncCompleted(MessageParcel& data, MessageParcel& reply); + int32_t OnCloudSyncCompleted(MessageParcel& data, MessageParcel& reply); int32_t OnOnRemoteChange(MessageParcel& data, MessageParcel& reply); int32_t OnOnSwitchChange(MessageParcel& data, MessageParcel& reply); static const Handler HANDLERS[static_cast(KVDBNotifierCode::TRANS_BUTT)]; diff --git a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/BUILD.gn b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/BUILD.gn index 972ab1aa..40ec019b 100644 --- a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/BUILD.gn +++ b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/BUILD.gn @@ -31,8 +31,6 @@ config("module_private_config") { # for ipc_core interfaces. "//commonlibrary/c_utils/base/include", - "//foundation/distributeddatamgr/data_share/interfaces/inner_api/common/include", - "//foundation/distributeddatamgr/data_share/interfaces/inner_api/provider/include", "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata/include", "//foundation/distributedhardware/device_manager/interfaces/inner_kits/native_cpp/include", "//base/hiviewdfx/hitrace/interfaces/native/innerkits/include", @@ -106,6 +104,11 @@ ohos_source_set("distributeddatafwk_src_file") { "samgr:samgr_proxy", ] + public_external_deps = [ + "data_share:datashare_common", + "data_share:datashare_provider", + ] + part_name = "kv_store" } diff --git a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_kv_data_manager_test.cpp b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_kv_data_manager_test.cpp index c39abbcf..38b883e3 100644 --- a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_kv_data_manager_test.cpp +++ b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_kv_data_manager_test.cpp @@ -288,6 +288,10 @@ HWTEST_F(DistributedKvDataManagerTest, GetKvStore008, TestSize.Level1) std::shared_ptr cloudKvStore = nullptr; Options options = create; options.isPublic = true; + options.cloudConfig = { + .enableCloud = true, + .autoSync = true + }; Status status = manager.GetSingleKvStore(options, appId, storeId64, cloudKvStore); ASSERT_EQ(status, Status::SUCCESS); EXPECT_NE(cloudKvStore, nullptr); diff --git a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/single_kvstore_async_get_test.cpp b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/single_kvstore_async_get_test.cpp index 296021d9..86cc749e 100644 --- a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/single_kvstore_async_get_test.cpp +++ b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/single_kvstore_async_get_test.cpp @@ -148,7 +148,7 @@ HWTEST_F(SingleKvStoreAsyncGetTest, GetKvStoreWithDiffDataType, TestSize.Level1) EXPECT_EQ(status, Status::SUCCESS); options.dataType = DataType::TYPE_DYNAMICAL; status = manager.GetSingleKvStore(options, appId, storeId, store); - EXPECT_EQ(status, Status::STORE_META_CHANGED); + EXPECT_EQ(status, Status::SUCCESS); status = manager.DeleteKvStore(appId, storeId, options.baseDir); EXPECT_EQ(status, Status::SUCCESS); } @@ -181,8 +181,9 @@ HWTEST_F(SingleKvStoreAsyncGetTest, AsyncGetValue, TestSize.Level1) EXPECT_EQ(status, Status::SUCCESS); EXPECT_EQ(value.ToString(), "test_value"); auto blockData = std::make_shared>(1, false); - std::function call = [blockData](Status status, Value &&value) { - EXPECT_EQ(status, Status::NOT_SUPPORT); + std::function call = [blockData, value](Status status, Value &&out) { + EXPECT_EQ(status, Status::SUCCESS); + EXPECT_EQ(out.ToString(), value.ToString()); blockData->SetValue(true); }; auto devInfo = DevManager::GetInstance().GetLocalDevice(); @@ -311,5 +312,7 @@ HWTEST_F(SingleKvStoreAsyncGetTest, AsyncGetEntriesWithLocalNetworkId, TestSize. auto devInfo = DevManager::GetInstance().GetLocalDevice(); singleKvStore->GetEntries("prefix_of_", devInfo.networkId, call); EXPECT_EQ(blockData->GetValue(), true); + auto ret = singleKvStore->GetDeviceEntries("test_device_1", results); + EXPECT_EQ(ret, Status::SUCCESS); } } // namespace OHOS::Test \ No newline at end of file diff --git a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/single_kvstore_client_test.cpp b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/single_kvstore_client_test.cpp index 485da7da..2275f7c7 100644 --- a/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/single_kvstore_client_test.cpp +++ b/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/single_kvstore_client_test.cpp @@ -1214,10 +1214,43 @@ HWTEST_F(SingleKvStoreClientTest, CloudSync001, TestSize.Level1) options.baseDir = "/data/service/el1/public/database/odmf"; options.schema = VALID_SCHEMA_STRICT_DEFINE; options.isPublic = true; + options.cloudConfig = { + .enableCloud = true, + .autoSync = true + }; AppId appId = { "odmf" }; StoreId storeId = { "cloud_store_id" }; (void)manager.GetSingleKvStore(options, appId, storeId, cloudSyncKvStore); + ASSERT_NE(cloudSyncKvStore, nullptr); auto status = cloudSyncKvStore->CloudSync(nullptr); - EXPECT_EQ(status, Status::SUCCESS) << "cloud sync should return success"; + EXPECT_NE(status, Status::SUCCESS) << "cloud sync should not return success"; +} + +/** + * @tc.name: CloudSync002 + * desc: create kv store which not supports cloud sync and execute CloudSync interface + * type: FUNC + * require: + * author:taoyuxin + */ +HWTEST_F(SingleKvStoreClientTest, CloudSync002, TestSize.Level1) +{ + std::shared_ptr cloudSyncKvStore = nullptr; + DistributedKvDataManager manager{}; + Options options; + options.encrypt = true; + options.securityLevel = S1; + options.area = EL1; + options.kvStoreType = KvStoreType::SINGLE_VERSION; + options.baseDir = "/data/service/el1/public/database/odmf"; + options.schema = VALID_SCHEMA_STRICT_DEFINE; + options.cloudConfig.enableCloud = false; + AppId appId = { "odmf" }; + StoreId storeId = { "cloud_store_id" }; + manager.DeleteKvStore(appId, storeId, options.baseDir); + (void)manager.GetSingleKvStore(options, appId, storeId, cloudSyncKvStore); + ASSERT_NE(cloudSyncKvStore, nullptr); + auto status = cloudSyncKvStore->CloudSync(nullptr); + EXPECT_NE(status, Status::SUCCESS); } } // namespace OHOS::Test \ No newline at end of file diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/include/distributeddata_kvdb_ipc_interface_code.h b/kv_store/frameworks/innerkitsimpl/kvdb/include/distributeddata_kvdb_ipc_interface_code.h index 367dbb29..6d53f4bd 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/include/distributeddata_kvdb_ipc_interface_code.h +++ b/kv_store/frameworks/innerkitsimpl/kvdb/include/distributeddata_kvdb_ipc_interface_code.h @@ -42,16 +42,19 @@ enum class KVDBServiceInterfaceCode : uint32_t { TRANS_SYNC_EXT, TRANS_CLOUD_SYNC, TRANS_NOTIFY_DATA_CHANGE, + TRANS_SET_CONFIG, TRANS_PUT_SWITCH, TRANS_GET_SWITCH, TRANS_SUBSCRIBE_SWITCH_DATA, TRANS_UNSUBSCRIBE_SWITCH_DATA, + TRANS_CLOSE, TRANS_BUTT }; enum class KVDBNotifierCode : uint32_t { TRANS_HEAD = 0, TRANS_SYNC_COMPLETED = TRANS_HEAD, + TRANS_CLOUD_SYNC_COMPLETED, TRANS_ON_REMOTE_CHANGED, TRANS_ON_SWITCH_CHANGED, TRANS_BUTT diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/include/kv_types_util.h b/kv_store/frameworks/innerkitsimpl/kvdb/include/kv_types_util.h index 0a1ec201..6c8988c7 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/include/kv_types_util.h +++ b/kv_store/frameworks/innerkitsimpl/kvdb/include/kv_types_util.h @@ -30,10 +30,15 @@ using DeviceInfo = DistributedKv::DeviceInfo; using ChangeNotification = DistributedKv::ChangeNotification; using Options = DistributedKv::Options; using SyncPolicy = DistributedKv::SyncPolicy; +using TableDetail = DistributedKv::TableDetail; +using Statistic = DistributedKv::Statistic; +using ProgressDetail = DistributedKv::ProgressDetail; using SwitchData = DistributedKv::SwitchData; using Status = OHOS::DistributedKv::Status; using Notification = OHOS::DistributedKv::SwitchNotification; using SwitchState = OHOS::DistributedKv::SwitchState; +using CloudConfig = OHOS::DistributedKv::CloudConfig; +using StoreConfig = OHOS::DistributedKv::StoreConfig; template<> API_EXPORT bool Marshalling(const Blob &input, MessageParcel &data); template<> @@ -89,6 +94,31 @@ API_EXPORT bool Marshalling(const Notification &input, MessageParcel &data); template<> API_EXPORT bool Unmarshalling(Notification &output, MessageParcel &data); +template<> +API_EXPORT bool Marshalling(const ProgressDetail &input, MessageParcel &data); +template<> +API_EXPORT bool Unmarshalling(ProgressDetail &output, MessageParcel &data); + +template<> +API_EXPORT bool Marshalling(const TableDetail &input, MessageParcel &data); +template<> +API_EXPORT bool Unmarshalling(TableDetail &output, MessageParcel &data); + +template<> +API_EXPORT bool Marshalling(const Statistic &input, MessageParcel &data); +template<> +API_EXPORT bool Unmarshalling(Statistic &output, MessageParcel &data); + +template<> +API_EXPORT bool Marshalling(const CloudConfig &input, MessageParcel &data); +template<> +API_EXPORT bool Unmarshalling(CloudConfig &output, MessageParcel &data); + +template<> +API_EXPORT bool Marshalling(const StoreConfig &input, MessageParcel &data); +template<> +API_EXPORT bool Unmarshalling(StoreConfig &output, MessageParcel &data); + int64_t GetTotalSize(const std::vector &entries); int64_t GetTotalSize(const std::vector &entries); } // namespace OHOS::ITypesUtil diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/include/kvdb_service.h b/kv_store/frameworks/innerkitsimpl/kvdb/include/kvdb_service.h index 54080b25..bd003bad 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/include/kvdb_service.h +++ b/kv_store/frameworks/innerkitsimpl/kvdb/include/kvdb_service.h @@ -32,6 +32,7 @@ public: uint32_t delay = 0; std::vector devices; std::string query; + uint64_t syncId = 0; }; DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.DistributedKv.KVFeature"); @@ -44,8 +45,9 @@ public: virtual Status AfterCreate( const AppId &appId, const StoreId &storeId, const Options &options, const std::vector &password) = 0; virtual Status Delete(const AppId &appId, const StoreId &storeId) = 0; - virtual Status Sync(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) = 0; - virtual Status SyncExt(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) = 0; + virtual Status Close(const AppId &appId, const StoreId &storeId) = 0; + virtual Status Sync(const AppId &appId, const StoreId &storeId, SyncInfo &syncInfo) = 0; + virtual Status SyncExt(const AppId &appId, const StoreId &storeId, SyncInfo &syncInfo) = 0; virtual Status RegServiceNotifier(const AppId &appId, sptr notifier) = 0; virtual Status UnregServiceNotifier(const AppId &appId) = 0; virtual Status SetSyncParam(const AppId &appId, const StoreId &storeId, const KvSyncParam &syncParam) = 0; @@ -60,12 +62,13 @@ public: virtual Status Unsubscribe(const AppId &appId, const StoreId &storeId, sptr observer) = 0; virtual Status GetBackupPassword( const AppId &appId, const StoreId &storeId, std::vector &password) = 0; - virtual Status CloudSync(const AppId &appId, const StoreId &storeId) = 0; + virtual Status CloudSync(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) = 0; virtual Status NotifyDataChange(const AppId &appId, const StoreId &storeId) = 0; virtual Status PutSwitch(const AppId &appId, const SwitchData &data) = 0; virtual Status GetSwitch(const AppId &appId, const std::string &networkId, SwitchData &data) = 0; virtual Status SubscribeSwitchData(const AppId &appId) = 0; virtual Status UnsubscribeSwitchData(const AppId &appId) = 0; + virtual Status SetConfig(const AppId &appId, const StoreId &storeId, const StoreConfig &storeConfig) = 0; }; } // namespace OHOS::DistributedKv -#endif // OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_SERVICE_H +#endif // OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_SERVICE_H \ No newline at end of file diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/include/kvdb_service_client.h b/kv_store/frameworks/innerkitsimpl/kvdb/include/kvdb_service_client.h index 77649e4a..efe99f20 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/include/kvdb_service_client.h +++ b/kv_store/frameworks/innerkitsimpl/kvdb/include/kvdb_service_client.h @@ -35,8 +35,9 @@ public: Status AfterCreate(const AppId &appId, const StoreId &storeId, const Options &options, const std::vector &password) override; Status Delete(const AppId &appId, const StoreId &storeId) override; - Status Sync(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) override; - Status SyncExt(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) override; + Status Close(const AppId &appId, const StoreId &storeId) override; + Status Sync(const AppId &appId, const StoreId &storeId, SyncInfo &syncInfo) override; + Status SyncExt(const AppId &appId, const StoreId &storeId, SyncInfo &syncInfo) override; Status RegServiceNotifier(const AppId &appId, sptr notifier) override; Status UnregServiceNotifier(const AppId &appIdd) override; Status SetSyncParam(const AppId &appId, const StoreId &storeId, const KvSyncParam &syncParam) override; @@ -50,12 +51,13 @@ public: Status Subscribe(const AppId &appId, const StoreId &storeId, sptr observer) override; Status Unsubscribe(const AppId &appId, const StoreId &storeId, sptr observer) override; Status GetBackupPassword(const AppId &appId, const StoreId &storeId, std::vector &password) override; - Status CloudSync(const AppId &appId, const StoreId &storeId) override; + Status CloudSync(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) override; Status NotifyDataChange(const AppId &appId, const StoreId &storeId) override; Status PutSwitch(const AppId &appId, const SwitchData &data) override; Status GetSwitch(const AppId &appId, const std::string &networkId, SwitchData &data) override; Status SubscribeSwitchData(const AppId &appId) override; Status UnsubscribeSwitchData(const AppId &appId) override; + Status SetConfig(const AppId &appId, const StoreId &storeId, const StoreConfig &storeConfig) override; sptr GetServiceAgent(const AppId &appId); protected: @@ -77,4 +79,4 @@ private: sptr serviceAgent_; }; } // namespace OHOS::DistributedKv -#endif // OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_SERVICE_CLIENT_H +#endif // OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_SERVICE_CLIENT_H \ No newline at end of file diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/include/observer_bridge.h b/kv_store/frameworks/innerkitsimpl/kvdb/include/observer_bridge.h index 1c05cdc3..d16b7fff 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/include/observer_bridge.h +++ b/kv_store/frameworks/innerkitsimpl/kvdb/include/observer_bridge.h @@ -30,8 +30,8 @@ public: ObserverBridge(AppId appId, StoreId storeId, std::shared_ptr observer, const Convertor &cvt); ~ObserverBridge(); - Status RegisterRemoteObserver(); - Status UnregisterRemoteObserver(); + Status RegisterRemoteObserver(uint32_t realType); + Status UnregisterRemoteObserver(uint32_t realType); void OnChange(const DBChangedData &data) override; void OnServiceDeath(); @@ -43,7 +43,9 @@ private: void OnChange(const DataOrigin &origin, Keys &&keys) override __attribute__((no_sanitize("cfi"))); private: + friend class ObserverBridge; const Convertor &convert_; + uint32_t realType_; }; template @@ -51,7 +53,7 @@ private: AppId appId_; StoreId storeId_; std::shared_ptr observer_; - sptr remote_; + sptr remote_; const Convertor &convert_; }; } // namespace OHOS::DistributedKv diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h b/kv_store/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h index efbfcff2..dbcf3c7f 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h +++ b/kv_store/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h @@ -65,6 +65,7 @@ public: const std::function &&)> &onResult) override; Status GetEntries(const Key &prefix, std::vector &entries) const override; Status GetEntries(const DataQuery &query, std::vector &entries) const override; + Status GetDeviceEntries(const std::string &device, std::vector &entries) const override; Status GetResultSet(const Key &prefix, std::shared_ptr &resultSet) const override; Status GetResultSet(const DataQuery &query, std::shared_ptr &resultSet) const override; Status CloseResultSet(std::shared_ptr &resultSet) override; @@ -98,6 +99,7 @@ public: Status SubscribeWithQuery(const std::vector &devices, const DataQuery &query) override; Status UnsubscribeWithQuery(const std::vector &devices, const DataQuery &query) override; Status CloudSync(const AsyncDetail &async) override; + Status SetConfig(const StoreConfig &storeConfig) override; protected: std::shared_ptr PutIn(uint32_t &realType, std::shared_ptr observer); std::shared_ptr TakeOut(uint32_t &realType, std::shared_ptr observer); @@ -120,15 +122,16 @@ private: Status GetEntries(const DBQuery &query, std::vector &entries) const; Status RetryWithCheckPoint(std::function lambda); std::function BridgeReleaser(); - Status DoSync(const SyncInfo &syncInfo, std::shared_ptr observer); - Status DoSyncExt(const SyncInfo &syncInfo, std::shared_ptr observer); - Status DoClientSync(const SyncInfo &syncInfo, std::shared_ptr observer); + Status DoSync(SyncInfo &syncInfo, std::shared_ptr observer); + Status DoSyncExt(SyncInfo &syncInfo, std::shared_ptr observer); + Status DoClientSync(SyncInfo &syncInfo, std::shared_ptr observer); Status SyncExt(const std::string &networkId, uint64_t sequenceId); bool IsRemoteChanged(const std::string &deviceId); void DoNotifyChange(); void Register(); bool autoSync_ = false; + bool cloudAutoSync_ = false; bool isClientSync_ = false; mutable std::shared_mutex rwMutex_; const Convertor &convertor_; @@ -144,4 +147,4 @@ private: ConcurrentMap asyncFuncs_; }; } // namespace OHOS::DistributedKv -#endif // OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_SINGLE_STORE_IMPL_H +#endif // OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_SINGLE_STORE_IMPL_H \ No newline at end of file diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/include/store_util.h b/kv_store/frameworks/innerkitsimpl/kvdb/include/store_util.h index eac812f3..4b93e816 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/include/store_util.h +++ b/kv_store/frameworks/innerkitsimpl/kvdb/include/store_util.h @@ -49,6 +49,7 @@ public: static bool Remove(const std::string &path); static void Flush(); static uint64_t GenSequenceId(); + static bool RemoveRWXForOthers(const std::string &path); private: static std::atomic sequenceId_; }; diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/src/auto_sync_timer.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/src/auto_sync_timer.cpp deleted file mode 100644 index 6fc836c3..00000000 --- a/kv_store/frameworks/innerkitsimpl/kvdb/src/auto_sync_timer.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#define LOG_TAG "AutoSyncTimer" -#include "auto_sync_timer.h" - -#include "kvdb_service_client.h" -#include "log_print.h" - -namespace OHOS::DistributedKv { -AutoSyncTimer &AutoSyncTimer::GetInstance() -{ - static AutoSyncTimer instance; - return instance; -} - -void AutoSyncTimer::StartTimer() -{ - std::lock_guard lockGuard(mutex_); - if (forceSyncTaskId_ == TaskExecutor::INVALID_TASK_ID) { - forceSyncTaskId_ = - TaskExecutor::GetInstance().Schedule(std::chrono::milliseconds(FORCE_SYNC_INTERVAL), ProcessTask()); - } - if (delaySyncTaskId_ == TaskExecutor::INVALID_TASK_ID) { - delaySyncTaskId_ = - TaskExecutor::GetInstance().Schedule(std::chrono::milliseconds(AUTO_SYNC_INTERVAL), ProcessTask()); - } else { - delaySyncTaskId_ = - TaskExecutor::GetInstance().Reset(delaySyncTaskId_, std::chrono::milliseconds(AUTO_SYNC_INTERVAL)); - } -} - -void AutoSyncTimer::DoAutoSync(const std::string &appId, std::set storeIds) -{ - AddSyncStores(appId, std::move(storeIds)); - StartTimer(); -} - -void AutoSyncTimer::AddSyncStores(const std::string &appId, std::set storeIds) -{ - stores_.Compute(appId, [&storeIds](const auto &key, std::vector &value) { - std::set tempStores(value.begin(), value.end()); - for (auto it = storeIds.begin(); it != storeIds.end(); it++) { - if (tempStores.count(*it) == 0) { - value.push_back(*it); - } - } - return !value.empty(); - }); -} - -bool AutoSyncTimer::HasSyncStores() -{ - return !stores_.Empty(); -} - -std::map> AutoSyncTimer::GetStoreIds() -{ - std::map> stores; - int count = SYNC_STORE_NUM; - stores_.EraseIf([&stores, &count](const std::string &key, std::vector &value) { - int size = value.size(); - if (size <= count) { - stores.insert({ key, std::move(value) }); - count = count - size; - return true; - } - auto &innerStore = stores[key]; - auto it = value.begin(); - while (it != value.end() && count > 0) { - innerStore.push_back(*it); - it++; - count--; - } - value.erase(value.begin(), it); - return value.empty(); - }); - return stores; -} - -std::function AutoSyncTimer::ProcessTask() -{ - return [this]() { - StopTimer(); - auto service = KVDBServiceClient::GetInstance(); - if (service == nullptr) { - return; - } - - auto storeIds = GetStoreIds(); - for (const auto &id : storeIds) { - ZLOGD("DoSync appId:%{public}s store size:%{public}zu", id.first.c_str(), id.second.size()); - for (const auto &storeId : id.second) { - service->Sync({ id.first }, storeId, {}); - } - } - if (HasSyncStores()) { - StartTimer(); - } - }; -} - -void AutoSyncTimer::StopTimer() -{ - std::lock_guard lockGuard(mutex_); - TaskExecutor::GetInstance().Remove(forceSyncTaskId_); - TaskExecutor::GetInstance().Remove(delaySyncTaskId_); - forceSyncTaskId_ = TaskExecutor::INVALID_TASK_ID; - delaySyncTaskId_ = TaskExecutor::INVALID_TASK_ID; -} -} // namespace OHOS::DistributedKv diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/src/backup_manager.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/src/backup_manager.cpp index 5a358ad6..f21796e4 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/src/backup_manager.cpp +++ b/kv_store/frameworks/innerkitsimpl/kvdb/src/backup_manager.cpp @@ -165,7 +165,7 @@ StoreUtil::FileInfo BackupManager::GetBackupFileInfo( backupFile = std::move(file); break; } - if ((file.modifyTime > modifyTime) && (file.size != 0)) { + if (name.empty() && (file.modifyTime > modifyTime) && (file.size != 0)) { modifyTime = file.modifyTime; backupFile = std::move(file); } diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/src/kv_types_util.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/src/kv_types_util.cpp index 9a0308d8..1f59bc3f 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/src/kv_types_util.cpp +++ b/kv_store/frameworks/innerkitsimpl/kvdb/src/kv_types_util.cpp @@ -105,7 +105,8 @@ bool Unmarshalling(ChangeNotification &output, MessageParcel &parcel) template<> bool Marshalling(const Options &input, MessageParcel &data) { - if (!ITypesUtil::Marshal(data, input.schema, input.hapName, input.policies)) { + if (!ITypesUtil::Marshal(data, input.schema, input.hapName, input.policies, input.cloudConfig.enableCloud, + input.cloudConfig.autoSync)) { ZLOGE("write policies failed"); return false; } @@ -130,7 +131,8 @@ bool Marshalling(const Options &input, MessageParcel &data) template<> bool Unmarshalling(Options &output, MessageParcel &data) { - if (!ITypesUtil::Unmarshal(data, output.schema, output.hapName, output.policies)) { + if (!ITypesUtil::Unmarshal(data, output.schema, output.hapName, output.policies, output.cloudConfig.enableCloud, + output.cloudConfig.autoSync)) { ZLOGE("read policies failed"); return false; } @@ -213,6 +215,59 @@ bool Unmarshalling(Notification &output, MessageParcel &data) return true; } +template<> +bool Marshalling(const ProgressDetail &input, MessageParcel &data) +{ + return Marshal(data, input.progress, input.code, input.details); +} +template<> +bool Unmarshalling(ProgressDetail &output, MessageParcel &data) +{ + return Unmarshal(data, output.progress, output.code, output.details); +} +template<> +bool Marshalling(const TableDetail &input, MessageParcel &data) +{ + return Marshal(data, input.upload, input.download); +} +template<> +bool Unmarshalling(TableDetail &output, MessageParcel &data) +{ + return Unmarshal(data, output.upload, output.download); +} +template<> +bool Marshalling(const Statistic &input, MessageParcel &data) +{ + return Marshal(data, input.total, input.success, input.failed, input.untreated); +} +template<> +bool Unmarshalling(Statistic &output, MessageParcel &data) +{ + return Unmarshal(data, output.total, output.success, output.failed, output.untreated); +} + +template<> +bool Marshalling(const CloudConfig &input, MessageParcel &data) +{ + return Marshal(data, input.enableCloud, input.autoSync); +} +template<> +bool Unmarshalling(CloudConfig &output, MessageParcel &data) +{ + return Unmarshal(data, output.enableCloud, output.autoSync); +} + +template<> +bool Marshalling(const StoreConfig &input, MessageParcel &data) +{ + return Marshal(data, input.cloudConfig); +} +template<> +bool Unmarshalling(StoreConfig &output, MessageParcel &data) +{ + return Unmarshal(data, output.cloudConfig); +} + int64_t GetTotalSize(const std::vector &entries) { int64_t bufferSize = 1; diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/src/kvdb_service_client.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/src/kvdb_service_client.cpp index 051fb382..11a039a0 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/src/kvdb_service_client.cpp +++ b/kv_store/frameworks/innerkitsimpl/kvdb/src/kvdb_service_client.cpp @@ -83,7 +83,7 @@ std::shared_ptr KVDBServiceClient::GetInstance() if (client == nullptr) { client = new (std::nothrow) KVDBServiceClient(service); } - + if (client == nullptr) { return nullptr; } @@ -152,7 +152,19 @@ Status KVDBServiceClient::Delete(const AppId &appId, const StoreId &storeId) return static_cast(status); } -Status KVDBServiceClient::Sync(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) +Status KVDBServiceClient::Close(const AppId &appId, const StoreId &storeId) +{ + MessageParcel reply; + int32_t status = IPC_SEND(static_cast(KVDBServiceInterfaceCode::TRANS_CLOSE), + reply, appId, storeId); + if (status != SUCCESS) { + ZLOGE("status:0x%{public}x appId:%{public}s, storeId:%{public}s", status, appId.appId.c_str(), + StoreUtil::Anonymous(storeId.storeId).c_str()); + } + return static_cast(status); +} + +Status KVDBServiceClient::Sync(const AppId &appId, const StoreId &storeId, SyncInfo &syncInfo) { MessageParcel reply; int32_t status = IPC_SEND(static_cast(KVDBServiceInterfaceCode::TRANS_SYNC), reply, appId, storeId, @@ -164,18 +176,19 @@ Status KVDBServiceClient::Sync(const AppId &appId, const StoreId &storeId, const return static_cast(status); } -Status KVDBServiceClient::CloudSync(const AppId &appId, const StoreId &storeId) +Status KVDBServiceClient::CloudSync(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) { MessageParcel reply; int32_t status = IPC_SEND( - static_cast(KVDBServiceInterfaceCode::TRANS_CLOUD_SYNC), reply, appId, storeId); + static_cast(KVDBServiceInterfaceCode::TRANS_CLOUD_SYNC), reply, appId, storeId, syncInfo.seqId); if (status != SUCCESS) { - ZLOGE("status: 0x%{public}x" PRIu64, status); + ZLOGE("status:0x%{public}x, appId:%{public}s, storeId:%{public}s" PRIu64, status, appId.appId.c_str(), + StoreUtil::Anonymous(storeId.storeId).c_str()); } return static_cast(status); } -Status KVDBServiceClient::SyncExt(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) +Status KVDBServiceClient::SyncExt(const AppId &appId, const StoreId &storeId, SyncInfo &syncInfo) { MessageParcel reply; int32_t status = IPC_SEND(static_cast(KVDBServiceInterfaceCode::TRANS_SYNC_EXT), reply, appId, @@ -411,4 +424,16 @@ Status KVDBServiceClient::UnsubscribeSwitchData(const AppId &appId) } return static_cast(status); } + +Status KVDBServiceClient::SetConfig(const AppId &appId, const StoreId &storeId, const StoreConfig &storeConfig) +{ + MessageParcel reply; + int32_t status = IPC_SEND( + static_cast(KVDBServiceInterfaceCode::TRANS_SET_CONFIG), reply, appId, storeId, storeConfig); + if (status != SUCCESS) { + ZLOGE("status:0x%{public}x appId:%{public}s, storeId:%{public}s", status, + appId.appId.c_str(), StoreUtil::Anonymous(storeId.storeId).c_str()); + } + return static_cast(status); +} } // namespace OHOS::DistributedKv \ No newline at end of file diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/src/observer_bridge.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/src/observer_bridge.cpp index 5a2ecbdc..a557d1ec 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/src/observer_bridge.cpp +++ b/kv_store/frameworks/innerkitsimpl/kvdb/src/observer_bridge.cpp @@ -33,9 +33,10 @@ ObserverBridge::~ObserverBridge() service->Unsubscribe(appId_, storeId_, remote_); } -Status ObserverBridge::RegisterRemoteObserver() +Status ObserverBridge::RegisterRemoteObserver(uint32_t realType) { if (remote_ != nullptr) { + remote_->realType_ |= realType; return SUCCESS; } @@ -48,11 +49,13 @@ Status ObserverBridge::RegisterRemoteObserver() auto status = service->Subscribe(appId_, storeId_, remote_); if (status != SUCCESS) { remote_ = nullptr; + } else { + remote_->realType_ = realType; } return status; } -Status ObserverBridge::UnregisterRemoteObserver() +Status ObserverBridge::UnregisterRemoteObserver(uint32_t realType) { if (remote_ == nullptr) { return SUCCESS; @@ -63,8 +66,13 @@ Status ObserverBridge::UnregisterRemoteObserver() return SERVER_UNAVAILABLE; } - auto status = service->Unsubscribe(appId_, storeId_, remote_); - remote_ = nullptr; + Status status = Status::SUCCESS; + remote_->realType_ &= ~SUBSCRIBE_TYPE_LOCAL; + remote_->realType_ &= ~realType; + if (remote_->realType_ == 0) { + status = service->Unsubscribe(appId_, storeId_, remote_); + remote_ = nullptr; + } return status; } @@ -85,6 +93,9 @@ ObserverBridge::ObserverClient::ObserverClient(std::shared_ptr observe void ObserverBridge::ObserverClient::OnChange(const ChangeNotification &data) { + if ((realType_ & SUBSCRIBE_TYPE_REMOTE) != SUBSCRIBE_TYPE_REMOTE) { + return; + } std::string deviceId; auto inserted = ObserverBridge::ConvertDB(data.GetInsertEntries(), deviceId, convert_); auto updated = ObserverBridge::ConvertDB(data.GetUpdateEntries(), deviceId, convert_); @@ -95,6 +106,9 @@ void ObserverBridge::ObserverClient::OnChange(const ChangeNotification &data) void ObserverBridge::ObserverClient::OnChange(const DataOrigin &origin, Keys &&keys) { + if ((realType_ & SUBSCRIBE_TYPE_CLOUD) != SUBSCRIBE_TYPE_CLOUD) { + return; + } KvStoreObserverClient::OnChange(origin, std::move(keys)); } diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/src/process_system_api_adapter_impl.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/src/process_system_api_adapter_impl.cpp index cdb3746e..982d5beb 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/src/process_system_api_adapter_impl.cpp +++ b/kv_store/frameworks/innerkitsimpl/kvdb/src/process_system_api_adapter_impl.cpp @@ -23,7 +23,7 @@ namespace OHOS::DistributedKv { using Label = DistributedDB::SecurityLabel; using Flag = DistributedDB::SecurityFlag; -using SecurityLabel = DistributedFS::ModuleSecurityLabel::SecurityLabel; +using SecurityLabel = FileManagement::ModuleSecurityLabel::SecurityLabel; constexpr int32_t HEAD_SIZE = 3; constexpr int32_t END_SIZE = 3; constexpr const char *REPLACE_CHAIN = "***"; diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/src/security_manager.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/src/security_manager.cpp index 696544bd..4201c2a2 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/src/security_manager.cpp +++ b/kv_store/frameworks/innerkitsimpl/kvdb/src/security_manager.cpp @@ -125,6 +125,7 @@ std::vector SecurityManager::LoadKeyFromFile(const std::string &name, c if (!FileExists(keyPath)) { return {}; } + StoreUtil::RemoveRWXForOthers(path + "/key"); std::vector content; auto loaded = LoadBufferFromFile(keyPath, content); @@ -168,6 +169,9 @@ bool SecurityManager::SaveKeyToFile(const std::string &name, const std::string & content.insert(content.end(), secretKey.begin(), secretKey.end()); auto keyFullPath = keyPath + "/" + name + ".key"; auto ret = SaveBufferToFile(keyFullPath, content); + if (access(keyFullPath.c_str(), F_OK) == 0) { + StoreUtil::RemoveRWXForOthers(keyFullPath); + } content.assign(content.size(), 0); if (!ret) { ZLOGE("client SaveSecretKey failed!"); diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp index 0f166e05..7f53f00b 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp +++ b/kv_store/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp @@ -35,6 +35,7 @@ SingleStoreImpl::SingleStoreImpl( appId_ = appId.appId; storeId_ = dbStore_->GetStoreId(); autoSync_ = options.autoSync; + cloudAutoSync_ = options.cloudConfig.autoSync; isClientSync_ = options.isClientSync; syncObserver_ = std::make_shared(); roleType_ = options.role; @@ -201,7 +202,7 @@ Status SingleStoreImpl::Commit() auto dbStatus = dbStore_->Commit(); auto status = StoreUtil::ConvertStatus(dbStatus); if (status != SUCCESS) { - ZLOGE("status:0x%{public}x storeId:%{public}s", status, dbStore_->GetStoreId().c_str()); + ZLOGE("status:0x%{public}x storeId:%{public}s", status, StoreUtil::Anonymous(storeId_).c_str()); } return status; } @@ -258,7 +259,7 @@ Status SingleStoreImpl::SubscribeKvStore(SubscribeType type, std::shared_ptrRegisterRemoteObserver(); + status = bridge->RegisterRemoteObserver(realType); } if (status != SUCCESS) { @@ -296,9 +297,11 @@ Status SingleStoreImpl::UnSubscribeKvStore(SubscribeType type, std::shared_ptrUnregisterRemoteObserver(); + status = bridge->UnregisterRemoteObserver(realType); } if (status != SUCCESS) { @@ -337,46 +340,18 @@ void SingleStoreImpl::Get(const Key &key, const std::string &networkId, const std::function &onResult) { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); - if (dataType_ != DataType::TYPE_DYNAMICAL) { - onResult(NOT_SUPPORT, Value()); - return; - } - if (networkId == DevManager::GetInstance().GetLocalDevice().networkId || !IsRemoteChanged(networkId)) { - Value value; - auto status = Get(key, value); - onResult(status, std::move(value)); - return; - } - uint64_t sequenceId = StoreUtil::GenSequenceId(); - asyncFuncs_.Insert(sequenceId, { .key = key, .toGet = onResult }); - auto result = SyncExt(networkId, sequenceId); - if (result != SUCCESS) { - asyncFuncs_.Erase(sequenceId); - onResult(result, Value()); - } + Value value; + auto status = Get(key, value); + onResult(status, std::move(value)); } void SingleStoreImpl::GetEntries(const Key &prefix, const std::string &networkId, const std::function &&)> &onResult) { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); - if (dataType_ != DataType::TYPE_DYNAMICAL) { - onResult(NOT_SUPPORT, {}); - return; - } - if (networkId == DevManager::GetInstance().GetLocalDevice().networkId || !IsRemoteChanged(networkId)) { - std::vector entries; - auto status = GetEntries(prefix, entries); - onResult(status, std::move(entries)); - return; - } - uint64_t sequenceId = StoreUtil::GenSequenceId(); - asyncFuncs_.Insert(sequenceId, { .key = prefix, .toGetEntries = onResult }); - auto result = SyncExt(networkId, sequenceId); - if (result != SUCCESS) { - asyncFuncs_.Erase(sequenceId); - onResult(result, {}); - } + std::vector entries; + auto status = GetEntries(prefix, entries); + onResult(status, std::move(entries)); } Status SingleStoreImpl::SyncExt(const std::string &networkId, uint64_t sequenceId) @@ -387,6 +362,7 @@ Status SingleStoreImpl::SyncExt(const std::string &networkId, uint64_t sequenceI return INVALID_ARGUMENT; } KVDBService::SyncInfo syncInfo; + syncInfo.mode = SyncMode::PULL; syncInfo.seqId = sequenceId; syncInfo.devices = { networkId }; auto status = DoSyncExt(syncInfo, shared_from_this()); @@ -401,7 +377,7 @@ Status SingleStoreImpl::SyncExt(const std::string &networkId, uint64_t sequenceI void SingleStoreImpl::SyncCompleted(const std::map &results, uint64_t sequenceId) { AsyncFunc asyncFunc; - auto exist = asyncFuncs_.ComputeIfPresent(sequenceId, [&asyncFunc](const auto &key, auto &value) -> bool { + auto exist = asyncFuncs_.ComputeIfPresent(sequenceId, [&asyncFunc](const auto &key, const auto &value) -> bool { asyncFunc = value; return false; }); @@ -439,7 +415,7 @@ bool SingleStoreImpl::IsRemoteChanged(const std::string &deviceId) if (serviceAgent == nullptr) { return true; } - return serviceAgent->IsChanged(clientUuid); + return serviceAgent->IsChanged(clientUuid, static_cast(dataType_)); } void SingleStoreImpl::SyncCompleted(const std::map &results) @@ -494,6 +470,36 @@ Status SingleStoreImpl::GetResultSet(const Key &prefix, std::shared_ptr &entries) const +{ + std::shared_lock lock(rwMutex_); + if (dbStore_ == nullptr) { + ZLOGE("db:%{public}s already closed!", StoreUtil::Anonymous(storeId_).c_str()); + return ALREADY_CLOSED; + } + if (device.empty()) { + ZLOGE("no devices"); + return INVALID_ARGUMENT; + } + std::vector dbEntries; + std::string devId; + auto dbStatus = dbStore_->GetDeviceEntries(device, dbEntries); + entries.resize(dbEntries.size()); + auto it = entries.begin(); + for (auto &dbEntry : dbEntries) { + auto &entry = *it; + entry.key = convertor_.ToKey(std::move(dbEntry.key), devId); + entry.value = std::move(dbEntry.value); + ++it; + } + + auto status = StoreUtil::ConvertStatus(dbStatus); + if (status == NOT_FOUND) { + status = SUCCESS; + } + return status; +} + Status SingleStoreImpl::GetResultSet(const DataQuery &query, std::shared_ptr &resultSet) const { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); @@ -615,13 +621,21 @@ Status SingleStoreImpl::CloudSync(const AsyncDetail &async) if (service == nullptr) { return SERVER_UNAVAILABLE; } - auto status = service->CloudSync({ appId_ }, { storeId_ }); - if (status == SUCCESS) { - return SUCCESS; - } else { + auto serviceAgent = service->GetServiceAgent({ appId_ }); + if (serviceAgent == nullptr) { + ZLOGE("failed! invalid agent app:%{public}s store:%{public}s!", appId_.c_str(), + StoreUtil::Anonymous(storeId_).c_str()); + return ILLEGAL_STATE; + } + KVDBService::SyncInfo syncInfo; + syncInfo.seqId = StoreUtil::GenSequenceId(); + serviceAgent->AddCloudSyncCallback(syncInfo.seqId, async); + auto status = service->CloudSync({ appId_ }, { storeId_ }, syncInfo); + if (status != SUCCESS) { ZLOGE("sync failed!: %{public}d", status); - return ERROR; + serviceAgent->DeleteCloudSyncCallback(syncInfo.seqId); } + return status; } Status SingleStoreImpl::RegisterSyncCallback(std::shared_ptr callback) @@ -768,6 +782,10 @@ Status SingleStoreImpl::Backup(const std::string &file, const std::string &baseD Status SingleStoreImpl::Restore(const std::string &file, const std::string &baseDir) { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); + auto service = KVDBServiceClient::GetInstance(); + if (service != nullptr) { + service->Close({ appId_ }, { storeId_ }); + } auto status = BackupManager::GetInstance().Restore(file, baseDir, appId_, storeId_, dbStore_); if (status != SUCCESS) { ZLOGE("status:0x%{public}x storeId:%{public}s backup:%{public}s ", status, @@ -805,7 +823,7 @@ std::function SingleStoreImpl::BridgeReleaser() } } - Status remote = obj->UnregisterRemoteObserver(); + Status remote = obj->UnregisterRemoteObserver(SUBSCRIBE_TYPE_ALL); if (status != SUCCESS || remote != SUCCESS) { ZLOGE("status:0x%{public}x remote:0x%{public}x observer:0x%{public}x", status, remote, StoreUtil::Anonymous(obj)); @@ -903,7 +921,7 @@ Status SingleStoreImpl::GetEntries(const DBQuery &query, std::vector &ent return status; } -Status SingleStoreImpl::DoClientSync(const SyncInfo &syncInfo, std::shared_ptr observer) +Status SingleStoreImpl::DoClientSync(SyncInfo &syncInfo, std::shared_ptr observer) { auto complete = [observer](const std::map &devicesMap) { if (observer == nullptr) { @@ -915,7 +933,7 @@ Status SingleStoreImpl::DoClientSync(const SyncInfo &syncInfo, std::shared_ptrSyncCompleted(result); }; - + auto dbStatus = dbStore_->Sync(syncInfo.devices, StoreUtil::GetDBMode(SyncMode(syncInfo.mode)), complete); Status status = StoreUtil::ConvertStatus(dbStatus); if (status != Status::SUCCESS) { @@ -924,7 +942,7 @@ Status SingleStoreImpl::DoClientSync(const SyncInfo &syncInfo, std::shared_ptr observer) +Status SingleStoreImpl::DoSync(SyncInfo &syncInfo, std::shared_ptr observer) { Status cStatus = Status::SUCCESS; if (isClientSync_) { @@ -960,7 +978,7 @@ Status SingleStoreImpl::DoSync(const SyncInfo &syncInfo, std::shared_ptr observer) +Status SingleStoreImpl::DoSyncExt(SyncInfo &syncInfo, std::shared_ptr observer) { auto service = KVDBServiceClient::GetInstance(); if (service == nullptr) { @@ -980,9 +998,18 @@ Status SingleStoreImpl::DoSyncExt(const SyncInfo &syncInfo, std::shared_ptrSetConfig({ appId_ }, { storeId_ }, storeConfig); +} + void SingleStoreImpl::DoNotifyChange() { - if (!autoSync_ && dataType_ == DataType::TYPE_DYNAMICAL) { + if (!autoSync_ && !cloudAutoSync_ && dataType_ == DataType::TYPE_DYNAMICAL) { return; } ZLOGD("app:%{public}s store:%{public}s dataType:%{public}d!", @@ -1001,7 +1028,8 @@ void SingleStoreImpl::OnRemoteDied() return; } observers_.ForEach([](const auto &, std::pair> &pair) { - if ((pair.first & SUBSCRIBE_TYPE_REMOTE) == SUBSCRIBE_TYPE_REMOTE) { + if ((pair.first & SUBSCRIBE_TYPE_REMOTE) == SUBSCRIBE_TYPE_REMOTE || + (pair.first & SUBSCRIBE_TYPE_CLOUD) == SUBSCRIBE_TYPE_CLOUD) { pair.second->OnServiceDeath(); } return false; @@ -1016,8 +1044,9 @@ void SingleStoreImpl::Register() std::shared_lock lock(rwMutex_); Status status = SUCCESS; observers_.ForEach([&status](const auto &, std::pair> &pair) { - if ((pair.first & SUBSCRIBE_TYPE_REMOTE) == SUBSCRIBE_TYPE_REMOTE) { - status = pair.second->RegisterRemoteObserver(); + if ((pair.first & SUBSCRIBE_TYPE_REMOTE) == SUBSCRIBE_TYPE_REMOTE || + (pair.first & SUBSCRIBE_TYPE_CLOUD) == SUBSCRIBE_TYPE_CLOUD) { + status = pair.second->RegisterRemoteObserver(pair.first); if (status != SUCCESS) { return true; } @@ -1044,4 +1073,4 @@ Status SingleStoreImpl::SetIdentifier(const std::string &accountId, const std::s } return status; } -} // namespace OHOS::DistributedKv +} // namespace OHOS::DistributedKv \ No newline at end of file diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/src/store_factory.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/src/store_factory.cpp index ae6382f5..e16eef88 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/src/store_factory.cpp +++ b/kv_store/frameworks/innerkitsimpl/kvdb/src/store_factory.cpp @@ -184,10 +184,10 @@ StoreFactory::DBOption StoreFactory::GetDBOption(const Options &options, const D dbOption.passwd = dbPassword.password; } - if (options.kvStoreType == KvStoreType::SINGLE_VERSION) { - dbOption.conflictResolvePolicy = DistributedDB::LAST_WIN; - } else if (options.kvStoreType == KvStoreType::DEVICE_COLLABORATION) { + if (options.isPublic || options.kvStoreType == KvStoreType::DEVICE_COLLABORATION) { dbOption.conflictResolvePolicy = DistributedDB::DEVICE_COLLABORATION; + } else if (options.kvStoreType == KvStoreType::SINGLE_VERSION) { + dbOption.conflictResolvePolicy = DistributedDB::LAST_WIN; } else if (options.kvStoreType == KvStoreType::LOCAL_ONLY) { dbOption.storageEngineType = DistributedDB::GAUSSDB_RD; } diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/src/store_manager.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/src/store_manager.cpp index 82a30507..86861d64 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/src/store_manager.cpp +++ b/kv_store/frameworks/innerkitsimpl/kvdb/src/store_manager.cpp @@ -64,7 +64,7 @@ std::shared_ptr StoreManager::GetKVStore(const AppId &appId, cons } pwd.assign(pwd.size(), 0); } - if (status == SUCCESS && service != nullptr && options.dataType == DataType::TYPE_DYNAMICAL) { + if (status == SUCCESS && service != nullptr) { auto serviceAgent = service->GetServiceAgent(appId); if (serviceAgent == nullptr) { ZLOGE("invalid agent app:%{public}s", appId.appId.c_str()); @@ -193,4 +193,4 @@ Status StoreManager::UnsubscribeSwitchData(const AppId &appId, std::shared_ptrDeleteSwitchCallback(appId.appId, observer); return SUCCESS; } -} // namespace OHOS::DistributedKv +} // namespace OHOS::DistributedKv \ No newline at end of file diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/src/store_util.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/src/store_util.cpp index 72303dd1..0b967237 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/src/store_util.cpp +++ b/kv_store/frameworks/innerkitsimpl/kvdb/src/store_util.cpp @@ -168,9 +168,9 @@ bool StoreUtil::InitPath(const std::string &path) { umask(DEFAULT_UMASK); if (access(path.c_str(), F_OK) == 0) { - return true; + return RemoveRWXForOthers(path); } - if (mkdir(path.c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) != 0 && errno != EEXIST) { + if (mkdir(path.c_str(), (S_IRWXU | S_IRWXG)) != 0 && errno != EEXIST) { ZLOGE("mkdir error:%{public}d, path:%{public}s", errno, path.c_str()); return false; } @@ -184,7 +184,7 @@ bool StoreUtil::CreateFile(const std::string &name) { umask(DEFAULT_UMASK); if (access(name.c_str(), F_OK) == 0) { - return true; + return RemoveRWXForOthers(name); } int fp = open(name.c_str(), (O_WRONLY | O_CREAT), (S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP)); if (fp < 0) { @@ -289,4 +289,38 @@ uint64_t StoreUtil::GenSequenceId() } return seqId; } + +bool StoreUtil::RemoveRWXForOthers(const std::string &path) +{ + struct stat buf; + if (stat(path.c_str(), &buf) < 0) { + ZLOGI("stat error:%{public}d, path:%{public}s", errno, path.c_str()); + return true; + } + + if ((buf.st_mode & S_IRWXO) == 0) { + return true; + } + + if (S_ISDIR(buf.st_mode)) { + DIR *dirp = opendir(path.c_str()); + struct dirent *dp = nullptr; + while ((dp = readdir(dirp)) != nullptr) { + if ((std::string(dp->d_name) == ".") || (std::string(dp->d_name) == "..")) { + continue; + } + if (!RemoveRWXForOthers(path + "/" + dp->d_name)) { + closedir(dirp); + return false; + } + } + closedir(dirp); + } + + if (chmod(path.c_str(), (buf.st_mode & ~S_IRWXO)) < 0) { + ZLOGE("chmod error:%{public}d, path:%{public}s", errno, path.c_str()); + return false; + } + return true; +} } // namespace OHOS::DistributedKv \ No newline at end of file diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/src/system_api.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/src/system_api.cpp index b1d147d2..dc534779 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/src/system_api.cpp +++ b/kv_store/frameworks/innerkitsimpl/kvdb/src/system_api.cpp @@ -23,7 +23,7 @@ namespace OHOS::DistributedKv { using Label = DistributedDB::SecurityLabel; using Flag = DistributedDB::SecurityFlag; -using SecurityLabel = DistributedFS::ModuleSecurityLabel::SecurityLabel; +using SecurityLabel = OHOS::FileManagement::ModuleSecurityLabel::SecurityLabel; SystemApi::SystemApi() { } diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/test/BUILD.gn b/kv_store/frameworks/innerkitsimpl/kvdb/test/BUILD.gn index d0fb674f..4a74ca36 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/test/BUILD.gn +++ b/kv_store/frameworks/innerkitsimpl/kvdb/test/BUILD.gn @@ -11,7 +11,6 @@ # See the License for the specific language governing permissions and # limitations under the License. import("//build/test.gni") -import("//foundation/distributeddatamgr/data_share/datashare.gni") import("//foundation/distributeddatamgr/kv_store/kv_store.gni") module_output_path = "kv_store/distributeddatafwk" @@ -24,8 +23,6 @@ config("module_private_config") { "${kv_store_base_path}/frameworks/innerkitsimpl/distributeddatasvc/include", "../../../../interfaces/innerkits/distributeddatamgr/include/", "//commonlibrary/c_utils/base/include", - "${datashare_innerapi_path}/common/include", - "${datashare_innerapi_path}/provider/include", "//foundation/distributeddatamgr/kv_store/frameworks/common", "//foundation/distributeddatamgr/kv_store/frameworks/innerkitsimpl/kvdb/include", "//foundation/distributeddatamgr/kv_store/frameworks/innerkitsimpl/kvdb/src", @@ -35,7 +32,6 @@ config("module_private_config") { "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/app_distributeddata/include", "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata/include", "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/app/include", - "//foundation/distributeddatamgr/distributedfile/interfaces/kits/js/src/mod_securitylabel", "//foundation/distributedhardware/device_manager/interfaces/inner_kits/native_cpp/include", "//base/hiviewdfx/hitrace/interfaces/native/innerkits/include", "//test/testfwk/developer_test/aw/distributed", @@ -95,6 +91,7 @@ ohos_source_set("kvdb_src_file") { ] external_deps = [ "c_utils:utils", + "file_api:securitylabel", "hilog:libhilog", "hisysevent:libhisysevent", "hitrace:hitrace_meter", @@ -104,6 +101,11 @@ ohos_source_set("kvdb_src_file") { "samgr:samgr_proxy", ] + public_external_deps = [ + "data_share:datashare_common", + "data_share:datashare_provider", + ] + part_name = "kv_store" } diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/test/auto_sync_timer_test.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/test/auto_sync_timer_test.cpp deleted file mode 100644 index 63983305..00000000 --- a/kv_store/frameworks/innerkitsimpl/kvdb/test/auto_sync_timer_test.cpp +++ /dev/null @@ -1,412 +0,0 @@ -/* -* Copyright (c) 2022 Huawei Device Co., Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#include "auto_sync_timer.h" - -#include - -#include "block_data.h" -#include "kvdb_service_client.h" -#include "store_manager.h" - -using namespace OHOS; -using namespace testing::ext; -using namespace OHOS::DistributedKv; -using namespace std::chrono; -namespace OHOS::Test { -class AutoSyncTimerTest : public testing::Test { -public: - class KVDBServiceMock : public KVDBServiceClient { - private: - static KVDBServiceMock *instance_; - - public: - static KVDBServiceMock *GetInstance() - { - KVDBServiceClient::GetInstance(); - return instance_; - } - explicit KVDBServiceMock(const sptr &object) : KVDBServiceClient(object) - { - instance_ = this; - } - virtual ~KVDBServiceMock() - { - instance_ = nullptr; - } - - Status Sync(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) override - { - endTime = time_point_cast(system_clock::now()).time_since_epoch().count(); - values_[appId.appId].insert(storeId.storeId); - { - std::lock_guard guard(mutex_); - ++callCount; - value_.SetValue(callCount); - } - return KVDBServiceClient::Sync(appId, storeId, syncInfo); - } - - uint32_t GetCallCount(uint32_t value) - { - uint32_t retry = 0; - uint32_t callTimes = 0; - while (retry < value) { - callTimes = value_.GetValue(); - if (callTimes >= value) { - break; - } - std::lock_guard guard(mutex_); - callTimes = value_.GetValue(); - if (callTimes >= value) { - break; - } - value_.Clear(callTimes); - retry++; - } - return callTimes; - } - - void ResetToZero() - { - std::lock_guard guard(mutex_); - callCount = 0; - value_.Clear(0); - } - - uint64_t startTime = 0; - uint64_t endTime = 0; - uint32_t callCount = 0; - std::map> values_; - BlockData value_{ 1, 0 }; - std::mutex mutex_; - }; - class TestSyncCallback : public KvStoreSyncCallback { - public: - void SyncCompleted(const std::map &results) override - { - ASSERT_TRUE(true); - } - }; - static void SetUpTestCase(void); - static void TearDownTestCase(void); - void SetUp(); - void TearDown(); - -protected: - static BrokerDelegator delegator_; - static constexpr int SLEEP_TIME = 10; -}; -BrokerDelegator AutoSyncTimerTest::delegator_; -AutoSyncTimerTest::KVDBServiceMock *AutoSyncTimerTest::KVDBServiceMock::instance_ = nullptr; -void AutoSyncTimerTest::SetUpTestCase(void) -{ -} - -void AutoSyncTimerTest::TearDownTestCase(void) -{ -} - -void AutoSyncTimerTest::SetUp(void) -{ -} - -void AutoSyncTimerTest::TearDown(void) -{ - sleep(SLEEP_TIME); // make sure the case has executed completely -} - -/** -* @tc.name: SingleWrite -* @tc.desc: single write -* @tc.type: FUNC -* @tc.require: I4XVQQ -* @tc.author: Yang Qing -*/ -HWTEST_F(AutoSyncTimerTest, SingleWrite, TestSize.Level0) -{ - auto *instance = KVDBServiceMock::GetInstance(); - ASSERT_NE(instance, nullptr); - instance->ResetToZero(); - instance->startTime = time_point_cast(system_clock::now()).time_since_epoch().count(); - instance->endTime = 0; - instance->values_.clear(); - AutoSyncTimer::GetInstance().DoAutoSync("ut_test", { { "ut_test_store" } }); - EXPECT_EQ(static_cast(instance->GetCallCount(1)), 1); - auto it = instance->values_.find("ut_test"); - ASSERT_NE(it, instance->values_.end()); - ASSERT_EQ(it->second.count("ut_test_store"), 1); - ASSERT_LT(instance->endTime - instance->startTime, 100); -} - -/** -* @tc.name: MultiWriteBelowDelayTime -* @tc.desc: write every 40 milliseconds -* @tc.type: FUNC -* @tc.require: I4XVQQ -* @tc.author: Yang Qing -*/ -HWTEST_F(AutoSyncTimerTest, MultiWriteBelowDelayTime, TestSize.Level1) -{ - auto *instance = KVDBServiceMock::GetInstance(); - ASSERT_NE(instance, nullptr); - instance->ResetToZero(); - instance->startTime = time_point_cast(system_clock::now()).time_since_epoch().count(); - instance->endTime = 0; - instance->values_.clear(); - std::atomic_bool finished = false; - std::thread thread([&finished] { - while (!finished.load()) { - AutoSyncTimer::GetInstance().DoAutoSync("ut_test", { { "ut_test_store" } }); - std::this_thread::sleep_for(std::chrono::milliseconds(40)); - } - }); - EXPECT_EQ(static_cast(instance->GetCallCount(1)), 1); - ASSERT_GE(instance->endTime - instance->startTime, 200); - ASSERT_LT(instance->endTime - instance->startTime, 250); - finished.store(true); - thread.join(); - auto it = instance->values_.find("ut_test"); - ASSERT_NE(it, instance->values_.end()); - ASSERT_EQ(it->second.count("ut_test_store"), 1); -} - -/** -* @tc.name: MultiWriteOverDelayTime -* @tc.desc: write every 150 milliseconds -* @tc.type: FUNC -* @tc.require: I4XVQQ -* @tc.author: Yang Qing - */ -HWTEST_F(AutoSyncTimerTest, MultiWriteOverDelayTime, TestSize.Level1) -{ - auto *instance = KVDBServiceMock::GetInstance(); - ASSERT_NE(instance, nullptr); - instance->ResetToZero(); - instance->startTime = time_point_cast(system_clock::now()).time_since_epoch().count(); - instance->endTime = 0; - instance->values_.clear(); - std::atomic_bool finished = false; - std::thread thread([&finished] { - while (!finished.load()) { - AutoSyncTimer::GetInstance().DoAutoSync("ut_test", { { "ut_test_store" } }); - std::this_thread::sleep_for(std::chrono::milliseconds(150)); - } - }); - EXPECT_EQ(static_cast(instance->GetCallCount(1)), 1); - ASSERT_LT(instance->endTime - instance->startTime, 100); - finished.store(true); - thread.join(); - auto it = instance->values_.find("ut_test"); - ASSERT_NE(it, instance->values_.end()); - ASSERT_EQ(it->second.count("ut_test_store"), 1); -} - -/** -* @tc.name: MultiWriteOverForceTime -* @tc.desc: write every 400 milliseconds -* @tc.type: FUNC -* @tc.require: I4XVQQ -* @tc.author: Yang Qing - */ -HWTEST_F(AutoSyncTimerTest, MultiWriteOverForceTime, TestSize.Level1) -{ - auto *instance = KVDBServiceMock::GetInstance(); - ASSERT_NE(instance, nullptr); - instance->ResetToZero(); - instance->startTime = time_point_cast(system_clock::now()).time_since_epoch().count(); - instance->endTime = 0; - instance->values_.clear(); - std::atomic_bool finished = false; - std::thread thread([&finished] { - while (!finished.load()) { - AutoSyncTimer::GetInstance().DoAutoSync("ut_test", { { "ut_test_store" } }); - std::this_thread::sleep_for(std::chrono::milliseconds(400)); - } - }); - EXPECT_EQ(static_cast(instance->GetCallCount(1)), 1); - ASSERT_LT(instance->endTime - instance->startTime, 100); - finished.store(true); - thread.join(); - auto it = instance->values_.find("ut_test"); - ASSERT_NE(it, instance->values_.end()); - ASSERT_EQ(it->second.count("ut_test_store"), 1); -} - -/** -* @tc.name: SingleWriteOvertenKVStores -* @tc.desc: single write over ten kv stores -* @tc.type: FUNC -* @tc.require: I4XVQQ -* @tc.author: Yang Qing -*/ -HWTEST_F(AutoSyncTimerTest, SingleWriteOvertenKVStores, TestSize.Level1) -{ - auto *instance = KVDBServiceMock::GetInstance(); - ASSERT_NE(instance, nullptr); - instance->ResetToZero(); - instance->startTime = time_point_cast(system_clock::now()).time_since_epoch().count(); - instance->endTime = 0; - instance->values_.clear(); - AutoSyncTimer::GetInstance().DoAutoSync("ut_test", { - { "ut_test_store0" }, - { "ut_test_store1" }, - { "ut_test_store2" }, - { "ut_test_store3" }, - { "ut_test_store4" }, - { "ut_test_store5" }, - { "ut_test_store6" }, - { "ut_test_store7" }, - { "ut_test_store8" }, - { "ut_test_store9" }, - { "ut_test_store10" }, - }); - EXPECT_EQ(static_cast(instance->GetCallCount(1)), 1); - ASSERT_LT(instance->endTime - instance->startTime, 100); - EXPECT_EQ(static_cast(instance->GetCallCount(11)), 11); - auto it = instance->values_.find("ut_test"); - ASSERT_NE(it, instance->values_.end()); - ASSERT_EQ(it->second.count("ut_test_store0"), 1); - ASSERT_EQ(it->second.count("ut_test_store1"), 1); - ASSERT_EQ(it->second.count("ut_test_store2"), 1); - ASSERT_EQ(it->second.count("ut_test_store3"), 1); - ASSERT_EQ(it->second.count("ut_test_store4"), 1); - ASSERT_EQ(it->second.count("ut_test_store5"), 1); - ASSERT_EQ(it->second.count("ut_test_store6"), 1); - ASSERT_EQ(it->second.count("ut_test_store7"), 1); - ASSERT_EQ(it->second.count("ut_test_store8"), 1); - ASSERT_EQ(it->second.count("ut_test_store9"), 1); - ASSERT_EQ(it->second.count("ut_test_store10"), 1); -} - -/** -* @tc.name: MultiWriteOvertenKVStores -* @tc.desc: mulity wirte -* @tc.type: FUNC -* @tc.require: I4XVQQ -* @tc.author: YangQing -*/ -HWTEST_F(AutoSyncTimerTest, MultiWriteOvertenKVStores, TestSize.Level1) -{ - auto *instance = KVDBServiceMock::GetInstance(); - ASSERT_NE(instance, nullptr); - instance->ResetToZero(); - instance->startTime = time_point_cast(system_clock::now()).time_since_epoch().count(); - instance->endTime = 0; - instance->values_.clear(); - std::atomic_bool finished = false; - std::thread thread([&finished] { - while (!finished.load()) { - AutoSyncTimer::GetInstance().DoAutoSync("ut_test", { - { "ut_test_store0" }, - { "ut_test_store1" }, - { "ut_test_store2" }, - { "ut_test_store3" }, - { "ut_test_store4" }, - { "ut_test_store5" }, - { "ut_test_store6" }, - { "ut_test_store7" }, - { "ut_test_store8" }, - { "ut_test_store9" }, - { "ut_test_store10" }, - }); - usleep(40); - } - }); - EXPECT_EQ(static_cast(instance->GetCallCount(1)), 1); - ASSERT_GE(instance->endTime - instance->startTime, 200); - ASSERT_LT(instance->endTime - instance->startTime, 250); - EXPECT_EQ(static_cast(instance->GetCallCount(11)), 11); - auto it = instance->values_.find("ut_test"); - ASSERT_EQ(it->second.count("ut_test_store0"), 1); - ASSERT_EQ(it->second.count("ut_test_store1"), 1); - ASSERT_EQ(it->second.count("ut_test_store2"), 1); - ASSERT_EQ(it->second.count("ut_test_store3"), 1); - ASSERT_EQ(it->second.count("ut_test_store4"), 1); - ASSERT_EQ(it->second.count("ut_test_store5"), 1); - ASSERT_EQ(it->second.count("ut_test_store6"), 1); - ASSERT_EQ(it->second.count("ut_test_store7"), 1); - ASSERT_EQ(it->second.count("ut_test_store8"), 1); - ASSERT_EQ(it->second.count("ut_test_store9"), 1); - ASSERT_EQ(it->second.count("ut_test_store10"), 1); - finished.store(true); - thread.join(); -} - -/** -* @tc.name: DoubleWrite -* @tc.desc: double wirte -* @tc.type: FUNC -* @tc.require: I4XVQQ -* @tc.author: YangQing - */ -HWTEST_F(AutoSyncTimerTest, DoubleWrite, TestSize.Level1) -{ - auto *instance = KVDBServiceMock::GetInstance(); - ASSERT_NE(instance, nullptr); - instance->ResetToZero(); - instance->startTime = time_point_cast(system_clock::now()).time_since_epoch().count(); - instance->endTime = 0; - instance->values_.clear(); - AutoSyncTimer::GetInstance().DoAutoSync("ut_test", { - { "ut_test_store0" }, - { "ut_test_store1" }, - { "ut_test_store2" }, - { "ut_test_store3" }, - { "ut_test_store4" }, - { "ut_test_store5" }, - { "ut_test_store6" }, - { "ut_test_store7" }, - { "ut_test_store8" }, - { "ut_test_store9" }, - { "ut_test_store10" }, - }); - AutoSyncTimer::GetInstance().DoAutoSync("ut_test", { - { "ut_test_store-0" }, - { "ut_test_store-1" }, - { "ut_test_store-2" }, - { "ut_test_store-3" }, - { "ut_test_store-4" }, - { "ut_test_store-5" }, - { "ut_test_store-6" }, - { "ut_test_store-7" }, - { "ut_test_store-8" }, - }); - EXPECT_EQ(static_cast(instance->GetCallCount(1)), 1); - ASSERT_LT(instance->endTime - instance->startTime, 100); - EXPECT_EQ(static_cast(instance->GetCallCount(20)), 20); - auto it = instance->values_.find("ut_test"); - ASSERT_EQ(it->second.count("ut_test_store0"), 1); - ASSERT_EQ(it->second.count("ut_test_store1"), 1); - ASSERT_EQ(it->second.count("ut_test_store2"), 1); - ASSERT_EQ(it->second.count("ut_test_store3"), 1); - ASSERT_EQ(it->second.count("ut_test_store4"), 1); - ASSERT_EQ(it->second.count("ut_test_store5"), 1); - ASSERT_EQ(it->second.count("ut_test_store6"), 1); - ASSERT_EQ(it->second.count("ut_test_store7"), 1); - ASSERT_EQ(it->second.count("ut_test_store8"), 1); - ASSERT_EQ(it->second.count("ut_test_store9"), 1); - ASSERT_EQ(it->second.count("ut_test_store10"), 1); - ASSERT_EQ(it->second.count("ut_test_store-0"), 1); - ASSERT_EQ(it->second.count("ut_test_store-1"), 1); - ASSERT_EQ(it->second.count("ut_test_store-2"), 1); - ASSERT_EQ(it->second.count("ut_test_store-3"), 1); - ASSERT_EQ(it->second.count("ut_test_store-4"), 1); - ASSERT_EQ(it->second.count("ut_test_store-5"), 1); - ASSERT_EQ(it->second.count("ut_test_store-6"), 1); - ASSERT_EQ(it->second.count("ut_test_store-7"), 1); - ASSERT_EQ(it->second.count("ut_test_store-8"), 1); -} -} // namespace OHOS::Test \ No newline at end of file diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/test/data_change_notifier_test.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/test/data_change_notifier_test.cpp index 3d217c84..368486da 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/test/data_change_notifier_test.cpp +++ b/kv_store/frameworks/innerkitsimpl/kvdb/test/data_change_notifier_test.cpp @@ -99,6 +99,10 @@ public: { ASSERT_TRUE(true); } + void SyncCompleted(const std::map &results, uint64_t sequenceId) override + { + ASSERT_TRUE(true); + } }; static void SetUpTestCase(void); static void TearDownTestCase(void); diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/test/single_store_impl_test.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/test/single_store_impl_test.cpp index 60dc2325..853ae072 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/test/single_store_impl_test.cpp +++ b/kv_store/frameworks/innerkitsimpl/kvdb/test/single_store_impl_test.cpp @@ -1129,6 +1129,9 @@ HWTEST_F(SingleStoreImplTest, RegisterSyncCallback, TestSize.Level0) void SyncCompleted(const map &results) override { } + void SyncCompleted(const std::map &results, uint64_t sequenceId) override + { + } }; auto callback = std::make_shared(); auto status = kvStore_->RegisterSyncCallback(callback); @@ -1150,6 +1153,9 @@ HWTEST_F(SingleStoreImplTest, UnRegisterSyncCallback, TestSize.Level0) void SyncCompleted(const map &results) override { } + void SyncCompleted(const std::map &results, uint64_t sequenceId) override + { + } }; auto callback = std::make_shared(); auto status = kvStore_->RegisterSyncCallback(callback); @@ -1606,10 +1612,11 @@ HWTEST_F(SingleStoreImplTest, StaticStoreAsyncGet, TestSize.Level0) ASSERT_NE(kvStore, nullptr); BlockData blockData{ 1, false }; std::function result = [&blockData](Status status, Value&& value) { - ASSERT_EQ(status, Status::NOT_SUPPORT); + ASSERT_EQ(status, Status::NOT_FOUND); blockData.SetValue(true); }; - kvStore->Get({"key"}, "networkId", result); + auto networkId = DevManager::GetInstance().GetLocalDevice().networkId; + kvStore->Get({"key"}, networkId, result); blockData.GetValue(); status = StoreManager::GetInstance().CloseKVStore(appId, storeId); ASSERT_EQ(status, SUCCESS); @@ -1641,10 +1648,11 @@ HWTEST_F(SingleStoreImplTest, StaticStoreAsyncGetEntries, TestSize.Level0) BlockData blockData{ 1, false }; std::function&&)> result = [&blockData](Status status, std::vector&& value) { - ASSERT_EQ(status, Status::NOT_SUPPORT); + ASSERT_EQ(status, Status::SUCCESS); blockData.SetValue(true); }; - kvStore->GetEntries({"key"}, "networkId", result); + auto networkId = DevManager::GetInstance().GetLocalDevice().networkId; + kvStore->GetEntries({"key"}, networkId, result); blockData.GetValue(); status = StoreManager::GetInstance().CloseKVStore(appId, storeId); ASSERT_EQ(status, SUCCESS); @@ -1732,4 +1740,33 @@ HWTEST_F(SingleStoreImplTest, DynamicStoreAsyncGetEntries, TestSize.Level0) status = StoreManager::GetInstance().CloseKVStore(appId, storeId); ASSERT_EQ(status, SUCCESS); } + +/** + * @tc.name: SetConfig + * @tc.desc: SetConfig + * @tc.type: FUNC + * @tc.require: + * @tc.author: ht + */ +HWTEST_F(SingleStoreImplTest, SetConfig, TestSize.Level0) +{ + std::string baseDir = "/data/service/el1/public/database/SingleStoreImplTest"; + AppId appId = { "SingleStoreImplTest" }; + StoreId storeId = { "SetConfigTest" }; + std::shared_ptr kvStore; + Options options; + options.kvStoreType = SINGLE_VERSION; + options.securityLevel = S1; + options.area = EL1; + options.rebuild = true; + options.baseDir = "/data/service/el1/public/database/SingleStoreImplTest"; + options.dataType = DataType::TYPE_DYNAMICAL; + options.cloudConfig.enableCloud = false; + Status status; + kvStore = StoreManager::GetInstance().GetKVStore(appId, storeId, options, status); + ASSERT_NE(kvStore, nullptr); + StoreConfig storeConfig; + storeConfig.cloudConfig.enableCloud = true; + ASSERT_EQ(kvStore->SetConfig(storeConfig), Status::SUCCESS); +} } // namespace OHOS::Test \ No newline at end of file diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/test/store_util_test.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/test/store_util_test.cpp index 0de6157d..568359a7 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/test/store_util_test.cpp +++ b/kv_store/frameworks/innerkitsimpl/kvdb/test/store_util_test.cpp @@ -15,7 +15,9 @@ #include "store_util.h" +#include #include +#include #include #include "store_manager.h" @@ -129,4 +131,73 @@ HWTEST_F(StoreUtilTest, GetObserverMode, TestSize.Level1) mode = storeUtil_.GetObserverMode(SUBSCRIBE_TYPE_ALL); ASSERT_EQ(mode, DistributedDB::OBSERVER_CHANGES_FOREIGN | DistributedDB::OBSERVER_CHANGES_NATIVE); } +/** +* @tc.name: CheckPermissions001 +* @tc.desc: Check if the permissions for the first file creation are normal +* @tc.type: FUNC +* @tc.require: +* @tc.author: Shao Yuanzhao +*/ +HWTEST_F(StoreUtilTest, CheckPermissions001, TestSize.Level1) +{ + StoreUtil storeUtil_; + std::string path = "/data/store_utils_test1"; + bool success = storeUtil_.InitPath(path); + ASSERT_TRUE(success); + + struct stat buf; + int ret = stat(path.c_str(), &buf); + ASSERT_GE(ret, 0); + ASSERT_FALSE(buf.st_mode & S_IRWXO); + + std::string fileName = path + "/test1.txt"; + success = storeUtil_.CreateFile(fileName); + ASSERT_TRUE(success); + ret = stat(fileName.c_str(), &buf); + ASSERT_GE(ret, 0); + ASSERT_FALSE(buf.st_mode & S_IRWXO); + + remove(fileName.c_str()); + rmdir(path.c_str()); +} +/** +* @tc.name: CheckPermissions002 +* @tc.desc: Check if updating existing file permissions is correct +* @tc.type: FUNC +* @tc.require: +* @tc.author: Shao Yuanzhao +*/ +HWTEST_F(StoreUtilTest, CheckPermissions002, TestSize.Level1) +{ + std::string path = "/data/store_utils_test2"; + int ret = mkdir(path.c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)); + struct stat buf; + ret = stat(path.c_str(), &buf); + ASSERT_GE(ret, 0); + ASSERT_TRUE(buf.st_mode & S_IRWXO); + + StoreUtil storeUtil_; + bool success = storeUtil_.InitPath(path); + ASSERT_TRUE(success); + ret = stat(path.c_str(), &buf); + ASSERT_GE(ret, 0); + ASSERT_FALSE(buf.st_mode & S_IRWXO); + + std::string fileName = path + "/test2.txt"; + int fp = open(fileName.c_str(), (O_WRONLY | O_CREAT), (S_IRWXU | S_IRWXG | S_IRWXO)); + ASSERT_GE(fp, 0); + close(fp); + ret = stat(fileName.c_str(), &buf); + ASSERT_GE(ret, 0); + ASSERT_TRUE(buf.st_mode & S_IRWXO); + + success = storeUtil_.CreateFile(fileName); + ASSERT_TRUE(success); + ret = stat(fileName.c_str(), &buf); + ASSERT_GE(ret, 0); + ASSERT_FALSE(buf.st_mode & S_IRWXO); + + remove(fileName.c_str()); + rmdir(path.c_str()); +} } // namespace OHOS::Test \ No newline at end of file diff --git a/kv_store/frameworks/jskitsimpl/distributeddata/include/js_util.h b/kv_store/frameworks/jskitsimpl/distributeddata/include/js_util.h index d9ebeead..12fce1a2 100644 --- a/kv_store/frameworks/jskitsimpl/distributeddata/include/js_util.h +++ b/kv_store/frameworks/jskitsimpl/distributeddata/include/js_util.h @@ -92,7 +92,7 @@ public: static napi_status SetValue(napi_env env, const QueryVariant& in, napi_value& out); /* napi_value <-> std::vector */ - static napi_status GetValue(napi_env env, napi_value in, std::vector& out); + static napi_status GetValue(napi_env env, napi_value in, std::vector& out, bool checkLength = true); static napi_status SetValue(napi_env env, const std::vector& in, napi_value& out); /* napi_value <-> std::vector */ 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 7b8b5ac3..e6b91446 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 @@ -73,6 +73,7 @@ napi_value JsKVStoreResultSet::GetCount(napi_env env, napi_callback_info info) / ZLOGD("KVStoreResultSet::GetCount(status=%{public}d)", ctxt->status); auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); int count = resultSet->GetCount(); napi_create_int32(env, count, &ctxt->output); @@ -87,6 +88,7 @@ napi_value JsKVStoreResultSet::GetPosition(napi_env env, napi_callback_info info NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); int position = resultSet->GetPosition(); napi_create_int32(env, position, &ctxt->output); @@ -101,6 +103,7 @@ napi_value JsKVStoreResultSet::MoveToFirst(napi_env env, napi_callback_info info NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isMoved = resultSet->MoveToFirst(); napi_get_boolean(env, isMoved, &ctxt->output); @@ -115,6 +118,7 @@ napi_value JsKVStoreResultSet::MoveToLast(napi_env env, napi_callback_info info) NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isMoved = resultSet->MoveToLast(); napi_get_boolean(env, isMoved, &ctxt->output); @@ -129,6 +133,7 @@ napi_value JsKVStoreResultSet::MoveToNext(napi_env env, napi_callback_info info) NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isMoved = resultSet->MoveToNext(); napi_get_boolean(env, isMoved, &ctxt->output); @@ -143,6 +148,7 @@ napi_value JsKVStoreResultSet::MoveToPrevious(napi_env env, napi_callback_info i NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isMoved = resultSet->MoveToPrevious(); napi_get_boolean(env, isMoved, &ctxt->output); @@ -163,6 +169,7 @@ napi_value JsKVStoreResultSet::Move(napi_env env, napi_callback_info info) /* bo NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isMoved = resultSet->Move(offset); napi_get_boolean(env, isMoved, &ctxt->output); @@ -183,6 +190,7 @@ napi_value JsKVStoreResultSet::MoveToPosition(napi_env env, napi_callback_info i ZLOGD("KVStoreResultSet::MoveToPosition(%{public}d)", position); auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isMoved = resultSet->MoveToPosition(position); napi_get_boolean(env, isMoved, &ctxt->output); @@ -197,6 +205,7 @@ napi_value JsKVStoreResultSet::IsFirst(napi_env env, napi_callback_info info) /* NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isFirst = resultSet->IsFirst(); napi_get_boolean(env, isFirst, &ctxt->output); @@ -211,6 +220,7 @@ napi_value JsKVStoreResultSet::IsLast(napi_env env, napi_callback_info info) /* NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isLast = resultSet->IsLast(); napi_get_boolean(env, isLast, &ctxt->output); @@ -225,6 +235,7 @@ napi_value JsKVStoreResultSet::IsBeforeFirst(napi_env env, napi_callback_info in NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isBeforeFirst = resultSet->IsBeforeFirst(); napi_get_boolean(env, isBeforeFirst, &ctxt->output); @@ -239,6 +250,7 @@ napi_value JsKVStoreResultSet::IsAfterLast(napi_env env, napi_callback_info info NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isAfterLast = resultSet->IsAfterLast(); napi_get_boolean(env, isAfterLast, &ctxt->output); @@ -254,6 +266,7 @@ napi_value JsKVStoreResultSet::GetEntry(napi_env env, napi_callback_info info) / DistributedKv::Entry entry; auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isSchema = reinterpret_cast(ctxt->native)->isSchema_; auto status = resultSet->GetEntry(entry); if (status != Status::SUCCESS) { @@ -267,7 +280,13 @@ napi_value JsKVStoreResultSet::GetEntry(napi_env env, napi_callback_info info) / std::shared_ptr JsKVStoreResultSet::Create() { - return KvUtils::ToResultSetBridge(GetInstance()); + auto instance = GetInstance(); + if (instance == nullptr) { + ZLOGE("resultSet is null"); + return nullptr; + } + SetInstance(nullptr); + return KvUtils::ToResultSetBridge(instance); } void JsKVStoreResultSet::SetSchema(bool isSchema) diff --git a/kv_store/frameworks/jskitsimpl/distributeddata/src/js_schema.cpp b/kv_store/frameworks/jskitsimpl/distributeddata/src/js_schema.cpp index 1de32338..adb17fa8 100644 --- a/kv_store/frameworks/jskitsimpl/distributeddata/src/js_schema.cpp +++ b/kv_store/frameworks/jskitsimpl/distributeddata/src/js_schema.cpp @@ -213,7 +213,7 @@ napi_value JsSchema::SetIndexes(napi_env env, napi_callback_info info) auto input = [env, ctxt, &indexes](size_t argc, napi_value* argv) { // required 1 arguments :: CHECK_ARGS_RETURN_VOID(ctxt, argc == 1, "invalid arguments!"); - ctxt->status = JSUtil::GetValue(env, argv[0], indexes); + ctxt->status = JSUtil::GetValue(env, argv[0], indexes, false); CHECK_STATUS_RETURN_VOID(ctxt, "invalid arg[0], i.e. invalid indexes!"); }; ctxt->GetCbInfoSync(env, info, input); diff --git a/kv_store/frameworks/jskitsimpl/distributeddata/src/js_util.cpp b/kv_store/frameworks/jskitsimpl/distributeddata/src/js_util.cpp index 2aae9bc3..964a6c38 100644 --- a/kv_store/frameworks/jskitsimpl/distributeddata/src/js_util.cpp +++ b/kv_store/frameworks/jskitsimpl/distributeddata/src/js_util.cpp @@ -135,7 +135,7 @@ napi_status JSUtil::SetValue(napi_env env, const std::string& in, napi_value& ou } /* napi_value <-> std::vector */ -napi_status JSUtil::GetValue(napi_env env, napi_value in, std::vector& out) +napi_status JSUtil::GetValue(napi_env env, napi_value in, std::vector& out, bool checkLength) { ZLOGD("napi_value -> std::vector"); out.clear(); @@ -145,7 +145,10 @@ napi_status JSUtil::GetValue(napi_env env, napi_value in, std::vector 0), "get_array failed!", napi_invalid_arg); + CHECK_RETURN(status == napi_ok, "get_array length failed!", napi_invalid_arg); + if (checkLength) { + CHECK_RETURN(length > 0, "check array length failed!", napi_invalid_arg); + } for (uint32_t i = 0; i < length; ++i) { napi_value item = nullptr; status = napi_get_element(env, in, i, &item); diff --git a/kv_store/frameworks/jskitsimpl/distributedkvstore/include/js_util.h b/kv_store/frameworks/jskitsimpl/distributedkvstore/include/js_util.h index ac2b0a2f..137bc075 100644 --- a/kv_store/frameworks/jskitsimpl/distributedkvstore/include/js_util.h +++ b/kv_store/frameworks/jskitsimpl/distributedkvstore/include/js_util.h @@ -120,7 +120,7 @@ public: static StatusMsg SetValue(napi_env env, const QueryVariant& in, napi_value& out); /* napi_value <-> std::vector */ - static StatusMsg GetValue(napi_env env, napi_value in, std::vector& out); + static StatusMsg GetValue(napi_env env, napi_value in, std::vector& out, bool checkLength = true); static StatusMsg SetValue(napi_env env, const std::vector& in, napi_value& out); /* napi_value <-> std::vector */ 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 8ad2ad98..7507a42c 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 @@ -78,6 +78,7 @@ napi_value JsKVStoreResultSet::GetCount(napi_env env, napi_callback_info info) / ZLOGD("KVStoreResultSet::GetCount(status=%{public}d)", ctxt->status); auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); int count = resultSet->GetCount(); napi_create_int32(env, count, &ctxt->output); @@ -92,6 +93,7 @@ napi_value JsKVStoreResultSet::GetPosition(napi_env env, napi_callback_info info NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); int position = resultSet->GetPosition(); napi_create_int32(env, position, &ctxt->output); @@ -106,6 +108,7 @@ napi_value JsKVStoreResultSet::MoveToFirst(napi_env env, napi_callback_info info NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isMoved = resultSet->MoveToFirst(); napi_get_boolean(env, isMoved, &ctxt->output); @@ -120,6 +123,7 @@ napi_value JsKVStoreResultSet::MoveToLast(napi_env env, napi_callback_info info) NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isMoved = resultSet->MoveToLast(); napi_get_boolean(env, isMoved, &ctxt->output); @@ -134,6 +138,7 @@ napi_value JsKVStoreResultSet::MoveToNext(napi_env env, napi_callback_info info) NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isMoved = resultSet->MoveToNext(); napi_get_boolean(env, isMoved, &ctxt->output); @@ -148,6 +153,7 @@ napi_value JsKVStoreResultSet::MoveToPrevious(napi_env env, napi_callback_info i NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isMoved = resultSet->MoveToPrevious(); napi_get_boolean(env, isMoved, &ctxt->output); @@ -170,6 +176,7 @@ napi_value JsKVStoreResultSet::Move(napi_env env, napi_callback_info info) /* bo ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, "Parameter error:params offset must be number"); auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isMoved = resultSet->Move(offset); napi_get_boolean(env, isMoved, &ctxt->output); @@ -193,6 +200,7 @@ napi_value JsKVStoreResultSet::MoveToPosition(napi_env env, napi_callback_info i ZLOGD("KVStoreResultSet::MoveToPosition(%{public}d)", position); auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isMoved = resultSet->MoveToPosition(position); napi_get_boolean(env, isMoved, &ctxt->output); @@ -207,6 +215,7 @@ napi_value JsKVStoreResultSet::IsFirst(napi_env env, napi_callback_info info) /* NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isFirst = resultSet->IsFirst(); napi_get_boolean(env, isFirst, &ctxt->output); @@ -221,6 +230,7 @@ napi_value JsKVStoreResultSet::IsLast(napi_env env, napi_callback_info info) /* NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isLast = resultSet->IsLast(); napi_get_boolean(env, isLast, &ctxt->output); @@ -235,6 +245,7 @@ napi_value JsKVStoreResultSet::IsBeforeFirst(napi_env env, napi_callback_info in NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isBeforeFirst = resultSet->IsBeforeFirst(); napi_get_boolean(env, isBeforeFirst, &ctxt->output); @@ -249,6 +260,7 @@ napi_value JsKVStoreResultSet::IsAfterLast(napi_env env, napi_callback_info info NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isAfterLast = resultSet->IsAfterLast(); napi_get_boolean(env, isAfterLast, &ctxt->output); @@ -264,6 +276,7 @@ napi_value JsKVStoreResultSet::GetEntry(napi_env env, napi_callback_info info) / DistributedKv::Entry entry; auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isSchema = reinterpret_cast(ctxt->native)->isSchema_; auto status = resultSet->GetEntry(entry); if (status != Status::SUCCESS) { @@ -277,7 +290,13 @@ napi_value JsKVStoreResultSet::GetEntry(napi_env env, napi_callback_info info) / std::shared_ptr JsKVStoreResultSet::Create() { - return KvUtils::ToResultSetBridge(GetInstance()); + auto instance = GetInstance(); + if (instance == nullptr) { + ZLOGE("resultSet is null"); + return nullptr; + } + SetInstance(nullptr); + return KvUtils::ToResultSetBridge(instance); } void JsKVStoreResultSet::SetSchema(bool isSchema) diff --git a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_schema.cpp b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_schema.cpp index 26caf0b1..afa2bd2a 100644 --- a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_schema.cpp +++ b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_schema.cpp @@ -215,7 +215,7 @@ napi_value JsSchema::SetIndexes(napi_env env, napi_callback_info info) auto input = [env, ctxt, &indexes](size_t argc, napi_value* argv) { // required 1 arguments :: ASSERT_ARGS(ctxt, argc == 1, "invalid arguments!"); - ctxt->status = JSUtil::GetValue(env, argv[0], indexes); + ctxt->status = JSUtil::GetValue(env, argv[0], indexes, false); ASSERT_STATUS(ctxt, "invalid arg[0], i.e. invalid indexes!"); }; ctxt->GetCbInfoSync(env, info, input); diff --git a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_util.cpp b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_util.cpp index 3bec6fa9..ee6ea4dd 100644 --- a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_util.cpp +++ b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_util.cpp @@ -153,7 +153,7 @@ JSUtil::StatusMsg JSUtil::SetValue(napi_env env, const std::string& in, napi_val } /* napi_value <-> std::vector */ -JSUtil::StatusMsg JSUtil::GetValue(napi_env env, napi_value in, std::vector& out) +JSUtil::StatusMsg JSUtil::GetValue(napi_env env, napi_value in, std::vector& out, bool checkLength) { ZLOGD("napi_value -> std::vector"); out.clear(); @@ -163,7 +163,10 @@ JSUtil::StatusMsg JSUtil::GetValue(napi_env env, napi_value in, std::vector 0), "get_array failed!", napi_invalid_arg); + ASSERT(statusMsg.status == napi_ok, "get_array length failed!", napi_invalid_arg); + if (checkLength) { + ASSERT(length > 0, "check array length failed!", napi_invalid_arg); + } for (uint32_t i = 0; i < length; ++i) { napi_value item = nullptr; statusMsg.status = napi_get_element(env, in, i, &item); diff --git a/kv_store/frameworks/libs/distributeddb/BUILD.gn b/kv_store/frameworks/libs/distributeddb/BUILD.gn index 6afb1710..b619cf6a 100644 --- a/kv_store/frameworks/libs/distributeddb/BUILD.gn +++ b/kv_store/frameworks/libs/distributeddb/BUILD.gn @@ -63,7 +63,6 @@ config("distrdb_config") { "USE_DFX_ABILITY", "SQLITE_ENABLE_DROPTABLE_CALLBACK", "OPENSSL_SUPPRESS_DEPRECATED", - "MAX_UPLOAD_COUNT=30", ] if (is_debug) { defines += [ "TRACE_SQLITE_EXECUTE" ] @@ -93,28 +92,19 @@ group("build_module") { ohos_shared_library("distributeddb") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false - blocklist = "./cfi_blocklist.txt" } sources = distributeddb_src configs = [ ":distrdb_config" ] public_configs = [ ":distrdb_public_config" ] - deps = [ - "//third_party/sqlite:sqlite", - "//third_party/zlib:shared_libz", - ] - - configs += [ "//third_party/jsoncpp:jsoncpp_config" ] cflags_cc = [ "-fvisibility=hidden" ] - deps += [ - "gaussdb_rd:gaussdb_rd", - "//third_party/jsoncpp:jsoncpp", - "//third_party/openssl:libcrypto_shared", - ] + deps = [ "gaussdb_rd:gaussdb_rd" ] external_deps = [ "c_utils:utils", @@ -124,6 +114,13 @@ ohos_shared_library("distributeddb") { "hitrace:hitrace_meter", ] + public_external_deps = [ + "jsoncpp:jsoncpp", + "openssl:libcrypto_shared", + "sqlite:sqlite", + "zlib:shared_libz", + ] + subsystem_name = "distributeddatamgr" innerapi_tags = [ "platformsdk_indirect" ] part_name = "kv_store" 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 4992d04d..28a0cab0 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/auto_launch.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/auto_launch.h @@ -28,6 +28,7 @@ #include "types_export.h" #include "relational_store_connection.h" #include "relationaldb_properties.h" +#include "semaphore_utils.h" #include "store_observer.h" namespace DistributedDB { @@ -133,6 +134,9 @@ protected: void GetDoOpenMap(std::map> &doOpenMap); + void GetConnInDoOpenMapInner(std::pair> &items, + SemaphoreUtils &sema); + void GetConnInDoOpenMap(std::map> &doOpenMap); void UpdateGlobalMap(std::map> &doOpenMap); diff --git a/kv_store/frameworks/libs/distributeddb/common/include/cloud/asset_operation_utils.h b/kv_store/frameworks/libs/distributeddb/common/include/cloud/asset_operation_utils.h index a6bde9e1..7a11c7f5 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/cloud/asset_operation_utils.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/cloud/asset_operation_utils.h @@ -49,8 +49,8 @@ private: static AssetOperationUtils::AssetOpType CheckAfterUpload(const Asset &cacheAsset, const Assets &dbAssets); static AssetOperationUtils::AssetOpType HandleIfExistAndSameStatus(const Asset &cacheAsset, const Assets &dbAssets); static Assets GetAssets(const std::string &colName, const VBucket &rowData); - static void MergeAssetsFlag(const Assets &from, Type &target); static void MergeAssetFlag(const Assets &from, Asset &target); + static void MergeAssetsFlag(const Assets &from, Type &target); static constexpr uint32_t BIT_MASK_COUNT = 16; }; } 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 470357f0..e8451ca4 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 @@ -71,11 +71,16 @@ public: static constexpr const char *CLOUD_VERSION_RECORD_PREFIX_KEY = "naturalbase_cloud_version_"; - 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; + + static constexpr int32_t MAX_UPLOAD_BATCH_COUNT = 2000; + static constexpr int32_t MIN_UPLOAD_BATCH_COUNT = 1; + static constexpr int32_t MAX_UPLOAD_SIZE = 128 * 1024 * 1024; // 128M + static constexpr int32_t MIN_UPLOAD_SIZE = 1024; // 1024Bytes + static constexpr int32_t MIN_RETRY_CONFLICT_COUNTS = -1; // unlimited }; } // namespace DistributedDB #endif // CLOUD_DB_CONSTANT_H \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/common/include/cloud/cloud_db_types.h b/kv_store/frameworks/libs/distributeddb/common/include/cloud/cloud_db_types.h index c4420d32..c31de2e2 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/cloud/cloud_db_types.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/cloud/cloud_db_types.h @@ -45,8 +45,8 @@ struct CloudSyncData { bool isCompensatedTask = false; bool isShared = false; int ignoredCount = 0; - CloudWaterType mode; bool isCloudVersionRecord = false; + CloudWaterType mode; CloudSyncData() = default; CloudSyncData(const std::string &_tableName) : tableName(_tableName) {}; CloudSyncData(const std::string &_tableName, CloudWaterType _mode) : tableName(_tableName), mode(_mode) {}; diff --git a/kv_store/frameworks/libs/distributeddb/common/include/db_base64_utils.h b/kv_store/frameworks/libs/distributeddb/common/include/db_base64_utils.h new file mode 100644 index 00000000..07462fb7 --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/common/include/db_base64_utils.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DB_BASE64_UTILS_H +#define DB_BASE64_UTILS_H + +#include +#include + +namespace DistributedDB { +class DBBase64Utils { +public: + static std::string Encode(const std::vector &source); + static std::vector Decode(const std::string &encoded); +}; +} +#endif // DB_BASE64_UTILS_H 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 6be05fec..b1135a2d 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/db_common.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/db_common.h @@ -19,6 +19,7 @@ #include #include +#include "cloud/cloud_db_types.h" #include "db_types.h" #include "kvdb_properties.h" #include "store_types.h" @@ -36,6 +37,11 @@ public: return DBConstant::RELATIONAL_PREFIX + tableName + DBConstant::LOG_POSTFIX; } + static inline const std::vector GetWaterTypeVec() + { + return {CloudWaterType::DELETE, CloudWaterType::UPDATE, CloudWaterType::INSERT}; + } + static std::string VectorToHexString(const std::vector &inVec, const std::string &separator = ""); static void PrintHexVector(const std::vector &data, int line = 0, const std::string &tag = ""); @@ -54,12 +60,11 @@ public: static int RemoveAllFilesOfDirectory(const std::string &dir, bool isNeedRemoveDir = true); static std::string GenerateIdentifierId(const std::string &storeId, - const std::string &appId, const std::string &userId, int32_t instanceId = 0); + const std::string &appId, const std::string &userId, const std::string &subUser = "", int32_t instanceId = 0); static std::string GenerateDualTupleIdentifierId(const std::string &storeId, const std::string &appId); - static void SetDatabaseIds(KvDBProperties &properties, const std::string &appId, const std::string &userId, - const std::string &storeId, int32_t instanceId = 0); + static void SetDatabaseIds(KvDBProperties &properties, const DbIdParam &dbIdParam); static std::string StringMasking(const std::string &oriStr, size_t remain = 3); // remain 3 unmask @@ -111,13 +116,13 @@ public: static bool IsRecordVersionConflict(const VBucket &record); + static bool IsRecordDelete(const VBucket &record); + static std::string GenerateHashLabel(const DBInfo &dbInfo); static uint64_t EraseBit(uint64_t origin, uint64_t eraseBit); - static void LoadGrdLib(bool isHash = false); - - static bool IsGrdLibLoaded(void); + static bool CheckCloudSyncConfigValid(const CloudSyncConfig &config); 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 10a70400..d1b4e80e 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/db_constant.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/db_constant.h @@ -60,6 +60,7 @@ public: static constexpr uint64_t MAX_USER_ID_LENGTH = 128; static constexpr uint64_t MAX_APP_ID_LENGTH = 128; static constexpr uint64_t MAX_STORE_ID_LENGTH = 128; + static constexpr uint64_t MAX_SUB_USER_LENGTH = 128; static const std::string MULTI_SUB_DIR; static const std::string SINGLE_SUB_DIR; @@ -169,6 +170,7 @@ public: static constexpr const char *LOG_TABLE_VERSION_5_4 = "5.04"; // new flag bit 0x20 added, upgrade trigger static constexpr const char *LOG_TABLE_VERSION_5_5 = "5.05"; // add status field static constexpr const char *LOG_TABLE_VERSION_5_6 = "5.06"; // upgrade trigger for simple tracker log table + static constexpr const char *LOG_TABLE_VERSION_5_7 = "5.07"; // trigger slow sql optimization static const std::string LOG_TABLE_VERSION_CURRENT; static const std::string LOG_TABLE_VERSION_KEY; @@ -192,6 +194,8 @@ public: static constexpr const char *LOCALTIME_OFFSET_KEY = "localTimeOffset"; static constexpr uint64_t OBSERVER_CHANGES_MASK = 0XF00; + + static constexpr const char *STORAGE_TYPE_LONG = "long"; }; } // 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 ef8ab5e9..faf4b67f 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 @@ -26,18 +26,54 @@ enum DBEventType { SECURITY = 3, BEHAVIOR = 4 }; + +enum class Scene { + OPEN_CONN = 1, + SEND_RECV_DATA, + CLOUD_SYNC, + DATA_ACCESS, + SEARCH_DATA, + DEVICE_SYNC +}; + +enum class State { + BEGIN = 0, + END +}; + +enum class Stage { + GET_DB = 0, + CHECK_OPT, + GET_DB_CONN, + CLOUD_SYNC, + CLOUD_DOWNLOAD, + CLOUD_UPLOAD, + CLOUD_NOTIFY, + DEVICE_SYNC, +}; + +enum class StageResult { + IDLE = 0, + SUCC, + FAIL, + CANCLE, + UNKNOWN +}; + struct ReportTask { - std::string eventName; - std::string appId; - std::string userId; - std::string storeId; + std::string funcName; + Scene scene; + State state; + Stage stage; + StageResult result; int errCode = 0; }; + class DBDfxAdapter final { public: static void Dump(int fd, const std::vector &args); - static void ReportFault(const ReportTask &reportTask); + static void ReportBehavior(const ReportTask &reportTask); static void StartTrace(const std::string &action); static void FinishTrace(); @@ -51,11 +87,18 @@ public: static const std::string SYNC_ACTION; static const std::string EVENT_OPEN_DATABASE_FAILED; private: - static const std::string EVENT_CODE; - static const std::string APP_ID; - static const std::string USER_ID; - static const std::string STORE_ID; + static const std::string ORG_PKG; + static const std::string FUNC; + static const std::string BIZ_SCENE; + static const std::string BIZ_STATE; + static const std::string BIZ_STAGE; + static const std::string STAGE_RES; + static const std::string ERROR_CODE; + static const std::string DISTRIBUTED_DB_BEHAVIOR; + static const std::string ORG_PKG_NAME; static const std::string SQLITE_EXECUTE; + + static constexpr int E_DB_DFX_BASE = 27328512; }; } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/common/include/param_check_utils.h b/kv_store/frameworks/libs/distributeddb/common/include/param_check_utils.h index a0f5897f..39a355f4 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/param_check_utils.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/param_check_utils.h @@ -31,9 +31,9 @@ public: // Check if the storeID is a safe arg. static bool IsStoreIdSafe(const std::string &storeId); - // check appId, userId, storeId. + // check appId, userId, storeId, subUser. static bool CheckStoreParameter(const std::string &storeId, const std::string &appId, const std::string &userId, - bool isIgnoreUserIdCheck = false); + bool isIgnoreUserIdCheck = false, const std::string &subUser = ""); // check encrypted args for KvStore. static bool CheckEncryptedParameter(CipherType cipher, const CipherPassword &passwd); diff --git a/kv_store/frameworks/libs/distributeddb/common/include/query_utils.h b/kv_store/frameworks/libs/distributeddb/common/include/query_utils.h new file mode 100644 index 00000000..3e6d53be --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/common/include/query_utils.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef QUERY_UTILS_H +#define QUERY_UTILS_H + +#include "cloud/cloud_db_types.h" +#include "query.h" + +namespace DistributedDB { +class QueryUtils { +public: + static void FillQueryInKeys(const std::string &col, const std::vector &data, size_t valueType, Query &query); +}; +} // DistributedDB +#endif // QUERY_UTILS_H diff --git a/kv_store/frameworks/libs/distributeddb/common/include/runtime_context.h b/kv_store/frameworks/libs/distributeddb/common/include/runtime_context.h index 217549f9..e67596c2 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/runtime_context.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/runtime_context.h @@ -197,6 +197,8 @@ public: virtual void ResetDBTimeChangeStatus(const std::vector &dbId) = 0; virtual bool CheckDBTimeChange(const std::vector &dbId) = 0; virtual bool IsTimeTickMonitorValid() const = 0; + virtual bool IsTimeChanged() const = 0; + virtual void SetTimeChanged(bool timeChange) = 0; protected: RuntimeContext() = default; virtual ~RuntimeContext() {} diff --git a/kv_store/frameworks/libs/distributeddb/common/src/auto_launch.cpp b/kv_store/frameworks/libs/distributeddb/common/src/auto_launch.cpp index 6d74e779..4ef74be5 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/auto_launch.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/auto_launch.cpp @@ -16,6 +16,7 @@ #include "auto_launch.h" #include "cloud/cloud_db_constant.h" +#include "concurrent_adapter.h" #include "db_common.h" #include "db_dump_helper.h" #include "db_dfx_adapter.h" @@ -31,7 +32,6 @@ #include "runtime_context.h" #include "semaphore_utils.h" #include "sync_able_kvdb_connection.h" -#include "concurrent_adapter.h" namespace DistributedDB { namespace { @@ -523,12 +523,6 @@ int AutoLaunch::OpenOneConnection(AutoLaunchItem &autoLaunchItem) default: errCode = -E_INVALID_ARGS; } - if (errCode == -E_INVALID_PASSWD_OR_CORRUPTED_DB) { - std::string userId = autoLaunchItem.propertiesPtr->GetStringProp(DBProperties::USER_ID, ""); - std::string appId = autoLaunchItem.propertiesPtr->GetStringProp(DBProperties::APP_ID, ""); - std::string storeId = autoLaunchItem.propertiesPtr->GetStringProp(DBProperties::STORE_ID, ""); - DBDfxAdapter::ReportFault( { DBDfxAdapter::EVENT_OPEN_DATABASE_FAILED, userId, appId, storeId, errCode } ); - } return errCode; } @@ -591,41 +585,47 @@ void AutoLaunch::GetDoOpenMap(std::map> &items, + SemaphoreUtils &sema) +{ + for (auto &iter : items.second) { + int errCode = RuntimeContext::GetInstance()->ScheduleTask([&sema, &iter, &items, this] { + int ret = OpenOneConnection(iter.second); + LOGI("[AutoLaunch] GetConnInDoOpenMap GetOneConnection errCode:%d", ret); + if (iter.second.conn == nullptr) { + sema.SendSemaphore(); + LOGI("[AutoLaunch] GetConnInDoOpenMap in open thread finish SendSemaphore"); + return; + } + ret = RegisterObserverAndLifeCycleCallback(iter.second, items.first, false); + if (ret != E_OK) { + LOGE("[AutoLaunch] GetConnInDoOpenMap failed, we do CloseConnection"); + TryCloseConnection(iter.second); // if here failed, do nothing + iter.second.conn = nullptr; + } + sema.SendSemaphore(); + LOGI("[AutoLaunch] GetConnInDoOpenMap in open thread finish SendSemaphore"); + }); + if (errCode != E_OK) { + LOGE("[AutoLaunch] GetConnInDoOpenMap ScheduleTask failed, SendSemaphore"); + sema.SendSemaphore(); + } + } +} + void AutoLaunch::GetConnInDoOpenMap(std::map> &doOpenMap) { LOGI("[AutoLaunch] GetConnInDoOpenMap doOpenMap.size():%zu", doOpenMap.size()); if (doOpenMap.empty()) { return; } - uint32_t totalSize = 0; + uint32_t totalSize = 0u; for (auto &items : doOpenMap) { totalSize += items.second.size(); } SemaphoreUtils sema(1 - totalSize); for (auto &items : doOpenMap) { - for (auto &iter : items.second) { - int errCode = RuntimeContext::GetInstance()->ScheduleTask([&sema, &iter, &items, this] { - int ret = OpenOneConnection(iter.second); - LOGI("[AutoLaunch] GetConnInDoOpenMap GetOneConnection errCode:%d", ret); - if (iter.second.conn == nullptr) { - sema.SendSemaphore(); - LOGI("[AutoLaunch] GetConnInDoOpenMap in open thread finish SendSemaphore"); - return; - } - ret = RegisterObserverAndLifeCycleCallback(iter.second, items.first, false); - if (ret != E_OK) { - LOGE("[AutoLaunch] GetConnInDoOpenMap failed, we do CloseConnection"); - TryCloseConnection(iter.second); // if here failed, do nothing - iter.second.conn = nullptr; - } - sema.SendSemaphore(); - LOGI("[AutoLaunch] GetConnInDoOpenMap in open thread finish SendSemaphore"); - }); - if (errCode != E_OK) { - LOGE("[AutoLaunch] GetConnInDoOpenMap ScheduleTask failed, SendSemaphore"); - sema.SendSemaphore(); - } - } + GetConnInDoOpenMapInner(items, sema); } LOGI("[AutoLaunch] GetConnInDoOpenMap WaitSemaphore"); sema.WaitSemaphore(); @@ -810,7 +810,7 @@ void AutoLaunch::AutoLaunchExtTask(const std::string &identifier, const std::str TaskHandle handle = ConcurrentAdapter::ScheduleTaskH([this, &identifier, &userId] () mutable { ADAPTER_AUTO_LOCK(autoLock, extLock_); extItemMap_[identifier].erase(userId); - if (extItemMap_[identifier].size() == 0) { + if (extItemMap_[identifier].empty()) { extItemMap_.erase(identifier); } }, nullptr, &extItemMap_); @@ -904,7 +904,7 @@ void AutoLaunch::ExtConnectionLifeCycleCallbackTask(const std::string &identifie } autoLaunchItem = extItemMap_[identifier][userId]; extItemMap_[identifier].erase(userId); - if (extItemMap_[identifier].size() == 0) { + if (extItemMap_[identifier].empty()) { extItemMap_.erase(identifier); } }, nullptr, &extItemMap_); @@ -1025,7 +1025,8 @@ int AutoLaunch::GetAutoLaunchKVProperties(const AutoLaunchParam ¶m, propertiesPtr->SetBoolProp(KvDBProperties::SYNC_DUAL_TUPLE_MODE, param.option.syncDualTupleMode); propertiesPtr->SetBoolProp(KvDBProperties::READ_ONLY_MODE, false); propertiesPtr->SetBoolProp(KvDBProperties::SHARED_MODE, false); - DBCommon::SetDatabaseIds(*propertiesPtr, param.appId, param.userId, param.storeId); + DbIdParam dbIdParam = { param.appId, param.userId, param.storeId }; + DBCommon::SetDatabaseIds(*propertiesPtr, dbIdParam); return E_OK; } diff --git a/kv_store/frameworks/libs/distributeddb/common/src/cloud/asset_operation_utils.cpp b/kv_store/frameworks/libs/distributeddb/common/src/cloud/asset_operation_utils.cpp index 97f8b819..d5558a33 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/cloud/asset_operation_utils.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/cloud/asset_operation_utils.cpp @@ -23,13 +23,13 @@ using CloudSyncAction = AssetOperationUtils::CloudSyncAction; namespace { std::once_flag g_init; using Reaction = std::function; -std::map g_reactions; +std::map reactions; Reaction GetReaction(const CloudSyncAction &action) { - if (g_reactions.find(action) != g_reactions.end()) { - return g_reactions[action]; + if (reactions.find(action) != reactions.end()) { + return reactions[action]; } else { - return g_reactions[CloudSyncAction::DEFAULT_ACTION]; + return reactions[CloudSyncAction::DEFAULT_ACTION]; } } } @@ -122,11 +122,11 @@ void AssetOperationUtils::FilterDeleteAsset(VBucket &record) void AssetOperationUtils::Init() { - g_reactions[CloudSyncAction::DEFAULT_ACTION] = DefaultOperation; - g_reactions[CloudSyncAction::START_DOWNLOAD] = CheckBeforeDownload; - g_reactions[CloudSyncAction::START_UPLOAD] = HandleIfExistAndSameStatus; - g_reactions[CloudSyncAction::END_DOWNLOAD] = CheckAfterDownload; - g_reactions[CloudSyncAction::END_UPLOAD] = CheckAfterUpload; + reactions[CloudSyncAction::DEFAULT_ACTION] = DefaultOperation; + reactions[CloudSyncAction::START_DOWNLOAD] = CheckBeforeDownload; + reactions[CloudSyncAction::START_UPLOAD] = HandleIfExistAndSameStatus; + reactions[CloudSyncAction::END_DOWNLOAD] = CheckAfterDownload; + reactions[CloudSyncAction::END_UPLOAD] = CheckAfterUpload; } AssetOperationUtils::AssetOpType AssetOperationUtils::DefaultOperation(const Asset &, const Assets &) @@ -217,6 +217,15 @@ AssetOperationUtils::AssetOpType AssetOperationUtils::HandleIfExistAndSameStatus return AssetOpType::NOT_HANDLE; } +void AssetOperationUtils::MergeAssetFlag(const Assets &from, Asset &target) +{ + for (const auto &fromAsset : from) { + if (fromAsset.name == target.name) { + target.flag = fromAsset.flag; + } + } +} + void AssetOperationUtils::MergeAssetsFlag(const Assets &from, Type &target) { if (TYPE_INDEX == target.index()) { @@ -227,13 +236,4 @@ void AssetOperationUtils::MergeAssetsFlag(const Assets &from, Type &target) } } } - -void AssetOperationUtils::MergeAssetFlag(const Assets &from, Asset &target) -{ - for (const auto &fromAsset : from) { - if (fromAsset.name == target.name) { - target.flag = fromAsset.flag; - } - } -} } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/common/src/db_base64_utils.cpp b/kv_store/frameworks/libs/distributeddb/common/src/db_base64_utils.cpp new file mode 100644 index 00000000..5cd543b1 --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/common/src/db_base64_utils.cpp @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "db_base64_utils.h" + +#include +#include + +namespace DistributedDB { +static constexpr const std::string_view BASE64_CHARS = /* NOLINT */ + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + +static constexpr const uint32_t CHAR_ARRAY_LENGTH_THREE = 3; +static constexpr const uint32_t CHAR_ARRAY_LENGTH_FOUR = 4; + +enum BASE64_ENCODE_CONSTANT : uint8_t { + BASE64_ENCODE_MASK1 = 0xfc, + BASE64_ENCODE_MASK2 = 0x03, + BASE64_ENCODE_MASK3 = 0x0f, + BASE64_ENCODE_MASK4 = 0x3f, + BASE64_ENCODE_MASK5 = 0xf0, + BASE64_ENCODE_MASK6 = 0xc0, + BASE64_ENCODE_OFFSET2 = 2, + BASE64_ENCODE_OFFSET4 = 4, + BASE64_ENCODE_OFFSET6 = 6, + BASE64_ENCODE_INDEX0 = 0, + BASE64_ENCODE_INDEX1 = 1, + BASE64_ENCODE_INDEX2 = 2, +}; + +enum BASE64_DECODE_CONSTANT : uint8_t { + BASE64_DECODE_MASK1 = 0x30, + BASE64_DECODE_MASK2 = 0xf, + BASE64_DECODE_MASK3 = 0x3c, + BASE64_DECODE_MASK4 = 0x3, + BASE64_DECODE_OFFSET2 = 2, + BASE64_DECODE_OFFSET4 = 4, + BASE64_DECODE_OFFSET6 = 6, + BASE64_DECODE_INDEX0 = 0, + BASE64_DECODE_INDEX1 = 1, + BASE64_DECODE_INDEX2 = 2, + BASE64_DECODE_INDEX3 = 3, +}; + +static inline bool IsBase64Char(const char c) +{ + return (isalnum(c) || (c == '+') || (c == '/')); +} + +static void MakeCharFour(const std::array &charArrayThree, + std::array &charArrayFour) +{ + const uint8_t table[CHAR_ARRAY_LENGTH_FOUR] = { + static_cast((charArrayThree[BASE64_ENCODE_INDEX0] & BASE64_ENCODE_MASK1) >> BASE64_ENCODE_OFFSET2), + static_cast(((charArrayThree[BASE64_ENCODE_INDEX0] & BASE64_ENCODE_MASK2) << BASE64_ENCODE_OFFSET4) + + ((charArrayThree[BASE64_ENCODE_INDEX1] & BASE64_ENCODE_MASK5) >> BASE64_ENCODE_OFFSET4)), + static_cast(((charArrayThree[BASE64_ENCODE_INDEX1] & BASE64_ENCODE_MASK3) << BASE64_ENCODE_OFFSET2) + + ((charArrayThree[BASE64_ENCODE_INDEX2] & BASE64_ENCODE_MASK6) >> BASE64_ENCODE_OFFSET6)), + static_cast(charArrayThree[BASE64_ENCODE_INDEX2] & BASE64_ENCODE_MASK4), + }; + for (size_t index = 0; index < CHAR_ARRAY_LENGTH_FOUR; ++index) { + charArrayFour[index] = table[index]; + } +} + +static void MakeCharTree(const std::array &charArrayFour, + std::array &charArrayThree) +{ + const uint8_t table[CHAR_ARRAY_LENGTH_THREE] = { + static_cast((charArrayFour[BASE64_DECODE_INDEX0] << BASE64_DECODE_OFFSET2) + + ((charArrayFour[BASE64_DECODE_INDEX1] & BASE64_DECODE_MASK1) >> BASE64_DECODE_OFFSET4)), + static_cast(((charArrayFour[BASE64_DECODE_INDEX1] & BASE64_DECODE_MASK2) << BASE64_DECODE_OFFSET4) + + ((charArrayFour[BASE64_DECODE_INDEX2] & BASE64_DECODE_MASK3) >> BASE64_DECODE_OFFSET2)), + static_cast(((charArrayFour[BASE64_DECODE_INDEX2] & BASE64_DECODE_MASK4) << BASE64_DECODE_OFFSET6) + + charArrayFour[BASE64_DECODE_INDEX3]), + }; + for (size_t index = 0; index < CHAR_ARRAY_LENGTH_THREE; ++index) { + charArrayThree[index] = table[index]; + } +} + +std::string DBBase64Utils::Encode(const std::vector &source) +{ + auto it = source.begin(); + std::string ret; + size_t index = 0; + std::array charArrayThree = { 0 }; + std::array charArrayFour = { 0 }; + + while (it != source.end()) { + charArrayThree[index] = *it; + ++index; + ++it; + if (index != CHAR_ARRAY_LENGTH_THREE) { + continue; + } + MakeCharFour(charArrayThree, charArrayFour); + std::for_each(charArrayFour.begin(), charArrayFour.end(), [&ret](uint8_t idx) { + ret += BASE64_CHARS[idx]; + }); + index = 0; + } + if (index == 0) { + return ret; + } + + for (auto i = index; i < CHAR_ARRAY_LENGTH_THREE; ++i) { + charArrayThree[i] = 0; + } + MakeCharFour(charArrayThree, charArrayFour); + + for (size_t i = 0; i < index + 1; ++i) { + ret += BASE64_CHARS[charArrayFour[i]]; + } + + while (index < CHAR_ARRAY_LENGTH_THREE) { + ret += '='; + ++index; + } + return ret; +} + +std::vector DBBase64Utils::Decode(const std::string &encoded) +{ + auto it = encoded.begin(); + size_t index = 0; + std::array charArrayThree = { 0 }; + std::array charArrayFour = { 0 }; + std::vector ret; + + while (it != encoded.end() && IsBase64Char(*it)) { + charArrayFour[index] = *it; + ++index; + ++it; + if (index != CHAR_ARRAY_LENGTH_FOUR) { + continue; + } + for (index = 0; index < CHAR_ARRAY_LENGTH_FOUR; ++index) { + charArrayFour[index] = BASE64_CHARS.find(static_cast(charArrayFour[index])); + } + MakeCharTree(charArrayFour, charArrayThree); + std::for_each(charArrayThree.begin(), charArrayThree.end(), [&ret](uint8_t idx) { + ret.emplace_back(idx); + }); + index = 0; + } + if (index == 0) { + return ret; + } + + for (auto i = index; i < CHAR_ARRAY_LENGTH_FOUR; ++i) { + charArrayFour[i] = 0; + } + for (unsigned char &i : charArrayFour) { + std::string::size_type idx = BASE64_CHARS.find(static_cast(i)); + if (idx != std::string::npos) { + i = static_cast(idx); + } + } + MakeCharTree(charArrayFour, charArrayThree); + + for (size_t i = 0; i < index - 1; i++) { + ret.emplace_back(charArrayThree[i]); + } + return ret; +} +} \ No newline at end of file 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 1de6c07a..47f3cf66 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/db_common.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/db_common.cpp @@ -285,12 +285,15 @@ int DBCommon::RemoveAllFilesOfDirectory(const std::string &dir, bool isNeedRemov } std::string DBCommon::GenerateIdentifierId(const std::string &storeId, - const std::string &appId, const std::string &userId, int32_t instanceId) + const std::string &appId, const std::string &userId, const std::string &subUser, int32_t instanceId) { std::string id = userId + "-" + appId + "-" + storeId; if (instanceId != 0) { id += "-" + std::to_string(instanceId); } + if (!subUser.empty()) { + id += "-" + subUser; + } return id; } @@ -299,15 +302,15 @@ std::string DBCommon::GenerateDualTupleIdentifierId(const std::string &storeId, return appId + "-" + storeId; } -void DBCommon::SetDatabaseIds(KvDBProperties &properties, const std::string &appId, const std::string &userId, - const std::string &storeId, int32_t instanceId) +void DBCommon::SetDatabaseIds(KvDBProperties &properties, const DbIdParam &dbIdParam) { - properties.SetIdentifier(userId, appId, storeId, instanceId); + properties.SetIdentifier(dbIdParam.userId, dbIdParam.appId, dbIdParam.storeId, + dbIdParam.subUser, dbIdParam.instanceId); std::string oriStoreDir; - // IDENTIFIER_DIR no need cal with instanceId - std::string identifier = GenerateIdentifierId(storeId, appId, userId); + // IDENTIFIER_DIR no need cal with instanceId and subUser + std::string identifier = GenerateIdentifierId(dbIdParam.storeId, dbIdParam.appId, dbIdParam.userId); if (properties.GetBoolProp(KvDBProperties::CREATE_DIR_BY_STORE_ID_ONLY, false)) { - oriStoreDir = storeId; + oriStoreDir = dbIdParam.storeId; } else { oriStoreDir = identifier; } @@ -633,6 +636,17 @@ bool DBCommon::IsRecordVersionConflict(const VBucket &record) return status == static_cast(DBStatus::CLOUD_VERSION_CONFLICT); } +bool DBCommon::IsRecordDelete(const VBucket &record) +{ + if (record.find(CloudDbConstant::DELETE_FIELD) == record.end()) { + return false; + } + if (record.at(CloudDbConstant::DELETE_FIELD).index() != TYPE_INDEX) { + return false; + } + return std::get(record.at(CloudDbConstant::DELETE_FIELD)); +} + std::string DBCommon::GenerateHashLabel(const DBInfo &dbInfo) { if (dbInfo.syncDualTupleMode) { @@ -645,4 +659,23 @@ uint64_t DBCommon::EraseBit(uint64_t origin, uint64_t eraseBit) { return origin & (~eraseBit); } + +bool DBCommon::CheckCloudSyncConfigValid(const CloudSyncConfig &config) +{ + if (config.maxUploadCount < CloudDbConstant::MIN_UPLOAD_BATCH_COUNT || + config.maxUploadCount > CloudDbConstant::MAX_UPLOAD_BATCH_COUNT) { + LOGE("[DBCommon] invalid upload count %" PRId32, config.maxUploadCount); + return false; + } + if (config.maxUploadSize < CloudDbConstant::MIN_UPLOAD_SIZE || + config.maxUploadSize > CloudDbConstant::MAX_UPLOAD_SIZE) { + LOGE("[DBCommon] invalid upload size %" PRId32, config.maxUploadSize); + return false; + } + if (config.maxRetryConflictTimes < CloudDbConstant::MIN_RETRY_CONFLICT_COUNTS) { + LOGE("[DBCommon] invalid retry conflict count %" PRId32, config.maxRetryConflictTimes); + return false; + } + return true; +} } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/common/src/db_constant.cpp b/kv_store/frameworks/libs/distributeddb/common/src/db_constant.cpp index 84c17404..fbf407ce 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/db_constant.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/db_constant.cpp @@ -42,7 +42,7 @@ const std::string DBConstant::RELATIONAL_SCHEMA_KEY = "relational_schema"; const std::string DBConstant::RELATIONAL_TRACKER_SCHEMA_KEY = "relational_tracker_schema"; const std::string DBConstant::RD_KV_COLLECTION_MODE = "{\"mode\" : \"kv\"}"; -const std::string DBConstant::RD_KV_HASH_COLLECTION_MODE = "{\"mode\" : \"kv\", \"indextype\" : \"hash\"}"; +const std::string DBConstant::RD_KV_HASH_COLLECTION_MODE = "{\"mode\" : \"kv\",\"indextype\" : \"hash\"}"; const std::string DBConstant::PATH_POSTFIX_UNPACKED = "_unpacked"; const std::string DBConstant::PATH_POSTFIX_IMPORT_BACKUP = "_import_bak"; @@ -76,7 +76,7 @@ const std::string DBConstant::LOG_POSTFIX = "_log"; const std::string DBConstant::LOG_TABLE_VERSION_1 = "1.0"; const std::string DBConstant::LOG_TABLE_VERSION_2 = "2.0"; -const std::string DBConstant::LOG_TABLE_VERSION_CURRENT = LOG_TABLE_VERSION_5_6; +const std::string DBConstant::LOG_TABLE_VERSION_CURRENT = LOG_TABLE_VERSION_5_7; const std::string DBConstant::LOG_TABLE_VERSION_KEY = "log_table_version"; 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 a954aa12..2e62ba47 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 @@ -40,10 +40,15 @@ constexpr const char *DUMP_LONG_PARAM = "--database"; constexpr const char *DUMP_SHORT_PARAM = "-d"; } -const std::string DBDfxAdapter::EVENT_CODE = "ERROR_CODE"; -const std::string DBDfxAdapter::APP_ID = "APP_ID"; -const std::string DBDfxAdapter::USER_ID = "USER_ID"; -const std::string DBDfxAdapter::STORE_ID = "STORE_ID"; +const std::string DBDfxAdapter::ORG_PKG = "ORG_PKG"; +const std::string DBDfxAdapter::FUNC = "FUNC"; +const std::string DBDfxAdapter::BIZ_SCENE = "BIZ_SCENE"; +const std::string DBDfxAdapter::BIZ_STATE = "BIZ_STATE"; +const std::string DBDfxAdapter::BIZ_STAGE = "BIZ_STAGE"; +const std::string DBDfxAdapter::STAGE_RES = "STAGE_RES"; +const std::string DBDfxAdapter::ERROR_CODE = "ERROR_CODE"; +const std::string DBDfxAdapter::ORG_PKG_NAME = "distributeddata"; +const std::string DBDfxAdapter::DISTRIBUTED_DB_BEHAVIOR = "DISTRIBUTED_DB_BEHAVIOR"; const std::string DBDfxAdapter::SQLITE_EXECUTE = "SQLITE_EXECUTE"; const std::string DBDfxAdapter::SYNC_ACTION = "SYNC_ACTION"; const std::string DBDfxAdapter::EVENT_OPEN_DATABASE_FAILED = "OPEN_DATABASE_FAILED"; @@ -72,16 +77,21 @@ void DBDfxAdapter::Dump(int fd, const std::vector &args) } #ifdef USE_DFX_ABILITY -void DBDfxAdapter::ReportFault(const ReportTask &reportTask) +void DBDfxAdapter::ReportBehavior(const ReportTask &reportTask) { + int dbDfxErrCode = -(reportTask.errCode - E_BASE) + E_DB_DFX_BASE; RuntimeContext::GetInstance()->ScheduleTask([=]() { // call hievent here HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::DISTRIBUTED_DATAMGR, - reportTask.eventName, - OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, - APP_ID, reportTask.appId, - STORE_ID, reportTask.storeId, - EVENT_CODE, std::to_string(reportTask.errCode)); + DISTRIBUTED_DB_BEHAVIOR, + OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR, + ORG_PKG, ORG_PKG_NAME, + FUNC, reportTask.funcName, + BIZ_SCENE, static_cast(reportTask.scene), + BIZ_STATE, static_cast(reportTask.state), + BIZ_STAGE, static_cast(reportTask.stage), + STAGE_RES, static_cast(reportTask.result), + ERROR_CODE, dbDfxErrCode); }); } @@ -123,7 +133,7 @@ void DBDfxAdapter::FinishAsyncTrace(const std::string &action, int32_t taskId) } #else -void DBDfxAdapter::ReportFault(const ReportTask &reportTask) +void DBDfxAdapter::ReportBehavior(const ReportTask &reportTask) { (void) reportTask; } diff --git a/kv_store/frameworks/libs/distributeddb/common/src/evloop/src/event_loop_impl.cpp b/kv_store/frameworks/libs/distributeddb/common/src/evloop/src/event_loop_impl.cpp index 8df03cc6..e8c8fa8b 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/evloop/src/event_loop_impl.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/evloop/src/event_loop_impl.cpp @@ -101,7 +101,7 @@ EventLoopImpl::EventLoopImpl() : pollingSetChanged_(false), running_(true) { - OnKill([this](){ OnKillLoop(); }); + OnKill([this]() { OnKillLoop(); }); } EventLoopImpl::~EventLoopImpl() diff --git a/kv_store/frameworks/libs/distributeddb/common/src/param_check_utils.cpp b/kv_store/frameworks/libs/distributeddb/common/src/param_check_utils.cpp index 4be5c806..59af4492 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/param_check_utils.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/param_check_utils.cpp @@ -53,7 +53,7 @@ bool ParamCheckUtils::IsStoreIdSafe(const std::string &storeId) } bool ParamCheckUtils::CheckStoreParameter(const std::string &storeId, const std::string &appId, - const std::string &userId, bool isIgnoreUserIdCheck) + const std::string &userId, bool isIgnoreUserIdCheck, const std::string &subUser) { if (!IsStoreIdSafe(storeId)) { return false; @@ -72,9 +72,15 @@ bool ParamCheckUtils::CheckStoreParameter(const std::string &storeId, const std: LOGE("Invalid app info[%zu][%zu]", userId.length(), appId.length()); return false; } + // subUser allow empty + if (subUser.length() > DBConstant::MAX_SUB_USER_LENGTH) { + LOGE("Invalid subUser info[%zu][%zu]", userId.length(), subUser.length()); + return false; + } if ((appId.find(DBConstant::ID_CONNECTOR) != std::string::npos) || - (storeId.find(DBConstant::ID_CONNECTOR) != std::string::npos)) { + (storeId.find(DBConstant::ID_CONNECTOR) != std::string::npos) || + (subUser.find(DBConstant::ID_CONNECTOR) != std::string::npos)) { LOGE("Invalid character in the store para info."); return false; } @@ -130,10 +136,12 @@ bool ParamCheckUtils::CheckObserver(const Key &key, unsigned int mode) return false; } uint64_t rawMode = DBCommon::EraseBit(mode, DBConstant::OBSERVER_CHANGES_MASK); - if (rawMode > OBSERVER_CHANGES_CLOUD || rawMode < OBSERVER_CHANGES_NATIVE) { - return false; + if (rawMode == OBSERVER_CHANGES_NATIVE || rawMode == OBSERVER_CHANGES_FOREIGN || + rawMode == OBSERVER_CHANGES_LOCAL_ONLY || rawMode == OBSERVER_CHANGES_CLOUD || + rawMode == (OBSERVER_CHANGES_NATIVE | OBSERVER_CHANGES_FOREIGN)) { + return true; } - return true; + return false; } bool ParamCheckUtils::IsS3SECEOpt(const SecurityOption &secOpt) @@ -287,11 +295,11 @@ bool ParamCheckUtils::CheckSharedTableName(const DataBaseSchema &schema) void ParamCheckUtils::TransferSchemaToLower(DataBaseSchema &schema) { for (auto &tableSchema : schema.tables) { - std::transform(tableSchema.name.begin(), tableSchema.name.end(), tableSchema.name.begin(), tolower); + std::transform(tableSchema.name.begin(), tableSchema.name.end(), tableSchema.name.begin(), ::tolower); std::transform(tableSchema.sharedTableName.begin(), tableSchema.sharedTableName.end(), - tableSchema.sharedTableName.begin(), tolower); + tableSchema.sharedTableName.begin(), ::tolower); for (auto &field : tableSchema.fields) { - std::transform(field.colName.begin(), field.colName.end(), field.colName.begin(), tolower); + std::transform(field.colName.begin(), field.colName.end(), field.colName.begin(), ::tolower); } } } diff --git a/kv_store/frameworks/libs/distributeddb/common/src/platform_specific.cpp b/kv_store/frameworks/libs/distributeddb/common/src/platform_specific.cpp index 96a6ee11..0667fc68 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/platform_specific.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/platform_specific.cpp @@ -78,7 +78,7 @@ int RemoveFile(const std::string &filePath) LOGE("[RemoveFile] Remove file fail %s %d err = %d", filePath.c_str(), errCode, errno); return -E_SYSTEM_API_FAIL; } - LOGI("Remove file successfully!"); + LOGD("Remove file successfully!"); return E_OK; } @@ -398,7 +398,7 @@ int RemoveFile(const std::string &filePath) LOGE("[RemoveFile] Remove file fail. err = %d", errno); return -E_SYSTEM_API_FAIL; } - LOGI("Remove file successfully!"); + LOGD("Remove file successfully!"); return E_OK; } 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 1e9030c2..081aae52 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/query_expression.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/query_expression.cpp @@ -460,7 +460,7 @@ void QueryExpression::SetNotSupportIfNeed(QueryObjType type) int QueryExpression::RangeParamCheck() const { - if (queryInfo_.size() > 1) { // Only Support one query filter. + if (queryInfo_.size() != 1) { // the query filter must have 1 filter and only the Range query. return -E_INVALID_ARGS; } for (const auto &queryObjNode : queryInfo_) { diff --git a/kv_store/frameworks/libs/distributeddb/common/src/query_utils.cpp b/kv_store/frameworks/libs/distributeddb/common/src/query_utils.cpp new file mode 100644 index 00000000..7545096a --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/common/src/query_utils.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "query_utils.h" + +namespace DistributedDB { +void QueryUtils::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; + } +} +} // DistributedDB \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/common/src/relational/relational_result_set_impl.cpp b/kv_store/frameworks/libs/distributeddb/common/src/relational/relational_result_set_impl.cpp index f7d2e2a0..bd065d9b 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/relational/relational_result_set_impl.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/relational/relational_result_set_impl.cpp @@ -330,6 +330,10 @@ DBStatus RelationalResultSetImpl::GetRow(std::map &dat // This func is not API. Impossible concurrency. There is no need to hold mutex. int RelationalResultSetImpl::Put(const DeviceID &deviceName, uint32_t sequenceId, RelationalRowDataSet &&data) { + if (sequenceId == 0) { + LOGE("[RelationalResultSetImpl] Invalid sequenceId"); + return -E_INVALID_ARGS; + } cacheDataSet_[sequenceId - 1] = std::move(data); for (auto iter = cacheDataSet_.begin(); iter != cacheDataSet_.end();) { if (iter->first != static_cast(dataSetSize_)) { 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 ac0df801..38938309 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 @@ -102,6 +102,8 @@ void FieldInfo::SetDataType(const std::string &dataType) std::transform(dataType_.begin(), dataType_.end(), dataType_.begin(), ::tolower); if (IsAssetType() || IsAssetsType()) { storageType_ = StorageType::STORAGE_TYPE_BLOB; // use for cloud sync + } else if (dataType_ == DBConstant::STORAGE_TYPE_LONG) { + storageType_ = StorageType::STORAGE_TYPE_INTEGER; } else { storageType_ = AffinityType(dataType_); } diff --git a/kv_store/frameworks/libs/distributeddb/common/src/runtime_context_impl.cpp b/kv_store/frameworks/libs/distributeddb/common/src/runtime_context_impl.cpp index 21b23de6..eca5b2e6 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/runtime_context_impl.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/runtime_context_impl.cpp @@ -105,6 +105,9 @@ int RuntimeContextImpl::GetCommunicatorAggregator(ICommunicatorAggregator *&outA { outAggregator = nullptr; const std::shared_ptr statusAdapter = GetDBStatusAdapter(); + if (statusAdapter == nullptr) { + return -E_OUT_OF_MEMORY; + } std::lock_guard lock(communicatorLock_); if (communicatorAggregator_ != nullptr) { outAggregator = communicatorAggregator_; @@ -324,7 +327,6 @@ NotificationChain::Listener *RuntimeContextImpl::RegisterTimeChangedLister(const } LOGD("[RuntimeContext] TimeTickMonitor start success"); } - LOGD("[RuntimeContext] call RegisterTimeChangedLister"); return timeTickMonitor_->RegisterTimeChangedLister(action, finalize, errCode); } @@ -787,7 +789,6 @@ void RuntimeContextImpl::StopTimeTickMonitorIfNeed() LOGD("[RuntimeContext] TimeTickMonitor exist because no listener"); timeTickMonitor_ = nullptr; } - LOGD("[RuntimeContext] TimeTickMonitor can not stop because listener is not empty"); } void RuntimeContextImpl::SetDBInfoHandle(const std::shared_ptr &handle) @@ -1204,4 +1205,21 @@ bool RuntimeContextImpl::IsTimeTickMonitorValid() const std::lock_guard autoLock(timeTickMonitorLock_); return timeTickMonitor_ != nullptr; } + +bool RuntimeContextImpl::IsTimeChanged() const +{ + std::lock_guard autoLock(timeTickMonitorLock_); + return timeTickMonitor_ != nullptr && timeTickMonitor_->IsTimeChanged(); +} + +void RuntimeContextImpl::SetTimeChanged(bool timeChange) +{ + std::lock_guard autoLock(timeTickMonitorLock_); + if (timeTickMonitor_ == nullptr) { + timeTickMonitor_ = std::make_unique(); + (void)timeTickMonitor_->StartTimeTickMonitor(); + LOGD("[RuntimeContext] TimeTickMonitor start success"); + } + timeTickMonitor_->SetTimeChanged(timeChange); +} } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/common/src/runtime_context_impl.h b/kv_store/frameworks/libs/distributeddb/common/src/runtime_context_impl.h index e717b94d..0d693f48 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/runtime_context_impl.h +++ b/kv_store/frameworks/libs/distributeddb/common/src/runtime_context_impl.h @@ -180,6 +180,8 @@ public: void ResetDBTimeChangeStatus(const std::vector &dbId) override; bool CheckDBTimeChange(const std::vector &dbId) override; bool IsTimeTickMonitorValid() const override; + bool IsTimeChanged() const override; + void SetTimeChanged(bool timeChange) override; private: static constexpr int MAX_TP_THREADS = 10; // max threads of the task pool. static constexpr int MIN_TP_THREADS = 1; // min threads of the task pool. diff --git a/kv_store/frameworks/libs/distributeddb/common/src/schema_object.cpp b/kv_store/frameworks/libs/distributeddb/common/src/schema_object.cpp index 6e24e2f8..324e5f41 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/schema_object.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/schema_object.cpp @@ -555,14 +555,15 @@ int SchemaObject::ParseCheckSchemaDefine(const JsonObject& inJsonObject) // If everything ok, insert this schema item into schema define // Remember to remove SCHEMA_DEFINE in the front of the fieldpath schemaDefine_[depth][FieldPath(++(subField.first.begin()), subField.first.end())] = attribute; + if (subField.second != FieldType::INTERNAL_FIELD_OBJECT) { + continue; + } // Deal with the nestpath and check depth limitation - if (subField.second == FieldType::INTERNAL_FIELD_OBJECT) { - if (depth == SchemaConstant::SCHEMA_FEILD_PATH_DEPTH_MAX - 1) { // Minus 1 to be the boundary - LOGE("[Schema][ParseDefine] node is INTERNAL_FIELD_OBJECT but reach schema depth limitation."); - return -E_SCHEMA_PARSE_FAIL; - } - nestPathCurDepth.insert(subField.first); + if (depth == (SchemaConstant::SCHEMA_FEILD_PATH_DEPTH_MAX - 1)) { // Minus 1 to be the boundary + LOGE("[Schema][ParseDefine] node is INTERNAL_FIELD_OBJECT but reach schema depth limitation."); + return -E_SCHEMA_PARSE_FAIL; } + nestPathCurDepth.insert(subField.first); } // If no deeper schema define, quit loop in advance if (nestPathCurDepth.empty()) { diff --git a/kv_store/frameworks/libs/distributeddb/common/src/schema_utils.cpp b/kv_store/frameworks/libs/distributeddb/common/src/schema_utils.cpp index 0f3293a5..c6af2033 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/schema_utils.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/schema_utils.cpp @@ -117,14 +117,14 @@ int SchemaUtils::SplitSchemaAttribute(const std::string &inAttrString, std::vect LOGE("default string size must be over 1."); return -E_SCHEMA_PARSE_FAIL; } - outAttrString[2] = inAttrString.substr(i - 1); + outAttrString[2] = inAttrString.substr(i - 1); // 2 is index return E_OK; default: break; } } // Only these states are legal, The meaning of the state can be seen in the matrix STATE_TRANSFER explanation - if (!(state == 1 || state == 3 || state == 7)) { + if (!(state == 1 || state == 3 || state == 7)) { // 1 is state; 3 is state; 7 is state; LOGD("Split Schema Attribute err, err state [%d]", state); return -E_SCHEMA_PARSE_FAIL; } @@ -149,7 +149,7 @@ int SchemaUtils::TransToString(const std::string &defaultContent, SchemaAttribut { // Have been trim, Strip leading and trailing ' if (defaultContent.size() > 1 && defaultContent.front() == '\'' && defaultContent.back() == '\'') { - outAttr.defaultValue.stringValue = defaultContent.substr(1, defaultContent.size() - 2); + outAttr.defaultValue.stringValue = defaultContent.substr(1, defaultContent.size() - 2); // 2: trim trailing if (outAttr.defaultValue.stringValue.size() > SchemaConstant::SCHEMA_DEFAULT_STRING_SIZE_LIMIT) { return -E_SCHEMA_PARSE_FAIL; } @@ -505,14 +505,14 @@ std::string SchemaUtils::FieldPathString(const FieldPath &inPath) void SchemaUtils::TransTrackerSchemaToLower(const TrackerSchema &srcSchema, TrackerSchema &destSchema) { std::string tableName(srcSchema.tableName.length(), ' '); - std::transform(srcSchema.tableName.begin(), srcSchema.tableName.end(), tableName.begin(), tolower); + std::transform(srcSchema.tableName.begin(), srcSchema.tableName.end(), tableName.begin(), ::tolower); destSchema.tableName = tableName; std::string extendName(srcSchema.extendColName.length(), ' '); - std::transform(srcSchema.extendColName.begin(), srcSchema.extendColName.end(), extendName.begin(), tolower); + std::transform(srcSchema.extendColName.begin(), srcSchema.extendColName.end(), extendName.begin(), ::tolower); destSchema.extendColName = extendName; for (const auto &srcName : srcSchema.trackerColNames) { std::string colName(srcName.length(), ' '); - std::transform(srcName.begin(), srcName.end(), colName.begin(), tolower); + std::transform(srcName.begin(), srcName.end(), colName.begin(), ::tolower); destSchema.trackerColNames.insert(colName); } } diff --git a/kv_store/frameworks/libs/distributeddb/common/src/time_tick_monitor.cpp b/kv_store/frameworks/libs/distributeddb/common/src/time_tick_monitor.cpp index 35942ee3..34a0c4d0 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/time_tick_monitor.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/time_tick_monitor.cpp @@ -151,6 +151,7 @@ int TimeTickMonitor::TimeTick(TimerId timerId) if (ret != E_OK) { LOGE("TimeTickMonitor ScheduleTask failed %d", ret); } + timeChanged_ = true; } return E_OK; } @@ -192,4 +193,14 @@ bool TimeTickMonitor::EmptyListener() const std::lock_guard lock(timeTickMonitorLock_); return timeChangedNotifier_->EmptyListener(TIME_CHANGE_EVENT); } + +bool TimeTickMonitor::IsTimeChanged() const +{ + return timeChanged_; +} + +void TimeTickMonitor::SetTimeChanged(bool timeChange) +{ + timeChanged_ = timeChange; +} } // namespace DistributedDB \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/common/src/time_tick_monitor.h b/kv_store/frameworks/libs/distributeddb/common/src/time_tick_monitor.h index 0294ad5a..3bdbc066 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/time_tick_monitor.h +++ b/kv_store/frameworks/libs/distributeddb/common/src/time_tick_monitor.h @@ -43,6 +43,10 @@ public: void NotifyTimeChange(TimeOffset offset) const; bool EmptyListener() const; + + bool IsTimeChanged() const; + + void SetTimeChanged(bool timeChange); private: static constexpr uint64_t MONITOR_INTERVAL = 1 * 1000; // 1s static constexpr int64_t MAX_NOISE = 9 * 100 * 1000; // 900ms @@ -69,6 +73,7 @@ private: Timestamp lastMonotonicTime_ = 0; Timestamp lastSystemTime_ = 0; bool isStarted_ = false; + std::atomic timeChanged_ = false; }; } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/communicator/include/frame_retainer.h b/kv_store/frameworks/libs/distributeddb/communicator/include/frame_retainer.h index a0b14408..4a7c80e9 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/include/frame_retainer.h +++ b/kv_store/frameworks/libs/distributeddb/communicator/include/frame_retainer.h @@ -58,6 +58,9 @@ public: std::list FetchFramesForSpecificCommunicator(const LabelType &inCommLabel); private: + void DecreaseRemainTimeAndDiscard(const LabelType &label, + std::pair> &eachTarget, std::set &frameToDiscard); + // This methed called from timer, it has overallMutex_ protect itself inside the method void PeriodicalSurveillance(); 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 2db196df..0ab33930 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_aggregator.cpp +++ b/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_aggregator.cpp @@ -27,7 +27,7 @@ namespace DistributedDB { namespace { constexpr int MAX_SEND_RETRY = 2; -constexpr int RETRY_TIME_SPLITS = 4; +constexpr int RETRY_TIME_SPLIT = 4; inline std::string GetThreadId() { std::stringstream stream; @@ -1073,7 +1073,7 @@ int32_t CommunicatorAggregator::GetNextRetryInterval(const std::string &target, if (adapterHandle_ != nullptr) { timeout = adapterHandle_->GetTimeout(target); } - return static_cast(timeout) * currentRetryCount / RETRY_TIME_SPLITS; + return static_cast(timeout) * currentRetryCount / RETRY_TIME_SPLIT; } uint64_t CommunicatorAggregator::GetSendSequenceId(const std::string &target) diff --git a/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_linker.cpp b/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_linker.cpp index 96f35894..9b0ac602 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_linker.cpp +++ b/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_linker.cpp @@ -259,7 +259,7 @@ void CommunicatorLinker::DetectDistinctValueChange(const std::string &inTarget, } // DistinctValue change detected !!! This must be caused by malfunctioning of underlayer communication component. - LOGE("[Linker][Detect] ######## DISTINCT VALUE CHANGE DETECTED : %" PRIu64 " VS %" PRIu64 " ########", + LOGE("[Linker][Detect] DISTINCT VALUE CHANGE DETECTED : %" PRIu64 " VS %" PRIu64 "", ULL(inDistinctValue), ULL(targetDistinctValue_[inTarget])); targetDistinctValue_[inTarget] = inDistinctValue; // The process of remote target must have undergone a quit and restart, the remote sequenceId will start from zero. @@ -412,7 +412,7 @@ void CommunicatorLinker::SendLabelExchange(const std::string &toTarget, SerialBu SuspendByOnceTimer([this, toTarget, inBuff, inSequenceId, inRetransmitCount]() { // Note: toTarget and inBuff and inSequenceId should be captured by value (must not by reference) SendLabelExchange(toTarget, inBuff, inSequenceId, inRetransmitCount); // Just do retry send - }, TIME_LAPSE_FOR_RETRY_SEND); + }, TIME_LAPSE_FOR_RETRY_SEND); if (error == E_OK) { delete cloneBuffer; cloneBuffer = nullptr; @@ -462,7 +462,7 @@ void CommunicatorLinker::SendLabelExchangeAck(const std::string &toTarget, Seria SuspendByOnceTimer([this, toTarget, inBuff, inSequenceId, inAckTriggerId]() { // Note: toTarget, inBuff, inSequenceId, inAckTriggerId should be captured by value (must not by reference) SendLabelExchangeAck(toTarget, inBuff, inSequenceId, inAckTriggerId); - }, TIME_LAPSE_FOR_RETRY_SEND); + }, TIME_LAPSE_FOR_RETRY_SEND); } } diff --git a/kv_store/frameworks/libs/distributeddb/communicator/src/db_status_adapter.cpp b/kv_store/frameworks/libs/distributeddb/communicator/src/db_status_adapter.cpp index d2f66e1f..c36ca755 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/src/db_status_adapter.cpp +++ b/kv_store/frameworks/libs/distributeddb/communicator/src/db_status_adapter.cpp @@ -49,13 +49,10 @@ bool DBStatusAdapter::IsSupport(const std::string &devInfo) if (IsSendLabelExchange()) { return false; } - { - std::lock_guard autoLock(supportMutex_); - if (remoteOptimizeInfo_.find(devInfo) != remoteOptimizeInfo_.end()) { - return remoteOptimizeInfo_[devInfo]; - } - } std::lock_guard autoLock(supportMutex_); + if (remoteOptimizeInfo_.find(devInfo) != remoteOptimizeInfo_.end()) { + return remoteOptimizeInfo_[devInfo]; + } remoteOptimizeInfo_[devInfo] = true; return true; } @@ -89,6 +86,7 @@ void DBStatusAdapter::SetDBStatusChangeCallback(const RemoteDBChangeCallback &re supportCallback_ = supportCallback; } if (remote == nullptr || local == nullptr) { + LOGD("[DBStatusAdapter][SetDBStatusChangeCallback] remote or local DB change callback is NULL."); return; } // avoid notify before set callback @@ -151,6 +149,7 @@ void DBStatusAdapter::TargetOffline(const std::string &device) { std::shared_ptr dbInfoHandle = GetDBInfoHandle(); if (dbInfoHandle == nullptr) { + LOGD("[DBStatusAdapter][TargetOffline] handle not set"); return; } { @@ -176,6 +175,7 @@ void DBStatusAdapter::SetRemoteOptimizeCommunication(const std::string &dev, boo { std::shared_ptr dbInfoHandle = GetDBInfoHandle(); if (dbInfoHandle == nullptr) { + LOGD("[DBStatusAdapter][SetRemoteOptimizeCommunication] handle not set"); return; } bool triggerLocalCallback = false; @@ -188,7 +188,7 @@ void DBStatusAdapter::SetRemoteOptimizeCommunication(const std::string &dev, boo if (remoteOptimizeInfo_[dev] == optimize) { return; } - if (remoteOptimizeInfo_[dev] && !optimize) { + if (remoteOptimizeInfo_[dev]) { triggerLocalCallback = true; } remoteOptimizeInfo_[dev] = optimize; @@ -216,6 +216,7 @@ bool DBStatusAdapter::IsSendLabelExchange() { std::shared_ptr dbInfoHandle = GetDBInfoHandle(); if (dbInfoHandle == nullptr) { + LOGD("[DBStatusAdapter][IsSendLabelExchange] handle not set"); return true; } { @@ -325,6 +326,7 @@ int DBStatusAdapter::GetLocalDeviceId(std::string &deviceId) ICommunicatorAggregator *communicatorAggregator = nullptr; int errCode = RuntimeContext::GetInstance()->GetCommunicatorAggregator(communicatorAggregator); if (errCode != E_OK) { + LOGE("[DBStatusAdapter][GetLocalDeviceId] Get ICommunicatorAggregator error: %d", errCode); return errCode; } return communicatorAggregator->GetLocalIdentity(deviceId); @@ -334,6 +336,7 @@ bool DBStatusAdapter::IsLocalDeviceId(const std::string &deviceId) { std::string localId; if (GetLocalDeviceId(localId) != E_OK) { + LOGE("[DBStatusAdapter][IsLocalDeviceId] Get local device ID failed."); return false; } return deviceId == localId; diff --git a/kv_store/frameworks/libs/distributeddb/communicator/src/frame_combiner.cpp b/kv_store/frameworks/libs/distributeddb/communicator/src/frame_combiner.cpp index 70ee3d8f..5fafb9e8 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/src/frame_combiner.cpp +++ b/kv_store/frameworks/libs/distributeddb/communicator/src/frame_combiner.cpp @@ -25,7 +25,7 @@ static const int COMBINER_SURVAIL_PERIOD_IN_MILLISECOND = 10000; // Period is 10 void FrameCombiner::Initialize() { RuntimeContext *context = RuntimeContext::GetInstance(); - TimerAction action = [this](TimerId inTimerId)->int{ + TimerAction action = [this](TimerId inTimerId)->int { PeriodicalSurveillance(); return E_OK; }; diff --git a/kv_store/frameworks/libs/distributeddb/communicator/src/frame_retainer.cpp b/kv_store/frameworks/libs/distributeddb/communicator/src/frame_retainer.cpp index fb2ad816..fc0eb0bb 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/src/frame_retainer.cpp +++ b/kv_store/frameworks/libs/distributeddb/communicator/src/frame_retainer.cpp @@ -149,6 +149,27 @@ std::list FrameRetainer::FetchFramesForSpecificCommunicator(const Lab return outFrameList; } +void FrameRetainer::DecreaseRemainTimeAndDiscard(const LabelType &label, + std::pair> &eachTarget, std::set &frameToDiscard) +{ + for (auto &eachFrame : eachTarget.second) { + // Decrease remainTime and discard if need. The remainTime will not be zero before decrease. + eachFrame.second.remainTime--; + if (eachFrame.second.remainTime != 0) { + continue; + } + LogRetainInfo("[Retainer][Surveil] DISCARD", label, eachTarget.first, eachFrame.first, + eachFrame.second); + totalSizeByByte_ -= eachFrame.second.buffer->GetSize(); + totalRetainFrames_--; + // Free this retain work first + delete eachFrame.second.buffer; + eachFrame.second.buffer = nullptr; + // Record this frame in discard list + frameToDiscard.insert(eachFrame.first); + } +} + void FrameRetainer::PeriodicalSurveillance() { std::lock_guard overallLockGuard(overallMutex_); @@ -156,21 +177,7 @@ void FrameRetainer::PeriodicalSurveillance() for (auto &eachLabel : retainWorkPool_) { for (auto &eachTarget : eachLabel.second) { std::set frameToDiscard; - for (auto &eachFrame : eachTarget.second) { - // Decrease remainTime and discard if need. The remainTime will not be zero before decrease. - eachFrame.second.remainTime--; - if (eachFrame.second.remainTime == 0) { - LogRetainInfo("[Retainer][Surveil] DISCARD", eachLabel.first, eachTarget.first, eachFrame.first, - eachFrame.second); - totalSizeByByte_ -= eachFrame.second.buffer->GetSize(); - totalRetainFrames_--; - // Free this retain work first - delete eachFrame.second.buffer; - eachFrame.second.buffer = nullptr; - // Record this frame in discard list - frameToDiscard.insert(eachFrame.first); - } - } + DecreaseRemainTimeAndDiscard(eachLabel.first, eachTarget, frameToDiscard); // Remove the retain work from frameMap. for (auto &entry : frameToDiscard) { eachTarget.second.erase(entry); 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 da371782..729bccaa 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/src/network_adapter.cpp +++ b/kv_store/frameworks/libs/distributeddb/communicator/src/network_adapter.cpp @@ -120,7 +120,7 @@ void NetworkAdapter::StopAdapter() // The async task is dependent on this Object. we have to wait until all async task finished. LOGI("[NAdapt][Stop] Wait all async task done."); std::unique_lock asyncTaskDoneLock(asyncTaskDoneMutex_); - asyncTaskDoneCv_.wait(asyncTaskDoneLock, [this]{ return pendingAsyncTaskCount_ <= 0; }); + asyncTaskDoneCv_.wait(asyncTaskDoneLock, [this] { return pendingAsyncTaskCount_ <= 0; }); LOGI("[NAdapt][Stop] Exit."); } @@ -303,7 +303,7 @@ void NetworkAdapter::OnDeviceChangeHandler(const DeviceInfos &devInfo, bool isOn // The IProcessCommunicator implementation guarantee that no mistake offline will happen. if (isOnline) { if (!processCommunicator_->IsSameProcessLabelStartedOnPeerDevice(devInfo)) { - LOGI("[NAdapt][OnDeviceChange] ######## Detect Not Really Online ########."); + LOGI("[NAdapt][OnDeviceChange] Detect Not Really Online."); std::lock_guard onlineRemoteDevLockGuard(onlineRemoteDevMutex_); onlineRemoteDev_.erase(devInfo.identifier); return; @@ -327,31 +327,32 @@ void NetworkAdapter::SearchOnlineRemoteDeviceAtStartup() { std::vector onlineDev = processCommunicator_->GetRemoteOnlineDeviceInfosList(); LOGE("[NAdapt][SearchOnline] onlineDev count = %zu.", onlineDev.size()); - if (!onlineDev.empty()) { - pendingAsyncTaskCount_.fetch_add(1); - // Note: onlineDev should be captured by value (must not by reference) - TaskAction callbackTask = [onlineDev, this]() { - LOGI("[NAdapt][SearchOnline] Begin Callback In Async Task."); - std::string localIdentity; - GetLocalIdentity(localIdentity); // It doesn't matter if getlocal fail and localIdentity be an empty string - for (auto &entry : onlineDev) { - if (entry.identifier == localIdentity) { - LOGW("[NAdapt][SearchOnline] ######## Detect Local Device in Remote Device List ########."); - continue; - } - OnDeviceChangeHandler(entry, true); + if (onlineDev.empty()) { + return; + } + pendingAsyncTaskCount_.fetch_add(1); + // Note: onlineDev should be captured by value (must not by reference) + TaskAction callbackTask = [onlineDev, this]() { + LOGI("[NAdapt][SearchOnline] Begin Callback In Async Task."); + std::string localIdentity; + GetLocalIdentity(localIdentity); // It doesn't matter if getlocal fail and localIdentity be an empty string + for (auto &entry : onlineDev) { + if (entry.identifier == localIdentity) { + LOGW("[NAdapt][SearchOnline] Detect Local Device in Remote Device List."); + continue; } - pendingAsyncTaskCount_.fetch_sub(1); - asyncTaskDoneCv_.notify_all(); - LOGI("[NAdapt][SearchOnline] End Callback In Async Task."); - }; - // Use ScheduleQueuedTask to keep order - int errCode = RuntimeContext::GetInstance()->ScheduleQueuedTask(SCHEDULE_QUEUE_TAG, callbackTask); - if (errCode != E_OK) { - LOGE("[NAdapt][SearchOnline] ScheduleQueuedTask failed, errCode = %d.", errCode); - pendingAsyncTaskCount_.fetch_sub(1); - asyncTaskDoneCv_.notify_all(); + OnDeviceChangeHandler(entry, true); } + pendingAsyncTaskCount_.fetch_sub(1); + asyncTaskDoneCv_.notify_all(); + LOGI("[NAdapt][SearchOnline] End Callback In Async Task."); + }; + // Use ScheduleQueuedTask to keep order + int errCode = RuntimeContext::GetInstance()->ScheduleQueuedTask(SCHEDULE_QUEUE_TAG, callbackTask); + if (errCode != E_OK) { + LOGE("[NAdapt][SearchOnline] ScheduleQueuedTask failed, errCode = %d.", errCode); + pendingAsyncTaskCount_.fetch_sub(1); + asyncTaskDoneCv_.notify_all(); } } @@ -385,7 +386,7 @@ void NetworkAdapter::CheckDeviceOfflineAfterSendFail(const DeviceInfos &devInfo) // Seem online but send fail, we have to check whether still online if (!isAlreadyOffline) { if (!processCommunicator_->IsSameProcessLabelStartedOnPeerDevice(devInfo)) { - LOGW("[NAdapt][CheckAfterSend] ######## Missed Offline Detected ########."); + LOGW("[NAdapt][CheckAfterSend] Missed Offline Detected."); { // Mark this device not online immediately to avoid repeatedly miss-offline detect when send continually std::lock_guard onlineRemoteDevLockGuard(onlineRemoteDevMutex_); diff --git a/kv_store/frameworks/libs/distributeddb/distributeddb.gni b/kv_store/frameworks/libs/distributeddb/distributeddb.gni index aa09533a..a9c00a25 100644 --- a/kv_store/frameworks/libs/distributeddb/distributeddb.gni +++ b/kv_store/frameworks/libs/distributeddb/distributeddb.gni @@ -21,6 +21,7 @@ distributeddb_src = [ "${distributeddb_path}/common/src/data_compression.cpp", "${distributeddb_path}/common/src/data_value.cpp", "${distributeddb_path}/common/src/db_common.cpp", + "${distributeddb_path}/common/src/db_base64_utils.cpp", "${distributeddb_path}/common/src/db_constant.cpp", "${distributeddb_path}/common/src/db_dfx_adapter.cpp", "${distributeddb_path}/common/src/db_dump_helper.cpp", @@ -42,6 +43,7 @@ distributeddb_src = [ "${distributeddb_path}/common/src/platform_specific.cpp", "${distributeddb_path}/common/src/query.cpp", "${distributeddb_path}/common/src/query_expression.cpp", + "${distributeddb_path}/common/src/query_utils.cpp", "${distributeddb_path}/common/src/ref_object.cpp", "${distributeddb_path}/common/src/relational/prepared_stmt.cpp", "${distributeddb_path}/common/src/relational/relational_result_set_impl.cpp", diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/BUILD.gn b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/BUILD.gn index f26b1c06..96499b75 100644 --- a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/BUILD.gn +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/BUILD.gn @@ -53,6 +53,8 @@ group("build_module") { ohos_static_library("gaussdb_rd") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false @@ -90,15 +92,11 @@ ohos_static_library("gaussdb_rd") { configs = [ ":gaussdb_rd_config" ] public_configs = [ ":gaussdb_rd_public_config" ] - deps = [ "//third_party/sqlite:sqlite" ] - - configs += [ "//third_party/cJSON:cJSON_config" ] ldflags = [ "-Wl,--exclude-libs,ALL" ] cflags_cc = [ "-fvisibility=hidden", "-std=c++17", ] - deps += [ "//third_party/cJSON:cjson" ] external_deps = [ "c_utils:utils", @@ -107,6 +105,11 @@ ohos_static_library("gaussdb_rd") { "hitrace:hitrace_meter", ] + public_external_deps = [ + "cJSON:cjson", + "sqlite:sqlite", + ] + subsystem_name = "distributeddatamgr" part_name = "kv_store" } diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/rd_db_constant.h b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/rd_db_constant.h index efd1d88e..f2c1972d 100644 --- a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/rd_db_constant.h +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/common/include/rd_db_constant.h @@ -19,7 +19,7 @@ #include namespace DocumentDB { -class DBConstant final { +class RdDBConstant final { public: static constexpr const char *COLL_PREFIX = "GRD_COLL_"; }; diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/collection.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/collection.cpp index 444910dc..89f76030 100644 --- a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/collection.cpp +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/collection.cpp @@ -28,7 +28,7 @@ Collection::Collection(const std::string &name, KvStoreExecutor *executor) : exe std::transform(lowerCaseName.begin(), lowerCaseName.end(), lowerCaseName.begin(), [](unsigned char c) { return std::tolower(c); }); - name_ = DBConstant::COLL_PREFIX + lowerCaseName; + name_ = RdDBConstant::COLL_PREFIX + lowerCaseName; } Collection::~Collection() 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 258e074f..1666428a 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 @@ -39,6 +39,7 @@ static int InitDocIdFromOid(DocKey &docKey) } char *idTemp = new char[GRD_DOC_OID_HEX_SIZE + 1]; if (sprintf_s(idTemp, GRD_DOC_OID_HEX_SIZE + 1, "%08x%04x", now, iv) < 0) { + delete[] idTemp; GLOGE("get oid error"); return -E_INNER_ERROR; } diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/projection_tree.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/projection_tree.cpp index acd2862f..f33d694f 100644 --- a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/projection_tree.cpp +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/projection_tree.cpp @@ -46,6 +46,7 @@ static int ParseSinglePathToTree(ProjectionNode *node, std::vector } return E_OK; } + int ProjectionTree::ParseTree(std::vector> &path) { ProjectionNode *node = &node_; diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/result_set.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/result_set.cpp index a9a70195..e09a511d 100644 --- a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/result_set.cpp +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/interface/src/result_set.cpp @@ -103,7 +103,7 @@ int ResultSet::GetNextInner(bool isNeedCheckTable) std::transform(lowerCaseName.begin(), lowerCaseName.end(), lowerCaseName.begin(), [](unsigned char c) { return std::tolower(c); }); - bool isCollectionExist = store_->IsCollectionExists(DBConstant::COLL_PREFIX + lowerCaseName, errCode); + bool isCollectionExist = store_->IsCollectionExists(RdDBConstant::COLL_PREFIX + lowerCaseName, errCode); if (errCode != E_OK) { return errCode; } diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.cpp index e75b4cbc..53606524 100644 --- a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.cpp +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.cpp @@ -322,7 +322,7 @@ int SqliteStoreExecutorImpl::CreateCollection(const std::string &name, const std if (dbHandle_ == nullptr) { return -E_ERROR; } - std::string collName = DBConstant::COLL_PREFIX + name; + std::string collName = RdDBConstant::COLL_PREFIX + name; int errCode = E_OK; bool isExists = IsCollectionExists(collName, errCode); if (errCode != E_OK) { @@ -354,7 +354,7 @@ int SqliteStoreExecutorImpl::DropCollection(const std::string &name, bool ignore return -E_ERROR; } - std::string collName = DBConstant::COLL_PREFIX + name; + std::string collName = RdDBConstant::COLL_PREFIX + name; if (!ignoreNonExists) { int errCode = E_OK; bool isExists = IsCollectionExists(collName, errCode); diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/test/unittest/BUILD.gn b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/test/unittest/BUILD.gn index e75938e5..a23631f3 100644 --- a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/test/unittest/BUILD.gn +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/test/unittest/BUILD.gn @@ -107,6 +107,16 @@ template("gaussdb_rd_unittest") { external_deps = [] } configs = [ ":module_private_config" ] + + branch_protector_ret = "pac_ret" + sanitize = { + ubsan = true + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + } + deps += [ ":src_file", "//third_party/googletest:gmock_main", 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 cb935cab..91e57739 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 @@ -16,11 +16,11 @@ #ifndef CLOUD_STORE_TYPE_H #define CLOUD_STORE_TYPE_H +#include #include #include #include #include -#include #include "query.h" #include "store_types.h" @@ -121,13 +121,17 @@ enum class CloudQueryType : int64_t { enum class LockAction : uint32_t { NONE = 0, - INSERT = 1 + INSERT = 0x1, + UPDATE = 0x2, + DELETE = 0x4, + DOWNLOAD = 0x8 }; enum CloudSyncState { IDLE = 0, DO_DOWNLOAD, DO_UPLOAD, + DO_REPEAT_CHECK, DO_FINISHED }; @@ -135,6 +139,7 @@ enum CloudSyncEvent { UPLOAD_FINISHED_EVENT, DOWNLOAD_FINISHED_EVENT, ERROR_EVENT, + REPEAT_CHECK_EVENT, REPEAT_DOWNLOAD_EVENT, START_SYNC_EVENT, ALL_TASK_FINISHED_EVENT @@ -187,5 +192,11 @@ enum class LockStatus : uint32_t { LOCK_CHANGE, BUTT, }; + +struct CloudSyncConfig { + int32_t maxUploadCount = 30; // default max upload 30 records + int32_t maxUploadSize = 1024 * 512 * 3; // default max upload 1024 * 512 * 3 = 1.5m + int32_t maxRetryConflictTimes = -1; // default max retry -1 is unlimited retry times +}; } // namespace DistributedDB #endif // CLOUD_STORE_TYPE_H \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/include/intercepted_data.h b/kv_store/frameworks/libs/distributeddb/interfaces/include/intercepted_data.h index 9d6fa2cf..8cc33d47 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/include/intercepted_data.h +++ b/kv_store/frameworks/libs/distributeddb/interfaces/include/intercepted_data.h @@ -44,5 +44,6 @@ public: // The callback function works on the send data from device "sourceID" to device "targetID". using PushDataInterceptor = std::function; +using DataInterceptor = PushDataInterceptor; } // namespace DistributedDB #endif // INTERCEPTED_DATA_H \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/include/kv_store_delegate_manager.h b/kv_store/frameworks/libs/distributeddb/interfaces/include/kv_store_delegate_manager.h index f3d9ae77..fdc97a6f 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/include/kv_store_delegate_manager.h +++ b/kv_store/frameworks/libs/distributeddb/interfaces/include/kv_store_delegate_manager.h @@ -32,6 +32,8 @@ namespace DistributedDB { class KvStoreDelegateManager final { public: DB_API KvStoreDelegateManager(const std::string &appId, const std::string &userId, int32_t instanceId = 0); + DB_API KvStoreDelegateManager(const std::string &appId, const std::string &userId, const std::string &subUser, + int32_t instanceId = 0); DB_API ~KvStoreDelegateManager(); KvStoreDelegateManager(const KvStoreDelegateManager &) = delete; @@ -123,6 +125,7 @@ private: KvStoreConfig kvStoreConfig_; std::string appId_; std::string userId_; + std::string subUser_; int32_t instanceId_; mutable std::mutex mutex_; diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/include/kv_store_nb_delegate.h b/kv_store/frameworks/libs/distributeddb/interfaces/include/kv_store_nb_delegate.h index d621c6fb..43f46719 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/include/kv_store_nb_delegate.h +++ b/kv_store/frameworks/libs/distributeddb/interfaces/include/kv_store_nb_delegate.h @@ -263,6 +263,17 @@ public: // get cloud version by device DB_API virtual std::pair> GetCloudVersion( const std::string &device) = 0; + + // This API is not recommended. Before using this API, you need to understand the API usage rules. + // The interceptor works when receive data. + DB_API virtual DBStatus SetReceiveDataInterceptor(const DataInterceptor &interceptor) = 0; + + // set the config for cloud sync task + DB_API virtual DBStatus SetCloudSyncConfig(const CloudSyncConfig &config) = 0; + + // Get Entries by the device(uuid) in sync_data. + // If device is empty, it would return all the entries which was written by local device. + DB_API virtual DBStatus GetDeviceEntries(const std::string &device, std::vector &entries) const = 0; }; } // namespace DistributedDB 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 59a627c4..132786ec 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 @@ -97,6 +97,9 @@ public: DB_API virtual DBStatus UpsertData(const std::string &tableName, const std::vector &records, RecordStatus status = RecordStatus::WAIT_COMPENSATED_SYNC) = 0; + + // set the config for cloud sync task + DB_API virtual DBStatus SetCloudSyncConfig(const CloudSyncConfig &config) = 0; protected: virtual DBStatus RemoveDeviceDataInner(const std::string &device, ClearMode mode) = 0; virtual DBStatus CreateDistributedTableInner(const std::string &tableName, TableSyncType type) = 0; diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/include/relational/relational_store_manager.h b/kv_store/frameworks/libs/distributeddb/interfaces/include/relational/relational_store_manager.h index 0e31d33b..745f4dc7 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/include/relational/relational_store_manager.h +++ b/kv_store/frameworks/libs/distributeddb/interfaces/include/relational/relational_store_manager.h @@ -35,6 +35,8 @@ public: const std::map &collateTypeMap = {}); DB_API RelationalStoreManager(const std::string &appId, const std::string &userId, int32_t instanceId = 0); + DB_API RelationalStoreManager(const std::string &appId, const std::string &userId, const std::string &subUser, + int32_t instanceId = 0); DB_API ~RelationalStoreManager() = default; RelationalStoreManager(const RelationalStoreManager &) = delete; @@ -60,6 +62,7 @@ private: RelationalStoreDelegate *&delegate, std::string &canonicalDir); std::string appId_; std::string userId_; + std::string subUser_; int32_t instanceId_; }; } // namespace DistributedDB 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 aaf3f64d..60210dd6 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/include/store_types.h +++ b/kv_store/frameworks/libs/distributeddb/interfaces/include/store_types.h @@ -223,11 +223,11 @@ struct ChangeProperties { enum IndexType : uint32_t { /** - * use btree index type in database + * use btree index type in database */ BTREE = 0, /** - * use hash index type in database + * use hash index type in database */ HASH, }; @@ -235,13 +235,21 @@ enum IndexType : uint32_t { struct Rdconfig { bool readOnly = false; IndexType type = BTREE; - int pageSize = 32u; - int cacheSize = 2048u; + uint32_t pageSize = 32u; + uint32_t cacheSize = 2048u; }; struct WatermarkInfo { uint64_t sendMark = 0; // data will be sent which timestamp greater than sendMark uint64_t receiveMark = 0; // data will be sent in remote which timestamp greater than receiveMark }; + +struct DbIdParam { + std::string appId; + std::string userId; + std::string storeId; + std::string subUser = ""; + int32_t instanceId = 0; +}; } // namespace DistributedDB #endif // KV_STORE_TYPE_H diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/src/intercepted_data_impl.cpp b/kv_store/frameworks/libs/distributeddb/interfaces/src/intercepted_data_impl.cpp index 9dafce35..af53410d 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/src/intercepted_data_impl.cpp +++ b/kv_store/frameworks/libs/distributeddb/interfaces/src/intercepted_data_impl.cpp @@ -76,7 +76,7 @@ InterceptedDataImpl::InterceptedDataImpl(std::vector dataIte // New packet cannot exceed both twice the MTU and twice the original size. // Besides, it cannot exceed 30 MB. maxPacketSize_ = std::min(DBConstant::MAX_SYNC_BLOCK_SIZE, - std::max(totalLength_, static_cast(DBConstant::MAX_MTU_SIZE)) * 2); + std::max(totalLength_, static_cast(DBConstant::MAX_MTU_SIZE)) * 2); // 2 times MAX_MTU size } InterceptedDataImpl::~InterceptedDataImpl() 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 1df65cb7..380bb2a5 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 @@ -115,8 +115,8 @@ namespace { properties.SetBoolProp(KvDBProperties::READ_ONLY_MODE, option.rdconfig.readOnly); bool sharedMode = (option.storageEngineType == GAUSSDB_RD); properties.SetBoolProp(KvDBProperties::SHARED_MODE, sharedMode); - properties.SetIntProp(KvDBProperties::PAGE_SIZE1, option.rdconfig.pageSize); - properties.SetIntProp(KvDBProperties::CACHE_SIZE, option.rdconfig.cacheSize); + properties.SetUIntProp(KvDBProperties::PAGE_SIZE1, option.rdconfig.pageSize); + properties.SetUIntProp(KvDBProperties::CACHE_SIZE, option.rdconfig.cacheSize); properties.SetIntProp(KvDBProperties::INDEX_TYPE, option.rdconfig.type); } @@ -159,6 +159,14 @@ KvStoreDelegateManager::KvStoreDelegateManager(const std::string &appId, const s instanceId_(instanceId) {} +KvStoreDelegateManager::KvStoreDelegateManager(const std::string &appId, const std::string &userId, + const std::string &subUser, int32_t instanceId) + : appId_(appId), + userId_(userId), + subUser_(subUser), + instanceId_(instanceId) +{} + KvStoreDelegateManager::~KvStoreDelegateManager() {} DBStatus KvStoreDelegateManager::SetKvStoreConfig(const KvStoreConfig &kvStoreConfig) @@ -188,7 +196,7 @@ void KvStoreDelegateManager::GetKvStore(const std::string &storeId, const KvStor } #ifndef OMIT_MULTI_VER // Multi version and local database mode not allow the creation of a memory database - if (!ParamCheckUtils::CheckStoreParameter(storeId, appId_, userId_) || GetKvStorePath().empty()) { + if (!ParamCheckUtils::CheckStoreParameter(storeId, appId_, userId_, false, subUser_) || GetKvStorePath().empty()) { callback(INVALID_ARGS, nullptr); return; } @@ -202,13 +210,11 @@ void KvStoreDelegateManager::GetKvStore(const std::string &storeId, const KvStor KvDBProperties properties; InitPropWithOption(properties, GetKvStorePath(), option); - DBCommon::SetDatabaseIds(properties, appId_, userId_, storeId); + DbIdParam dbIdParam = { appId_, userId_, storeId }; + DBCommon::SetDatabaseIds(properties, dbIdParam); int errCode; IKvDBConnection *conn = GetOneConnectionWithRetry(properties, errCode); - if (errCode == -E_INVALID_PASSWD_OR_CORRUPTED_DB) { - DBDfxAdapter::ReportFault( { DBDfxAdapter::EVENT_OPEN_DATABASE_FAILED, userId_, appId_, storeId, errCode } ); - } if (conn == nullptr) { DBStatus status = TransferDBErrno(errCode); callback(status, nullptr); @@ -262,7 +268,7 @@ bool KvStoreDelegateManager::GetKvStoreParamCheck(const std::string &storeId, co LOGE("[KvStoreMgr] Unsupport option for RD mode"); return false; } - if (!ParamCheckUtils::CheckStoreParameter(storeId, appId_, userId_) || + if (!ParamCheckUtils::CheckStoreParameter(storeId, appId_, userId_, false, subUser_) || (GetKvStorePath().empty() && !option.isMemoryDb)) { LOGE("[KvStoreMgr] Invalid id or path info for the store"); callback(INVALID_ARGS, nullptr); @@ -318,13 +324,11 @@ void KvStoreDelegateManager::GetKvStore(const std::string &storeId, const KvStor } KvDBProperties properties; InitPropWithNbOption(properties, GetKvStorePath(), schema, option); - DBCommon::SetDatabaseIds(properties, appId_, userId_, storeId, instanceId_); + DbIdParam dbIdParam = { appId_, userId_, storeId, subUser_, instanceId_ }; + DBCommon::SetDatabaseIds(properties, dbIdParam); int errCode; IKvDBConnection *conn = GetOneConnectionWithRetry(properties, errCode); - if (errCode == -E_INVALID_PASSWD_OR_CORRUPTED_DB) { - DBDfxAdapter::ReportFault( { DBDfxAdapter::EVENT_OPEN_DATABASE_FAILED, userId_, appId_, storeId, errCode } ); - } DBStatus status = TransferDBErrno(errCode); if (conn == nullptr) { callback(status, nullptr); @@ -405,7 +409,8 @@ DBStatus KvStoreDelegateManager::DeleteKvStore(const std::string &storeId) KvDBProperties properties; properties.SetStringProp(KvDBProperties::DATA_DIR, GetKvStorePath()); - DBCommon::SetDatabaseIds(properties, appId_, userId_, storeId); + DbIdParam dbIdParam = { appId_, userId_, storeId }; + DBCommon::SetDatabaseIds(properties, dbIdParam); int errCode = KvDBManager::RemoveDatabase(properties); if (errCode == E_OK) { LOGI("Database deleted successfully!"); @@ -474,7 +479,8 @@ DBStatus KvStoreDelegateManager::GetKvStoreDiskSize(const std::string &storeId, } KvDBProperties properties; properties.SetStringProp(KvDBProperties::DATA_DIR, dataDir); - DBCommon::SetDatabaseIds(properties, appId_, userId_, storeId); + DbIdParam dbIdParam = { appId_, userId_, storeId }; + DBCommon::SetDatabaseIds(properties, dbIdParam); int errCode = KvDBManager::CalculateKvStoreSize(properties, size); if (errCode != E_OK) { if (errCode == -E_NOT_FOUND) { @@ -581,7 +587,7 @@ DBStatus KvStoreDelegateManager::DisableKvStoreAutoLaunch(const std::string &use return DB_ERROR; } - std::string syncIdentifier = DBCommon::GenerateIdentifierId(storeId, appId, userId, 0); + std::string syncIdentifier = DBCommon::GenerateIdentifierId(storeId, appId, userId, "", 0); std::string hashIdentifier = DBCommon::TransferHashString(syncIdentifier); std::string dualIdentifier = DBCommon::TransferHashString(DBCommon::GenerateDualTupleIdentifierId(storeId, appId)); int errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(hashIdentifier, dualIdentifier, userId); 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 3395aa4e..d360b50f 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 @@ -378,7 +378,7 @@ DBStatus KvStoreNbDelegateImpl::RegisterObserver(const Key &key, unsigned int mo if (rawMode == static_cast(ObserverMode::OBSERVER_CHANGES_CLOUD)) { return RegisterCloudObserver(key, mode, observer); } - return RegisterDeviceObserver(key, rawMode, observer); + return RegisterDeviceObserver(key, static_cast(rawMode), observer); } DBStatus KvStoreNbDelegateImpl::RegisterDeviceObserver(const Key &key, unsigned int mode, KvStoreObserver *observer) @@ -393,6 +393,10 @@ DBStatus KvStoreNbDelegateImpl::RegisterDeviceObserver(const Key &key, unsigned } std::lock_guard lockGuard(observerMapLock_); + if (observerMap_.size() >= DBConstant::MAX_OBSERVER_COUNT) { + LOGE("[KvStoreNbDelegate] The number of kv observers has been over limit, storeId[%.3s]", storeId_.c_str()); + return OVER_MAX_LIMITS; + } if (observerMap_.find(observer) != observerMap_.end()) { LOGE("[KvStoreNbDelegate] Observer has been already registered!"); return ALREADY_SET; @@ -408,13 +412,13 @@ DBStatus KvStoreNbDelegateImpl::RegisterDeviceObserver(const Key &key, unsigned } int errCode = E_OK; + auto storeId = storeId_; KvDBObserverHandle *observerHandle = conn_->RegisterObserver( mode, key, - [observer](const KvDBCommitNotifyData ¬ifyData) { + [observer, storeId](const KvDBCommitNotifyData ¬ifyData) { KvStoreChangedDataImpl data(¬ifyData); - LOGI("[KvStoreNbDelegate] Begin trigger on change"); + LOGD("[KvStoreNbDelegate] Trigger [%s] on change", storeId.c_str()); observer->OnChange(data); - LOGI("[KvStoreNbDelegate] End trigger on change"); }, errCode); @@ -437,16 +441,22 @@ DBStatus KvStoreNbDelegateImpl::RegisterCloudObserver(const Key &key, unsigned i } std::lock_guard lockGuard(observerMapLock_); + if (cloudObserverMap_.size() >= DBConstant::MAX_OBSERVER_COUNT) { + LOGE("[KvStoreNbDelegate] The number of kv cloud observers has been over limit, storeId[%.3s]", + storeId_.c_str()); + return OVER_MAX_LIMITS; + } if (cloudObserverMap_.find(observer) != cloudObserverMap_.end() && cloudObserverMap_[observer] == mode) { LOGE("[KvStoreNbDelegate] Cloud observer has been already registered!"); return ALREADY_SET; } - ObserverAction action = [observer](const std::string &device, ChangedData &&changedData, bool isChangedData) { + auto storeId = storeId_; + ObserverAction action = [observer, storeId]( + const std::string &device, ChangedData &&changedData, bool isChangedData) { if (isChangedData) { - LOGI("[KvStoreNbDelegate] Begin trigger on change"); + LOGD("[KvStoreNbDelegate] Trigger [%s] on change", storeId.c_str()); observer->OnChange(Origin::ORIGIN_CLOUD, device, std::move(changedData)); - LOGI("[KvStoreNbDelegate] End trigger on change"); } }; int errCode = conn_->RegisterObserverAction(observer, action); @@ -578,8 +588,8 @@ DBStatus KvStoreNbDelegateImpl::Sync(const std::vector &devices, Sy return NOT_SUPPORT; } QuerySyncObject querySyncObj(query); - if (querySyncObj.GetSortType() != SortType::NONE) { - LOGE("not support order by timestamp"); + if (querySyncObj.GetSortType() != SortType::NONE || querySyncObj.IsQueryByRange()) { + LOGE("not support order by timestamp and query by range"); return NOT_SUPPORT; } PragmaSync pragmaData(devices, mode, querySyncObj, std::bind(&KvStoreNbDelegateImpl::OnSyncComplete, @@ -850,7 +860,10 @@ DBStatus KvStoreNbDelegateImpl::GetInner(const IOption &option, const Key &key, if (errCode == E_OK) { return OK; } - LOGW("[KvStoreNbDelegate] [%s] Get the data failed:%d", storeId_.c_str(), errCode); + + if (errCode != -E_NOT_FOUND) { + LOGW("[KvStoreNbDelegate] [%s] Get the data failed:%d", storeId_.c_str(), errCode); + } return TransferDBErrno(errCode); } @@ -966,7 +979,7 @@ DBStatus KvStoreNbDelegateImpl::SubscribeRemoteQuery(const std::vectorUpdateKey(callback); @@ -1133,7 +1147,7 @@ DBStatus KvStoreNbDelegateImpl::RemoveDeviceData(const std::string &device, Clea return DB_ERROR; } if (mode == ClearMode::DEFAULT) { - return RemoveDeviceData(device); + return device.empty() ? RemoveDeviceData() : RemoveDeviceData(device); } int errCode = conn_->RemoveDeviceData(device, mode); LOGI("[KvStoreNbDelegateImpl] remove device data res %d", errCode); @@ -1148,7 +1162,11 @@ DBStatus KvStoreNbDelegateImpl::RemoveDeviceData(const std::string &device, cons return DB_ERROR; } if (mode == ClearMode::DEFAULT) { - return RemoveDeviceData(device); + return device.empty() ? RemoveDeviceData() : RemoveDeviceData(device); + } + if (user.empty()) { + LOGE("[KvStoreNbDelegateImpl] remove device data with empty user!"); + return INVALID_ARGS; } int errCode = conn_->RemoveDeviceData(device, user, mode); LOGI("[KvStoreNbDelegateImpl] remove device data with user res %d", errCode); @@ -1167,6 +1185,7 @@ int32_t KvStoreNbDelegateImpl::GetTaskCount() void KvStoreNbDelegateImpl::SetGenCloudVersionCallback(const GenerateCloudVersionCallback &callback) { if (conn_ == nullptr || callback == nullptr) { + LOGD("[KvStoreNbDelegate] Invalid connection or callback for operation"); return; } conn_->SetGenCloudVersionCallback(callback); @@ -1192,7 +1211,49 @@ std::pair> KvStoreNbDelegateImpl::G } else { LOGE("[KvStoreNbDelegate] get cloudVersion failed:%d", errCode); } + if (res.second.empty()) { + errCode = -E_NOT_FOUND; + } res.first = TransferDBErrno(errCode); return res; } + +DBStatus KvStoreNbDelegateImpl::SetReceiveDataInterceptor(const DataInterceptor &interceptor) +{ + if (conn_ == nullptr) { + LOGE("%s", INVALID_CONNECTION); + return DB_ERROR; + } + int errCode = conn_->SetReceiveDataInterceptor(interceptor); + LOGI("[KvStoreNbDelegate] Set receive data interceptor errCode:%d", errCode); + return TransferDBErrno(errCode); +} + +DBStatus KvStoreNbDelegateImpl::SetCloudSyncConfig(const CloudSyncConfig &config) +{ + if (conn_ == nullptr) { + LOGE("%s", INVALID_CONNECTION); + return DB_ERROR; + } + if (!DBCommon::CheckCloudSyncConfigValid(config)) { + return INVALID_ARGS; + } + int errCode = conn_->SetCloudSyncConfig(config); + LOGI("[KvStoreNbDelegate] Set cloud sync config errCode:%d", errCode); + return TransferDBErrno(errCode); +} + +DBStatus KvStoreNbDelegateImpl::GetDeviceEntries(const std::string &device, std::vector &entries) const +{ + if (conn_ == nullptr) { + LOGE("%s", INVALID_CONNECTION); + return DB_ERROR; + } + int errCode = conn_->GetEntries(device, entries); + if (errCode == E_OK) { + return OK; + } + LOGE("[KvStoreNbDelegate] Get the entries failed:%d", errCode); + return TransferDBErrno(errCode); +} } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_nb_delegate_impl.h b/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_nb_delegate_impl.h index c2e5ba71..4f46f85c 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_nb_delegate_impl.h +++ b/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_nb_delegate_impl.h @@ -73,8 +73,7 @@ public: DBStatus UnpublishToLocal(const Key &key, bool deletePublic, bool updateTimestamp) override; // Observer interfaces - DBStatus RegisterObserver(const Key &key, unsigned int mode, KvStoreObserver *observer) override - __attribute__((no_sanitize("cfi"))); + DBStatus RegisterObserver(const Key &key, unsigned int mode, KvStoreObserver *observer) override; DBStatus UnRegisterObserver(const KvStoreObserver *observer) override; @@ -177,6 +176,12 @@ public: void SetGenCloudVersionCallback(const GenerateCloudVersionCallback &callback) override; std::pair> GetCloudVersion(const std::string &device) override; + + DBStatus SetReceiveDataInterceptor(const DataInterceptor &interceptor) override; + + DBStatus SetCloudSyncConfig(const CloudSyncConfig &config) override; + + DBStatus GetDeviceEntries(const std::string &device, std::vector &entries) const override; private: DBStatus GetInner(const IOption &option, const Key &key, Value &value) const; DBStatus PutInner(const IOption &option, const Key &key, const Value &value); diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_result_set_impl.cpp b/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_result_set_impl.cpp index cdbb0f20..d3e6752d 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_result_set_impl.cpp +++ b/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_result_set_impl.cpp @@ -153,13 +153,11 @@ bool KvStoreResultSetImpl::IsClosed() const void KvStoreResultSetImpl::Close() { - return; } void KvStoreResultSetImpl::GetColumnNames(std::vector &columnNames) const { (void)columnNames; - return; } DBStatus KvStoreResultSetImpl::GetColumnType(int columnIndex, ColumnType &columnType) const diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.cpp b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.cpp index 5d87b56e..cbb0da6a 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.cpp +++ b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.cpp @@ -399,6 +399,7 @@ DBStatus RelationalStoreDelegateImpl::SetReference(const std::vectorSetCloudSyncConfig(config); + if (errCode != E_OK) { + LOGE("[RelationalStore Delegate] SetCloudSyncConfig failed:%d", errCode); + return TransferDBErrno(errCode); + } + LOGI("[RelationalStore Delegate] SetCloudSyncConfig success"); + return OK; +} } // namespace DistributedDB #endif \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.h b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.h index 527ea646..173defd3 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 @@ -79,6 +79,8 @@ public: DBStatus UpsertData(const std::string &tableName, const std::vector &records, RecordStatus status) override; + + DBStatus SetCloudSyncConfig(const CloudSyncConfig &config) override; private: static void OnSyncComplete(const std::map> &devicesStatus, const SyncStatusCallback &onComplete); diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_manager.cpp b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_manager.cpp index 036602af..c44882b4 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_manager.cpp +++ b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_manager.cpp @@ -46,6 +46,14 @@ RelationalStoreManager::RelationalStoreManager(const std::string &appId, const s instanceId_(instanceId) {} +RelationalStoreManager::RelationalStoreManager(const std::string &appId, const std::string &userId, + const std::string &subUser, int32_t instanceId) + : appId_(appId), + userId_(userId), + subUser_(subUser), + instanceId_(instanceId) +{} + static RelationalStoreConnection *GetOneConnectionWithRetry(const RelationalDBProperties &properties, int &errCode) { for (int i = 0; i < GET_CONNECT_RETRY; i++) { @@ -74,7 +82,7 @@ bool RelationalStoreManager::PreCheckOpenStore(const std::string &path, const st return false; } - if (!ParamCheckUtils::CheckStoreParameter(storeId, appId_, userId_) || path.empty()) { + if (!ParamCheckUtils::CheckStoreParameter(storeId, appId_, userId_, false, subUser_) || path.empty()) { return false; } @@ -91,7 +99,7 @@ DB_API DBStatus RelationalStoreManager::OpenStore(const std::string &path, const RelationalDBProperties properties; properties.SetStringProp(RelationalDBProperties::DATA_DIR, canonicalDir); - properties.SetIdentifier(userId_, appId_, storeId, instanceId_); + properties.SetIdentifier(userId_, appId_, storeId, subUser_, instanceId_); properties.SetBoolProp(RelationalDBProperties::SYNC_DUAL_TUPLE_MODE, option.syncDualTupleMode); if (option.isEncryptedDb) { if (!ParamCheckUtils::CheckEncryptedParameter(option.cipher, option.passwd) || option.iterateTimes == 0) { @@ -102,9 +110,6 @@ DB_API DBStatus RelationalStoreManager::OpenStore(const std::string &path, const int errCode = E_OK; auto *conn = GetOneConnectionWithRetry(properties, errCode); - if (errCode == -E_INVALID_PASSWD_OR_CORRUPTED_DB) { - DBDfxAdapter::ReportFault( { DBDfxAdapter::EVENT_OPEN_DATABASE_FAILED, userId_, appId_, storeId, errCode } ); - } if (conn == nullptr) { return TransferDBErrno(errCode); } 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 c82fda8b..6439f897 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 @@ -30,7 +30,6 @@ #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 @@ -750,7 +749,7 @@ void DataChangedObserver(sqlite3_context *ctx, int argc, sqlite3_value **argv) return; } std::string tableName = static_cast(tableNameChar); - auto columnNameChar = reinterpret_cast(sqlite3_value_text(argv[1])); // 1 is param index of column + auto columnNameChar = reinterpret_cast(sqlite3_value_text(argv[1])); // 1 is param index if (columnNameChar == nullptr) { return; } @@ -764,15 +763,15 @@ void DataChangedObserver(sqlite3_context *ctx, int argc, sqlite3_value **argv) return; } if (!isRowid && type == "TEXT") { - auto dataChar = reinterpret_cast(sqlite3_value_text(argv[2])); // 2 is param index of changed data + auto dataChar = reinterpret_cast(sqlite3_value_text(argv[2])); // 2 is param index if (dataChar == nullptr) { return; } data = static_cast(dataChar); } else { - data = static_cast(sqlite3_value_int64(argv[2])); // 2 is param index of data + data = static_cast(sqlite3_value_int64(argv[2])); // 2 is param index } - ChangeType option = static_cast(sqlite3_value_int64(argv[3])); // 3 is param index of option type + ChangeType option = static_cast(sqlite3_value_int64(argv[3])); // 3 is param index SaveChangedData(hashFileName, tableName, columnName, data, option); sqlite3_result_int64(ctx, static_cast(1)); // 1 is result ok } @@ -910,7 +909,7 @@ void ClientObserverCallback(const std::string &hashFileName) } } -void TriggerObserver(std::vector> storeObservers, const std::string &hashFileName) +void TriggerObserver(std::vector> &storeObservers, const std::string &hashFileName) { std::lock_guard storeChangedDataLock(g_storeChangedDataMutex); for (const auto &storeObserver : storeObservers) { @@ -930,9 +929,7 @@ void StoreObserverCallback(sqlite3 *db, const std::string &hashFileName) std::lock_guard storeObserverLock(g_storeObserverMutex); auto it = g_storeObserverMap.find(hashFileName); if (it != g_storeObserverMap.end() && !it->second.empty()) { - for (const auto &observer : it->second) { - storeObserver.push_back(observer); - } + std::copy(it->second.begin(), it->second.end(), std::back_inserter(storeObserver)); } else { return; } @@ -1280,8 +1277,17 @@ int HandleDropLogicDeleteData(sqlite3 *db, const std::string &tableName, uint64_ LOGE("delete logic deletedData failed. %d", errCode); return errCode; } - sql = "UPDATE " + logTblName + " SET data_key = -1, flag = (flag & ~0x08) | 0x01 WHERE flag&0x08=0x08" + - (cursor == 0 ? ";" : " AND cursor <= '" + std::to_string(cursor) + "';"); + std::string logTableVersion; + errCode = SQLiteUtils::GetLogTableVersion(db, logTableVersion); + if (errCode != E_OK && errCode != -E_NOT_FOUND) { + LOGE("get log table version failed. %d", errCode); + return errCode; + } + sql = "UPDATE " + logTblName + " SET data_key = -1, flag = (flag & ~0x08) | 0x01"; + if (logTableVersion >= DBConstant::LOG_TABLE_VERSION_5_3) { + sql += ", sharing_resource = ''"; + } + sql += " WHERE flag&0x08=0x08" + (cursor == 0 ? ";" : " AND cursor <= '" + std::to_string(cursor) + "';"); errCode = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr); if (errCode != SQLITE_OK) { LOGE("update logic deletedData failed. %d", errCode); @@ -1376,7 +1382,10 @@ bool CheckUnLockingDataExists(sqlite3 *db, const std::string &tableName) return false; } - bool isExists = ((sqlite3_step(stmt) == SQLITE_ROW) && (sqlite3_column_int(stmt, 0) > 0)); + bool isExists = false; + if ((sqlite3_step(stmt) == SQLITE_ROW) && (sqlite3_column_int(stmt, 0) > 0)) { + isExists = true; + } (void)sqlite3_finalize(stmt); return isExists; } @@ -1675,9 +1684,9 @@ DB_API DistributedDB::DBStatus UnregisterStoreObserver(sqlite3 *db, const std::s auto it = g_storeObserverMap.find(hashFileName); if (it != g_storeObserverMap.end()) { it->second.remove(storeObserver); - } - if (it->second.empty()) { - g_storeObserverMap.erase(it); + if (it->second.empty()) { + g_storeObserverMap.erase(it); + } } return DistributedDB::OK; @@ -1698,10 +1707,6 @@ DB_API DistributedDB::DBStatus UnregisterStoreObserver(sqlite3 *db) return DistributedDB::DB_ERROR; } - if (errCode != DistributedDB::DBStatus::OK) { - return DistributedDB::DB_ERROR; - } - std::lock_guard lock(g_storeObserverMutex); auto it = g_storeObserverMap.find(hashFileName); if (it != g_storeObserverMap.end()) { diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_sync_able_storage.h b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_sync_able_storage.h index 267fee90..154a9cb9 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 @@ -101,7 +101,7 @@ public: int LocalDataChanged(int notifyEvent, std::vector &queryObj) override; int InterceptData(std::vector &entries, const std::string &sourceID, - const std::string &targetID) const override; + const std::string &targetID, bool isPush) const override; int CheckAndInitQueryCondition(QueryObject &query) const override; int RegisterObserverAction(uint64_t connectionId, const StoreObserver *observer, @@ -214,11 +214,17 @@ public: void SyncFinishHook() override; - int SetSyncFinishHook(const std::function &func) override; + void SetSyncFinishHook(const std::function &func) override; void SetDoUploadHook(const std::function &) override; void DoUploadHook() override; + + CloudSyncConfig GetCloudSyncConfig() const override; + + void SetCloudSyncConfig(const CloudSyncConfig &config); + + bool IsTableExistReference(const std::string &table) override; protected: int FillReferenceData(CloudSyncData &syncData); @@ -281,13 +287,13 @@ private: 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); - int CreateTempSyncTriggerInner(SQLiteSingleVerRelationalStorageExecutor *handle, const std::string &tableName); + bool CheckTableSupportCompensatedSync(const TableSchema &table); + void ExecuteDataChangeCallback( - const std::pair> &item, int &observerCnt, - const std::string &deviceName, const ChangedData &changedData, bool isChangedData); + const std::pair> &item, + const std::string &deviceName, const ChangedData &changedData, bool isChangedData, int &observerCnt); // data std::shared_ptr storageEngine_ = nullptr; std::function onSchemaChanged_; @@ -318,6 +324,9 @@ private: std::function syncFinishFunc_; std::function uploadStartFunc_; + + mutable std::mutex configMutex_; + CloudSyncConfig cloudSyncConfig_; }; } // namespace DistributedDB #endif diff --git a/kv_store/frameworks/libs/distributeddb/storage/include/cloud/cloud_storage_utils.h b/kv_store/frameworks/libs/distributeddb/storage/include/cloud/cloud_storage_utils.h index 8cac9ad5..abf5d168 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/include/cloud/cloud_storage_utils.h +++ b/kv_store/frameworks/libs/distributeddb/storage/include/cloud/cloud_storage_utils.h @@ -152,16 +152,16 @@ public: static int CalculateHashKeyForOneField(const Field &field, const VBucket &vBucket, bool allowEmpty, CollateType collateType, std::vector &hashValue); + static bool CheckCloudSchemaFields(const TableSchema &tableSchema, const TableSchema &oldSchema); + static void TransferFieldToLower(VBucket &vBucket); static bool GetTypeCaseInsensitive(const std::string &fieldName, const VBucket &vBucket, Type &data); - static bool CheckCloudSchemaFields(const TableSchema &tableSchema, const TableSchema &oldSchema); - static int BindUpdateLogStmtFromVBucket(const VBucket &vBucket, const TableSchema &tableSchema, const std::vector &colNames, sqlite3_stmt *updateLogStmt); - static bool IsGetCloudDataContinue(uint32_t curNum, uint32_t curSize, uint32_t maxSize); + static bool IsGetCloudDataContinue(uint32_t curNum, uint32_t curSize, uint32_t maxSize, uint32_t maxCount); static int IdentifyCloudType(CloudSyncData &cloudSyncData, VBucket &data, VBucket &log, VBucket &flags); diff --git a/kv_store/frameworks/libs/distributeddb/storage/include/db_properties.h b/kv_store/frameworks/libs/distributeddb/storage/include/db_properties.h index aa944c69..716343cb 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/include/db_properties.h +++ b/kv_store/frameworks/libs/distributeddb/storage/include/db_properties.h @@ -36,15 +36,21 @@ public: // Set the bool property for the name void SetBoolProp(const std::string &name, bool value); - // Get the bool property according the name + // Get the integer property according the name int GetIntProp(const std::string &name, int defaultValue) const; // Set the integer property for the name void SetIntProp(const std::string &name, int value); + // Get the unsigned integer property according the name + uint32_t GetUIntProp(const std::string &name, uint32_t defaultValue) const; + + // Set the unsigned integer property for the name + void SetUIntProp(const std::string &name, uint32_t value); + // Set all indentifers void SetIdentifier(const std::string &userId, const std::string &appId, const std::string &storeId, - int32_t instanceId = 0); + const std::string &subUser = "", int32_t instanceId = 0); static const std::string CREATE_IF_NECESSARY; static const std::string DATABASE_TYPE; @@ -53,6 +59,7 @@ public: static const std::string APP_ID; static const std::string STORE_ID; static const std::string INSTANCE_ID; + static const std::string SUB_USER; static const std::string IDENTIFIER_DATA; static const std::string IDENTIFIER_DIR; static const std::string DUAL_TUPLE_IDENTIFIER_DATA; @@ -64,6 +71,7 @@ protected: std::map stringProperties_; std::map boolProperties_; std::map intProperties_; + std::map uintProperties_; }; } #endif \ No newline at end of file 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 8fee952e..3cfb7139 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 @@ -57,9 +57,8 @@ public: ICloudSyncStorageHook() = default; virtual ~ICloudSyncStorageHook() = default; - virtual int SetSyncFinishHook(const std::function &) + virtual void SetSyncFinishHook(const std::function &) { - return E_OK; } virtual void SyncFinishHook() @@ -195,6 +194,13 @@ public: { return {E_OK, {}}; } + + virtual CloudSyncConfig GetCloudSyncConfig() const = 0; + + virtual bool IsTableExistReference(const std::string &table) + { + return false; + } }; } diff --git a/kv_store/frameworks/libs/distributeddb/storage/include/ikvdb_connection.h b/kv_store/frameworks/libs/distributeddb/storage/include/ikvdb_connection.h index 6a5bc83b..fde488cb 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/include/ikvdb_connection.h +++ b/kv_store/frameworks/libs/distributeddb/storage/include/ikvdb_connection.h @@ -23,6 +23,7 @@ #include "cloud/icloud_db.h" #include "db_types.h" #include "iconnection.h" +#include "intercepted_data.h" #include "kv_store_observer.h" #include "macro_utils.h" #include "query.h" @@ -158,6 +159,12 @@ public: virtual void SetGenCloudVersionCallback(const GenerateCloudVersionCallback &callback) = 0; virtual int GetCloudVersion(const std::string &device, std::map &versionMap) = 0; + + virtual int SetReceiveDataInterceptor(const DataInterceptor &interceptor) = 0; + + virtual int SetCloudSyncConfig(const CloudSyncConfig &config) = 0; + + virtual int GetEntries(const std::string &device, std::vector &entries) const = 0; }; } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/storage/include/relational_store_connection.h b/kv_store/frameworks/libs/distributeddb/storage/include/relational_store_connection.h index fe812ae3..b7017feb 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/include/relational_store_connection.h +++ b/kv_store/frameworks/libs/distributeddb/storage/include/relational_store_connection.h @@ -80,6 +80,8 @@ public: virtual int Pragma(PragmaCmd cmd, PragmaData &pragmaData) = 0; virtual int UpsertData(RecordStatus status, const std::string &tableName, const std::vector &records) = 0; + + virtual int SetCloudSyncConfig(const CloudSyncConfig &config) = 0; protected: // Get the stashed 'RelationalDB_ pointer' without ref. template 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 1effc027..761422db 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/include/storage_proxy.h +++ b/kv_store/frameworks/libs/distributeddb/storage/include/storage_proxy.h @@ -61,7 +61,7 @@ public: int64_t &count); int GetUploadCount(const QuerySyncObject &query, const bool isCloudForcePush, bool isCompensatedTask, - bool isPriorityTask, int64_t &count); + bool isUseWaterMark, int64_t &count); int GetUploadCount(const QuerySyncObject &query, const Timestamp &localMark, bool isCloudForcePush, bool isCompensatedTask, int64_t &count); @@ -143,6 +143,10 @@ public: int GetCloudDbSchema(std::shared_ptr &cloudSchema); std::pair GetLocalCloudVersion(); + + CloudSyncConfig GetCloudSyncConfig() const; + + bool IsTableExistReference(const std::string &table); protected: void Init(); diff --git a/kv_store/frameworks/libs/distributeddb/storage/include/sync_generic_interface.h b/kv_store/frameworks/libs/distributeddb/storage/include/sync_generic_interface.h index 759aaad9..4e908a4e 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/include/sync_generic_interface.h +++ b/kv_store/frameworks/libs/distributeddb/storage/include/sync_generic_interface.h @@ -111,7 +111,7 @@ public: } virtual int InterceptData(std::vector &entries, const std::string &sourceID, - const std::string &targetID) const + const std::string &targetID, bool isPush) const { return -E_NOT_SUPPORT; } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/cloud/cloud_storage_utils.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/cloud/cloud_storage_utils.cpp index 77d4aa6a..129b701c 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/cloud/cloud_storage_utils.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/cloud/cloud_storage_utils.cpp @@ -1024,11 +1024,28 @@ std::pair> CloudStorageUtils::GetHashValueWithPrimaryK return { errCode, hashValue }; } +bool CloudStorageUtils::CheckCloudSchemaFields(const TableSchema &tableSchema, const TableSchema &oldSchema) +{ + if (tableSchema.name != oldSchema.name) { + return true; + } + for (const auto &oldField : oldSchema.fields) { + auto it = std::find_if(tableSchema.fields.begin(), tableSchema.fields.end(), + [&oldField](const std::vector::value_type &field) { + return oldField == field; + }); + if (it == tableSchema.fields.end()) { + return false; + } + } + return true; +} + void CloudStorageUtils::TransferFieldToLower(VBucket &vBucket) { for (auto it = vBucket.begin(); it != vBucket.end();) { std::string lowerField(it->first.length(), ' '); - std::transform(it->first.begin(), it->first.end(), lowerField.begin(), tolower); + std::transform(it->first.begin(), it->first.end(), lowerField.begin(), ::tolower); if (lowerField != it->first) { vBucket[lowerField] = std::move(vBucket[it->first]); vBucket.erase(it++); @@ -1042,7 +1059,7 @@ bool CloudStorageUtils::GetTypeCaseInsensitive(const std::string &fieldName, con { auto tmpFieldName = fieldName; auto tmpVBucket = vBucket; - std::transform(tmpFieldName.begin(), tmpFieldName.end(), tmpFieldName.begin(), tolower); + std::transform(tmpFieldName.begin(), tmpFieldName.end(), tmpFieldName.begin(), ::tolower); TransferFieldToLower(tmpVBucket); auto it = tmpVBucket.find(tmpFieldName); if (it == tmpVBucket.end()) { @@ -1052,23 +1069,6 @@ bool CloudStorageUtils::GetTypeCaseInsensitive(const std::string &fieldName, con return true; } -bool CloudStorageUtils::CheckCloudSchemaFields(const TableSchema &tableSchema, const TableSchema &oldSchema) -{ - if (tableSchema.name != oldSchema.name) { - return true; - } - for (const auto &oldField : oldSchema.fields) { - auto it = std::find_if(tableSchema.fields.begin(), tableSchema.fields.end(), - [&oldField](const std::vector::value_type &field) { - return oldField == field; - }); - if (it == tableSchema.fields.end()) { - return false; - } - } - return true; -} - int CloudStorageUtils::BindUpdateLogStmtFromVBucket(const VBucket &vBucket, const TableSchema &tableSchema, const std::vector &colNames, sqlite3_stmt *updateLogStmt) { @@ -1195,20 +1195,14 @@ bool CloudStorageUtils::IsCloudGidMismatch(const std::string &downloadGid, const return !downloadGid.empty() && !curGid.empty() && downloadGid != curGid; } -bool CloudStorageUtils::IsGetCloudDataContinue(uint32_t curNum, uint32_t curSize, uint32_t maxSize) +bool CloudStorageUtils::IsGetCloudDataContinue(uint32_t curNum, uint32_t curSize, uint32_t maxSize, uint32_t maxCount) { if (curNum == 0) { return true; } -#ifdef MAX_UPLOAD_COUNT - if (curSize < maxSize && curNum < MAX_UPLOAD_COUNT) { + if (curSize < maxSize && curNum < maxCount) { return true; } -#else - if (curSize < maxSize) { - return true; - } -#endif return false; } @@ -1222,7 +1216,9 @@ int CloudStorageUtils::IdentifyCloudType(CloudSyncData &cloudSyncData, VBucket & if (rowid == nullptr || flag == nullptr || timeStamp == nullptr || hashKey == nullptr) { return -E_INVALID_DATA; } - if (status != nullptr && CloudStorageUtils::IsDataLocked(*status)) { + bool isDelete = ((static_cast(*flag) & DataItem::DELETE_FLAG) != 0); + bool isInsert = (!isDelete) && (log.find(CloudDbConstant::GID_FIELD) == log.end()); + if (status != nullptr && !isInsert && (CloudStorageUtils::IsDataLocked(*status))) { cloudSyncData.ignoredCount++; cloudSyncData.lockData.extend.push_back(log); cloudSyncData.lockData.hashKey.push_back(*hashKey); @@ -1230,14 +1226,13 @@ int CloudStorageUtils::IdentifyCloudType(CloudSyncData &cloudSyncData, VBucket & cloudSyncData.lockData.rowid.push_back(*rowid); return -E_IGNORE_DATA; } - if ((static_cast(*flag) & DataItem::DELETE_FLAG) != 0) { + if (isDelete) { cloudSyncData.delData.record.push_back(data); cloudSyncData.delData.extend.push_back(log); cloudSyncData.delData.hashKey.push_back(*hashKey); cloudSyncData.delData.timestamp.push_back(*timeStamp); cloudSyncData.delData.rowid.push_back(*rowid); } else { - bool isInsert = (log.find(CloudDbConstant::GID_FIELD) == log.end()); if (data.empty()) { LOGE("The cloud data is empty, isInsert:%d", isInsert); return -E_INVALID_DATA; @@ -1306,7 +1301,7 @@ std::pair CloudStorageUtils::GetDataItemFromCloudData(VBucket &da if (isSystemRecord) { dataItem.hashKey = dataItem.key; dataItem.flag |= static_cast(LogInfoFlag::FLAG_SYSTEM_RECORD); - } else { + } else if (!dataItem.key.empty()) { (void)DBCommon::CalcValueHash(dataItem.key, dataItem.hashKey); } return res; @@ -1318,8 +1313,7 @@ std::pair CloudStorageUtils::GetDataItemFromCloudVersionData(VBuc auto &[errCode, dataItem] = res; GetBytesFromCloudData(CloudDbConstant::CLOUD_KV_FIELD_KEY, data, dataItem.key); GetBytesFromCloudData(CloudDbConstant::CLOUD_KV_FIELD_VALUE, data, dataItem.value); - GetStringFromCloudData(CloudDbConstant::CLOUD_KV_FIELD_DEVICE, data, dataItem.dev); - errCode = E_OK; + errCode = GetStringFromCloudData(CloudDbConstant::CLOUD_KV_FIELD_DEVICE, data, dataItem.dev); return res; } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/cloud/schema_mgr.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/cloud/schema_mgr.cpp index e832d84d..a912637b 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/cloud/schema_mgr.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/cloud/schema_mgr.cpp @@ -18,6 +18,7 @@ #include #include "cloud/cloud_db_constant.h" +#include "cloud/cloud_storage_utils.h" #include "cloud/cloud_store_types.h" #include "cloud/cloud_storage_utils.h" #include "db_common.h" diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/db_properties.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/db_properties.cpp index 5e7e6dac..c86aa900 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/db_properties.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/db_properties.cpp @@ -23,6 +23,7 @@ const std::string DBProperties::USER_ID = "userId"; const std::string DBProperties::APP_ID = "appId"; const std::string DBProperties::STORE_ID = "storeId"; const std::string DBProperties::INSTANCE_ID = "instanceId"; +const std::string DBProperties::SUB_USER = "subUser"; const std::string DBProperties::IDENTIFIER_DATA = "identifier"; const std::string DBProperties::IDENTIFIER_DIR = "identifierDir"; const std::string DBProperties::DUAL_TUPLE_IDENTIFIER_DATA = "dualTupleIdentifier"; @@ -73,15 +74,30 @@ void DBProperties::SetIntProp(const std::string &name, int value) intProperties_[name] = value; } +uint32_t DBProperties::GetUIntProp(const std::string &name, uint32_t defaultValue) const +{ + auto iter = uintProperties_.find(name); + if (iter != uintProperties_.end()) { + return iter->second; + } + return defaultValue; +} + +void DBProperties::SetUIntProp(const std::string &name, uint32_t value) +{ + uintProperties_[name] = value; +} + void DBProperties::SetIdentifier(const std::string &userId, const std::string &appId, const std::string &storeId, - int32_t instanceId) + const std::string &subUser, int32_t instanceId) { SetStringProp(DBProperties::APP_ID, appId); SetStringProp(DBProperties::USER_ID, userId); SetStringProp(DBProperties::STORE_ID, storeId); + SetStringProp(DBProperties::SUB_USER, subUser); SetIntProp(DBProperties::INSTANCE_ID, instanceId); std::string hashIdentifier = DBCommon::TransferHashString( - DBCommon::GenerateIdentifierId(storeId, appId, userId, instanceId)); + DBCommon::GenerateIdentifierId(storeId, appId, userId, subUser, instanceId)); SetStringProp(DBProperties::IDENTIFIER_DATA, hashIdentifier); std::string dualIdentifier = DBCommon::TransferHashString(DBCommon::GenerateDualTupleIdentifierId(storeId, appId)); SetStringProp(DBProperties::DUAL_TUPLE_IDENTIFIER_DATA, dualIdentifier); 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 bcb59af7..3c0b905c 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 @@ -21,6 +21,8 @@ namespace DistributedDB { RdSingleVerNaturalStore::RdSingleVerNaturalStore() + : storageEngine_(nullptr), + notificationEventsRegistered_(false) { LOGD("RdSingleVerNaturalStore Created"); } @@ -377,7 +379,7 @@ int RdSingleVerNaturalStore::GetCompressionAlgo(std::set &alg return -E_NOT_SUPPORT; } -void RdSingleVerNaturalStore::SetDataInterceptor(const PushDataInterceptor &interceptor) +void RdSingleVerNaturalStore::SetSendDataInterceptor(const PushDataInterceptor &interceptor) { return; } @@ -429,7 +431,9 @@ void RdSingleVerNaturalStore::InitDataBaseOption(const KvDBProperties &kvDBProp, std::string config = "{"; config += InitRdConfig() + R"(, )"; - config += R"("pageSize":)" + std::to_string(pageSize) + R"(, )"; + config += option.isHashTable ? + R"("bufferPoolPolicy": "BUF_PRIORITY_NORMAL")" : R"("bufferPoolPolicy": "BUF_PRIORITY_INDEX")"; + config += R"(, "pageSize":)" + std::to_string(pageSize) + R"(, )"; config += R"("bufferPoolSize":)" + std::to_string(cacheSize) + R"(, )"; config += R"("redoPubBufSize":)" + std::to_string(cacheSize) + R"(, )"; config += isSharedMode ? R"("sharedModeEnable": 1)" : R"("sharedModeEnable": 0)"; @@ -437,4 +441,7 @@ void RdSingleVerNaturalStore::InitDataBaseOption(const KvDBProperties &kvDBProp, option.rdConfig = config; } +void RdSingleVerNaturalStore::SetReceiveDataInterceptor(const DataInterceptor &interceptor) +{ +} } // namespace DistributedDB 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 e364e93e..61c62fc2 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 @@ -129,7 +129,7 @@ public: int GetCompressionAlgo(std::set &algorithmSet) const override; - void SetDataInterceptor(const PushDataInterceptor &interceptor) override; + void SetSendDataInterceptor(const PushDataInterceptor &interceptor) override; int SetMaxLogSize(uint64_t limit); @@ -141,6 +141,8 @@ public: void CommitNotify(int notifyEvent, KvDBCommitNotifyFilterAbleData *data) override; + void SetReceiveDataInterceptor(const DataInterceptor &interceptor) override; + private: int GetAndInitStorageEngine(const KvDBProperties &kvDBProp); 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 05924902..aa79170b 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 @@ -50,7 +50,7 @@ namespace DistributedDB { std::string InitRdConfig() { - return R"("redoFlushByTrx": 1, "maxConnNum": 100, "crcCheckEnable": 0, "bufferPoolPolicy": "BUF_PRIORITY_INDEX")"; + return R"("redoFlushByTrx": 1, "maxConnNum": 100, "crcCheckEnable": 0)"; } struct GrdErrnoPair { diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/kv/generic_kvdb_connection.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/kv/generic_kvdb_connection.cpp index 3c3c1f76..29bdee3a 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/kv/generic_kvdb_connection.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/kv/generic_kvdb_connection.cpp @@ -371,6 +371,12 @@ int GenericKvDBConnection::GetWatermarkInfo([[gnu::unused]] const std::string &d return -E_NOT_SUPPORT; } +bool GenericKvDBConnection::IsObserverEmpty() +{ + std::lock_guard lockGuard(observerListLock_); + return observerList_.empty(); +} + int GenericKvDBConnection::Sync([[gnu::unused]] const CloudSyncOption &option, [[gnu::unused]] const SyncProcessCallback &onProcess) { @@ -424,4 +430,19 @@ int GenericKvDBConnection::GetCloudVersion(const std::string &device, std::map &entries) const +{ + return -E_NOT_SUPPORT; +} } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/kv/generic_kvdb_connection.h b/kv_store/frameworks/libs/distributeddb/storage/src/kv/generic_kvdb_connection.h index cb45e5ff..833367f0 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/kv/generic_kvdb_connection.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/kv/generic_kvdb_connection.h @@ -102,6 +102,12 @@ public: void SetGenCloudVersionCallback(const GenerateCloudVersionCallback &callback) override; int GetCloudVersion(const std::string &device, std::map &versionMap) override; + + int SetReceiveDataInterceptor(const DataInterceptor &interceptor) override; + + int SetCloudSyncConfig(const CloudSyncConfig &config) override; + + int GetEntries(const std::string &device, std::vector &entries) const override; protected: // Get the stashed 'KvDB_ pointer' without ref. template @@ -118,6 +124,8 @@ protected: void ResetExclusiveStatus(); + bool IsObserverEmpty(); + // Called in Close(), overriding of Close() is forbidden. virtual int PreClose(); diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/kv/kvdb_manager.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/kv/kvdb_manager.cpp index 5fa23a53..c9246b9c 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/kv/kvdb_manager.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/kv/kvdb_manager.cpp @@ -16,6 +16,7 @@ #include "kvdb_manager.h" #include "log_print.h" #include "db_common.h" +#include "db_dfx_adapter.h" #include "runtime_context.h" #include "schema_object.h" #include "default_factory.h" @@ -328,15 +329,21 @@ IKvDBConnection *KvDBManager::GetDatabaseConnection(const KvDBProperties &proper IKvDB *kvDB = manager->GetDataBase(properties, errCode, isNeedIfOpened); if (kvDB == nullptr) { if (isNeedIfOpened) { + DBDfxAdapter::ReportBehavior( + {__func__, Scene::OPEN_CONN, State::END, Stage::GET_DB, StageResult::FAIL, errCode}); LOGE("Failed to open the db:%d", errCode); } } else { if (!CheckOpenDBOptionWithCached(properties, kvDB)) { LOGE("Failed to check open db option"); errCode = -E_INVALID_ARGS; + DBDfxAdapter::ReportBehavior( + {__func__, Scene::OPEN_CONN, State::END, Stage::CHECK_OPT, StageResult::FAIL, errCode}); } else { connection = kvDB->GetDBConnection(errCode); if (connection == nullptr) { // not kill kvdb, Other operations like import may be used concurrently + DBDfxAdapter::ReportBehavior( + {__func__, Scene::OPEN_CONN, State::END, Stage::GET_DB_CONN, StageResult::FAIL, errCode}); LOGE("Failed to get the db connect for delegate:%d", errCode); } } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/kv/sync_able_kvdb.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/kv/sync_able_kvdb.cpp index 34ab5a05..2a34e7ac 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/kv/sync_able_kvdb.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/kv/sync_able_kvdb.cpp @@ -180,8 +180,6 @@ int SyncAbleKvDB::StartSyncerWithNoLock(bool isCheckSyncActive, bool isNeedActiv int errCode = syncer_.Initialize(syncInterface, isNeedActive); if (errCode == E_OK) { started_ = true; - } else { - LOGW("KvDB start syncer failed, err:'%d'.", errCode); } bool isSyncDualTupleMode = syncInterface->GetDbProperties().GetBoolProp(KvDBProperties::SYNC_DUAL_TUPLE_MODE, false); @@ -234,6 +232,7 @@ void SyncAbleKvDB::StopSyncerWithNoLock(bool isClosedOperation) } closed_ = isClosedOperation; if (!isClosedOperation && userChangeListener_ != nullptr) { + cloudSyncer_->StopAllTasks(); userChangeListener_->Drop(false); userChangeListener_ = nullptr; } @@ -452,7 +451,6 @@ int SyncAbleKvDB::GetSyncDataSize(const std::string &device, size_t &size) const bool SyncAbleKvDB::NeedStartSyncer() const { if (!RuntimeContext::GetInstance()->IsCommunicatorAggregatorValid()) { - LOGW("KvDB communicator not ready!"); return false; } // don't start when check callback got not active @@ -510,6 +508,9 @@ void SyncAbleKvDB::StartCloudSyncer() } cloudSyncer_ = new(std::nothrow) CloudSyncer(StorageProxy::GetCloudDb(cloudStorage), static_cast(conflictType)); + if (cloudSyncer_ == nullptr) { + LOGW("[SyncAbleKvDB][StartCloudSyncer] start cloud syncer and cloud syncer was not initialized"); + } } } @@ -533,6 +534,41 @@ void SyncAbleKvDB::FillSyncInfo(const CloudSyncOption &option, const SyncProcess info.mode = option.mode; info.users = option.users; info.lockAction = option.lockAction; + info.storeId = MyProp().GetStringProp(DBProperties::STORE_ID, ""); + info.merge = option.merge; +} + +int SyncAbleKvDB::CheckSyncOption(const CloudSyncOption &option, const CloudSyncer &syncer) +{ + if (option.users.empty()) { + LOGE("[SyncAbleKvDB][Sync] no user in sync option"); + return -E_INVALID_ARGS; + } + const std::map> &cloudDBs = syncer.GetCloudDB(); + if (cloudDBs.empty()) { + LOGE("[SyncAbleKvDB][Sync] not set cloud db"); + return -E_CLOUD_ERROR; + } + auto schemas = GetDataBaseSchemas(); + if (schemas.empty()) { + LOGE("[SyncAbleKvDB][Sync] not set cloud schema"); + return -E_CLOUD_ERROR; + } + for (const auto &user : option.users) { + if (cloudDBs.find(user) == cloudDBs.end()) { + LOGE("[SyncAbleKvDB][Sync] cloud db with invalid user: %s", user.c_str()); + return -E_INVALID_ARGS; + } + if (schemas.find(user) == schemas.end()) { + LOGE("[SyncAbleKvDB][Sync] cloud schema with invalid user: %s", user.c_str()); + return -E_SCHEMA_MISMATCH; + } + } + if (option.waitTime > DBConstant::MAX_SYNC_TIMEOUT || option.waitTime < DBConstant::INFINITE_WAIT) { + LOGE("[SyncAbleKvDB][Sync] invalid wait time of sync option: %lld", option.waitTime); + return -E_INVALID_ARGS; + } + return E_OK; } int SyncAbleKvDB::Sync(const CloudSyncOption &option, const SyncProcessCallback &onProcess) @@ -542,9 +578,14 @@ int SyncAbleKvDB::Sync(const CloudSyncOption &option, const SyncProcessCallback LOGE("[SyncAbleKvDB][Sync] cloud syncer was not initialized"); return -E_INVALID_DB; } + int errCode = CheckSyncOption(option, *syncer); + if (errCode != E_OK) { + RefObject::DecObjRef(syncer); + return errCode; + } CloudSyncer::CloudTaskInfo info; FillSyncInfo(option, onProcess, info); - int errCode = syncer->Sync(info); + errCode = syncer->Sync(info); RefObject::DecObjRef(syncer); return errCode; } @@ -553,7 +594,7 @@ int SyncAbleKvDB::SetCloudDB(const std::mapSetCloudDB(cloudDBs); @@ -565,7 +606,7 @@ int SyncAbleKvDB::CleanAllWaterMark() { auto syncer = GetAndIncCloudSyncer(); if (syncer == nullptr) { - LOGE("[SyncAbleKvDB][Sync] cloud syncer was not initialized"); + LOGE("[SyncAbleKvDB][CleanAllWaterMark] cloud syncer was not initialized"); return -E_INVALID_DB; } syncer->CleanAllWaterMark(); @@ -602,10 +643,15 @@ void SyncAbleKvDB::SetGenCloudVersionCallback(const GenerateCloudVersionCallback { auto cloudSyncer = GetAndIncCloudSyncer(); if (cloudSyncer == nullptr) { - LOGE("[SyncAbleKvDB][Sync] cloud syncer was not initialized"); + LOGE("[SyncAbleKvDB][SetGenCloudVersionCallback] cloud syncer was not initialized"); return; } cloudSyncer->SetGenCloudVersionCallback(callback); RefObject::DecObjRef(cloudSyncer); } + +std::map SyncAbleKvDB::GetDataBaseSchemas() +{ + return {}; +} } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/kv/sync_able_kvdb.h b/kv_store/frameworks/libs/distributeddb/storage/src/kv/sync_able_kvdb.h index 1f5223c8..116e1c00 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/kv/sync_able_kvdb.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/kv/sync_able_kvdb.h @@ -83,7 +83,7 @@ public: // Set an equal identifier for this database, After this called, send msg to the target will use this identifier int SetEqualIdentifier(const std::string &identifier, const std::vector &targets); - virtual void SetDataInterceptor(const PushDataInterceptor &interceptor) = 0; + virtual void SetSendDataInterceptor(const PushDataInterceptor &interceptor) = 0; void Dump(int fd) override; @@ -106,6 +106,8 @@ public: int32_t GetTaskCount(); void SetGenCloudVersionCallback(const GenerateCloudVersionCallback &callback); + + virtual void SetReceiveDataInterceptor(const DataInterceptor &interceptor) = 0; protected: virtual IKvDBSyncInterface *GetSyncInterface() = 0; @@ -138,6 +140,8 @@ protected: virtual ICloudSyncStorageInterface *GetICloudSyncInterface() const; int CleanAllWaterMark(); + + virtual std::map GetDataBaseSchemas(); private: int RegisterEventType(EventType type); @@ -148,6 +152,8 @@ private: void FillSyncInfo(const CloudSyncOption &option, const SyncProcessCallback &onProcess, CloudSyncer::CloudTaskInfo &info); + int CheckSyncOption(const CloudSyncOption &option, const CloudSyncer &syncer); + CloudSyncer *GetAndIncCloudSyncer(); SyncerProxy syncer_; diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/kv/sync_able_kvdb_connection.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/kv/sync_able_kvdb_connection.cpp index 2234a95a..48b82e88 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/kv/sync_able_kvdb_connection.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/kv/sync_able_kvdb_connection.cpp @@ -320,7 +320,7 @@ int SyncAbleKvDBConnection::SetPushDataInterceptor(const PushDataInterceptor &in if (kvDB == nullptr) { return -E_INVALID_CONNECTION; } - kvDB->SetDataInterceptor(interceptor); + kvDB->SetSendDataInterceptor(interceptor); return E_OK; } @@ -387,4 +387,14 @@ void SyncAbleKvDBConnection::SetGenCloudVersionCallback(const GenerateCloudVersi } kvDB->SetGenCloudVersionCallback(callback); } + +int SyncAbleKvDBConnection::SetReceiveDataInterceptor(const DataInterceptor &interceptor) +{ + auto kvDB = GetDB(); + if (kvDB == nullptr) { + return -E_INVALID_CONNECTION; + } + kvDB->SetReceiveDataInterceptor(interceptor); + return E_OK; +} } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/kv/sync_able_kvdb_connection.h b/kv_store/frameworks/libs/distributeddb/storage/src/kv/sync_able_kvdb_connection.h index 2916d93f..f624c868 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/kv/sync_able_kvdb_connection.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/kv/sync_able_kvdb_connection.h @@ -46,6 +46,8 @@ public: int32_t GetTaskCount() override; void SetGenCloudVersionCallback(const GenerateCloudVersionCallback &callback) override; + + int SetReceiveDataInterceptor(const DataInterceptor &interceptor) override; protected: int DisableManualSync(); diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/multiver/multi_ver_natural_store.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/multiver/multi_ver_natural_store.cpp index 8437cc75..82d89e4a 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/multiver/multi_ver_natural_store.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/multiver/multi_ver_natural_store.cpp @@ -1190,7 +1190,13 @@ int MultiVerNaturalStore::DeleteMetaDataByPrefixKey(const Key &keyPrefix) const return -E_NOT_SUPPORT; } -void MultiVerNaturalStore::SetDataInterceptor(const PushDataInterceptor &interceptor) +void MultiVerNaturalStore::SetSendDataInterceptor(const PushDataInterceptor &interceptor) +{ + (void)interceptor; + return; +} + +void MultiVerNaturalStore::SetReceiveDataInterceptor(const DataInterceptor &interceptor) { (void)interceptor; return; diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/multiver/multi_ver_natural_store.h b/kv_store/frameworks/libs/distributeddb/storage/src/multiver/multi_ver_natural_store.h index e2f005d9..58658faf 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/multiver/multi_ver_natural_store.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/multiver/multi_ver_natural_store.h @@ -156,7 +156,9 @@ public: int InitStorages(const KvDBProperties &kvDBProp, bool isChangeTag = false); - void SetDataInterceptor(const PushDataInterceptor &interceptor) override; + void SetSendDataInterceptor(const PushDataInterceptor &interceptor) override; + + void SetReceiveDataInterceptor(const DataInterceptor &interceptor) override; private: diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/operation/database_oper.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/operation/database_oper.cpp index 9d8528f9..22bebe67 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/operation/database_oper.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/operation/database_oper.cpp @@ -567,7 +567,7 @@ int DatabaseOper::ClearExportedTempFiles(const KvDBProperties &property) const int DatabaseOper::PackExportedDatabase(const std::string &fileDir, const std::string &packedFile, const KvDBProperties &property) const { - LOGI("Pack the exported database."); + LOGD("Pack the exported database."); int databaseType = property.GetIntProp(KvDBProperties::DATABASE_TYPE, KvDBProperties::SINGLE_VER_TYPE_SQLITE); FileInfo fileInfo = {static_cast(databaseType), deviceId_}; int errCode = PackageFile::PackageFiles(fileDir, packedFile, fileInfo); diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/operation/single_ver_database_oper.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/operation/single_ver_database_oper.cpp index a822d2e4..8983e7fc 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/operation/single_ver_database_oper.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/operation/single_ver_database_oper.cpp @@ -181,7 +181,7 @@ int SingleVerDatabaseOper::ExportMainDB(const std::string ¤tDir, const Cip CipherType cipherType; CipherPassword currPasswd; singleVerNaturalStore_->GetDbProperties().GetPassword(cipherType, currPasswd); - LOGI("Begin the sqlite main database export!"); + LOGD("Begin the sqlite main database export!"); int errCode = SQLiteUtils::ExportDatabase(currentDb, cipherType, currPasswd, backupDbName, passwd); if (errCode != E_OK) { LOGE("Export the database failed:%d", errCode); diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/relational/relational_store_instance.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/relational/relational_store_instance.cpp index f118dcc1..67cfce0a 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/relational/relational_store_instance.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/relational/relational_store_instance.cpp @@ -16,6 +16,7 @@ #include "relational_store_instance.h" #include "db_common.h" +#include "db_dfx_adapter.h" #include "db_errno.h" #include "sqlite_relational_store.h" #include "log_print.h" @@ -197,17 +198,23 @@ RelationalStoreConnection *RelationalStoreInstance::GetDatabaseConnection(const RelationalStoreConnection *connection = nullptr; IRelationalStore *db = GetDataBase(properties, errCode); if (db == nullptr) { + DBDfxAdapter::ReportBehavior( + {__func__, Scene::OPEN_CONN, State::BEGIN, Stage::GET_DB, StageResult::FAIL, errCode}); LOGE("Failed to open the db:%d", errCode); goto END; } errCode = CheckCompatibility(properties, db->GetProperties()); if (errCode != E_OK) { + DBDfxAdapter::ReportBehavior( + {__func__, Scene::OPEN_CONN, State::BEGIN, Stage::CHECK_OPT, StageResult::FAIL, errCode}); goto END; } connection = db->GetDBConnection(errCode); if (connection == nullptr) { // not kill db, Other operations like import may be used concurrently + DBDfxAdapter::ReportBehavior( + {__func__, Scene::OPEN_CONN, State::BEGIN, Stage::GET_DB_CONN, StageResult::FAIL, errCode}); LOGE("Failed to get the db connect for delegate:%d", errCode); } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/relational/relational_sync_able_storage.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/relational/relational_sync_able_storage.cpp index 951ac33c..4a5f0a6f 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/relational/relational_sync_able_storage.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/relational/relational_sync_able_storage.cpp @@ -25,6 +25,7 @@ #include "db_dfx_adapter.h" #include "generic_single_ver_kv_entry.h" #include "platform_specific.h" +#include "query_utils.h" #include "relational_remote_query_continue_token.h" #include "relational_sync_data_inserter.h" #include "res_finalizer.h" @@ -43,12 +44,6 @@ void TriggerCloseAutoLaunchConn(const RelationalDBProperties &properties) } } -#define CHECK_STORAGE_ENGINE do { \ - if (storageEngine_ == nullptr) { \ - return -E_INVALID_DB; \ - } \ -} while (0) - RelationalSyncAbleStorage::RelationalSyncAbleStorage(std::shared_ptr engine) : storageEngine_(std::move(engine)), reusedHandle_(nullptr), @@ -184,12 +179,14 @@ void RelationalSyncAbleStorage::ReleaseHandle(SQLiteSingleVerRelationalStorageEx // Get meta data associated with the given key. int RelationalSyncAbleStorage::GetMetaData(const Key &key, Value &value) const { - CHECK_STORAGE_ENGINE; + if (storageEngine_ == nullptr) { + return -E_INVALID_DB; + } if (key.size() > DBConstant::MAX_KEY_SIZE) { return -E_INVALID_ARGS; } int errCode = E_OK; - auto handle = GetHandle(true, errCode, OperatePerm::NORMAL_PERM); + auto handle = GetHandle(false, errCode, OperatePerm::NORMAL_PERM); if (handle == nullptr) { return errCode; } @@ -204,7 +201,9 @@ int RelationalSyncAbleStorage::GetMetaData(const Key &key, Value &value) const // Put meta data as a key-value entry. int RelationalSyncAbleStorage::PutMetaData(const Key &key, const Value &value) { - CHECK_STORAGE_ENGINE; + if (storageEngine_ == nullptr) { + return -E_INVALID_DB; + } int errCode = E_OK; auto *handle = GetHandle(true, errCode, OperatePerm::NORMAL_PERM); if (handle == nullptr) { @@ -222,7 +221,9 @@ int RelationalSyncAbleStorage::PutMetaData(const Key &key, const Value &value) int RelationalSyncAbleStorage::PutMetaData(const Key &key, const Value &value, bool isInTransaction) { - CHECK_STORAGE_ENGINE; + if (storageEngine_ == nullptr) { + return -E_INVALID_DB; + } int errCode = E_OK; SQLiteSingleVerRelationalStorageExecutor *handle = nullptr; std::unique_lock handLock(reusedHandleMutex_, std::defer_lock); @@ -259,7 +260,9 @@ int RelationalSyncAbleStorage::PutMetaData(const Key &key, const Value &value, b // Delete multiple meta data records in a transaction. int RelationalSyncAbleStorage::DeleteMetaData(const std::vector &keys) { - CHECK_STORAGE_ENGINE; + if (storageEngine_ == nullptr) { + return -E_INVALID_DB; + } for (const auto &key : keys) { if (key.empty() || key.size() > DBConstant::MAX_KEY_SIZE) { return -E_INVALID_ARGS; @@ -287,7 +290,9 @@ int RelationalSyncAbleStorage::DeleteMetaData(const std::vector &keys) // Delete multiple meta data records with key prefix in a transaction. int RelationalSyncAbleStorage::DeleteMetaDataByPrefixKey(const Key &keyPrefix) const { - CHECK_STORAGE_ENGINE; + if (storageEngine_ == nullptr) { + return -E_INVALID_DB; + } if (keyPrefix.empty() || keyPrefix.size() > DBConstant::MAX_KEY_SIZE) { return -E_INVALID_ARGS; } @@ -310,7 +315,9 @@ int RelationalSyncAbleStorage::DeleteMetaDataByPrefixKey(const Key &keyPrefix) c // Get all meta data keys. int RelationalSyncAbleStorage::GetAllMetaKeys(std::vector &keys) const { - CHECK_STORAGE_ENGINE; + if (storageEngine_ == nullptr) { + return -E_INVALID_DB; + } int errCode = E_OK; auto *handle = GetHandle(true, errCode, OperatePerm::NORMAL_PERM); if (handle == nullptr) { @@ -639,7 +646,7 @@ int RelationalSyncAbleStorage::LocalDataChanged(int notifyEvent, std::vector &entries, const std::string &sourceID, - const std::string &targetID) const + const std::string &targetID, bool isPush) const { return E_OK; } @@ -755,23 +762,24 @@ int RelationalSyncAbleStorage::UnRegisterObserverAction(uint64_t connectionId, c return; } 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; + if (action == it->second.end()) { + return; + } + 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; }, nullptr, &dataChangeCallbackMap_); ADAPTER_WAIT(handle); return errCode; } void RelationalSyncAbleStorage::ExecuteDataChangeCallback( - const std::pair> &item, int &observerCnt, - const std::string &deviceName, const ChangedData &changedData, bool isChangedData) + const std::pair> &item, + const std::string &deviceName, const ChangedData &changedData, bool isChangedData, int &observerCnt) { for (auto &action : item.second) { if (action.second == nullptr) { @@ -796,7 +804,7 @@ void RelationalSyncAbleStorage::TriggerObserverAction(const std::string &deviceN int observerCnt = 0; ADAPTER_AUTO_LOCK(lock, dataChangeDeviceMutex_); for (const auto &item : dataChangeCallbackMap_) { - ExecuteDataChangeCallback(item, observerCnt, deviceName, changedData, isChangedData); + ExecuteDataChangeCallback(item, deviceName, changedData, isChangedData, observerCnt); } LOGD("relational observer size = %d", observerCnt); DecObjRef(this); @@ -1004,7 +1012,9 @@ StoreInfo RelationalSyncAbleStorage::GetStoreInfo() const int RelationalSyncAbleStorage::StartTransaction(TransactType type) { - CHECK_STORAGE_ENGINE; + if (storageEngine_ == nullptr) { + return -E_INVALID_DB; + } std::unique_lock lock(transactionMutex_); if (transactionHandle_ != nullptr) { LOGD("Transaction started already."); @@ -1125,7 +1135,9 @@ int RelationalSyncAbleStorage::GetCloudDataNext(ContinueToken &continueStmtToken return -E_INVALID_DB; } cloudDataResult.isShared = IsSharedTable(cloudDataResult.tableName); - int errCode = transactionHandle_->GetSyncCloudData(cloudDataResult, CloudDbConstant::MAX_UPLOAD_SIZE, *token); + auto config = GetCloudSyncConfig(); + transactionHandle_->SetUploadConfig(config.maxUploadCount, config.maxUploadSize); + int errCode = transactionHandle_->GetSyncCloudData(cloudDataResult, *token); LOGI("mode:%d upload data, ins:%zu, upd:%zu, del:%zu, lock:%zu", cloudDataResult.mode, cloudDataResult.insData.extend.size(), cloudDataResult.updData.extend.size(), cloudDataResult.delData.extend.size(), cloudDataResult.lockData.extend.size()); @@ -1204,6 +1216,9 @@ int RelationalSyncAbleStorage::GetInfoByPrimaryKeyOrGid(const std::string &table int RelationalSyncAbleStorage::GetInfoByPrimaryKeyOrGidInner(SQLiteSingleVerRelationalStorageExecutor *handle, const std::string &tableName, const VBucket &vBucket, DataInfoWithLog &dataInfoWithLog, VBucket &assetInfo) { + if (handle == nullptr) { + return -E_INVALID_DB; + } TableSchema tableSchema; int errCode = GetCloudTableSchema(tableName, tableSchema); if (errCode != E_OK) { @@ -1305,7 +1320,9 @@ int RelationalSyncAbleStorage::SetLogTriggerStatus(bool status) int RelationalSyncAbleStorage::FillCloudLogAndAsset(const OpType opType, const CloudSyncData &data, bool fillAsset, bool ignoreEmptyGid) { - CHECK_STORAGE_ENGINE; + if (storageEngine_ == nullptr) { + return -E_INVALID_DB; + } int errCode = E_OK; auto writeHandle = static_cast( storageEngine_->FindExecutor(true, OperatePerm::NORMAL_PERM, errCode)); @@ -1688,6 +1705,7 @@ int RelationalSyncAbleStorage::UpsertDataInner(SQLiteSingleVerRelationalStorageE int errCode = E_OK; errCode = handle->StartTransaction(TransactType::IMMEDIATE); if (errCode != E_OK) { + LOGE("[RDBStorageEngine] start transaction failed %d when upsert data", errCode); return errCode; } errCode = CreateTempSyncTriggerInner(handle, tableName); @@ -1749,6 +1767,7 @@ int RelationalSyncAbleStorage::UpsertDataInTransaction(SQLiteSingleVerRelational recordCopy[CloudDbConstant::MODIFY_FIELD] = static_cast(dataInfoWithLog.logInfo.timestamp); recordCopy[CloudDbConstant::CREATE_FIELD] = static_cast(dataInfoWithLog.logInfo.wTimestamp); recordCopy[CloudDbConstant::SHARING_RESOURCE_FIELD] = dataInfoWithLog.logInfo.sharingResource; + recordCopy[CloudDbConstant::VERSION_FIELD] = dataInfoWithLog.logInfo.version; } downloadData.existDataKey.push_back(dataInfoWithLog.logInfo.dataKey); downloadData.data.push_back(std::move(recordCopy)); @@ -1877,23 +1896,14 @@ int RelationalSyncAbleStorage::GetCompensatedSyncQueryInner(SQLiteSingleVerRelat return errCode; } for (const auto &table : tables) { - // check whether reference exist - std::map> tableReference; - errCode = RelationalSyncAbleStorage::GetTableReference(table.name, tableReference); - if (errCode != E_OK) { - LOGW("[RelationalSyncAbleStorage] Get table reference failed, continue next! errCode = %d", errCode); - errCode = E_OK; - continue; - } - if (!tableReference.empty()) { - LOGD("[RelationalSyncAbleStorage] current table exist reference property"); + if (!CheckTableSupportCompensatedSync(table)) { continue; } std::vector syncDataPk; errCode = handle->GetWaitCompensatedSyncDataPk(table, syncDataPk); if (errCode != E_OK) { - LOGW("[GetWaitCompensatedSyncDataPk] Get wait compensated sync date failed, continue! errCode=%d", errCode); + LOGW("[RDBStorageEngine] Get wait compensated sync date failed, continue! errCode=%d", errCode); errCode = E_OK; continue; } @@ -1953,10 +1963,10 @@ int RelationalSyncAbleStorage::GetSyncQueryByPk(const std::string &tableName, syncPk[col].push_back(value); } } - LOGD("[RDBStorageEngine] match %zu data for compensated sync, ignore %d", data.size(), ignoreCount); + LOGI("[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); + QueryUtils::FillQueryInKeys(col, pkList, dataIndex[col], query); } auto objectList = QuerySyncObject::GetQuerySyncObject(query); if (objectList.size() != 1u) { @@ -1966,47 +1976,6 @@ int RelationalSyncAbleStorage::GetSyncQueryByPk(const std::string &tableName, 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; - } -} - int RelationalSyncAbleStorage::CreateTempSyncTriggerInner(SQLiteSingleVerRelationalStorageExecutor *handle, const std::string &tableName) { @@ -2017,6 +1986,30 @@ int RelationalSyncAbleStorage::CreateTempSyncTriggerInner(SQLiteSingleVerRelatio return handle->CreateTempSyncTrigger(trackerTable); } +bool RelationalSyncAbleStorage::CheckTableSupportCompensatedSync(const TableSchema &table) +{ + auto it = std::find_if(table.fields.begin(), table.fields.end(), [](const auto &field) { + return field.primary && (field.type == TYPE_INDEX || field.type == TYPE_INDEX || + field.type == TYPE_INDEX); + }); + if (it != table.fields.end()) { + LOGI("[RDBStorageEngine] Table contain not support pk field type, ignored"); + return false; + } + // check whether reference exist + std::map> tableReference; + int errCode = RelationalSyncAbleStorage::GetTableReference(table.name, tableReference); + if (errCode != E_OK) { + LOGW("[RDBStorageEngine] Get table reference failed! errCode = %d", errCode); + return false; + } + if (!tableReference.empty()) { + LOGI("[RDBStorageEngine] current table exist reference property"); + return false; + } + return true; +} + int RelationalSyncAbleStorage::MarkFlagAsConsistent(const std::string &tableName, const DownloadData &downloadData, const std::set &gidFilters) { @@ -2038,10 +2031,9 @@ void RelationalSyncAbleStorage::SyncFinishHook() } } -int RelationalSyncAbleStorage::SetSyncFinishHook(const std::function &func) +void RelationalSyncAbleStorage::SetSyncFinishHook(const std::function &func) { syncFinishFunc_ = func; - return E_OK; } void RelationalSyncAbleStorage::DoUploadHook() @@ -2055,5 +2047,29 @@ void RelationalSyncAbleStorage::SetDoUploadHook(const std::function { uploadStartFunc_ = func; } + +CloudSyncConfig RelationalSyncAbleStorage::GetCloudSyncConfig() const +{ + std::lock_guard autoLock(configMutex_); + return cloudSyncConfig_; +} + +void RelationalSyncAbleStorage::SetCloudSyncConfig(const CloudSyncConfig &config) +{ + std::lock_guard autoLock(configMutex_); + cloudSyncConfig_ = config; +} + +bool RelationalSyncAbleStorage::IsTableExistReference(const std::string &table) +{ + // check whether reference exist + std::map> tableReference; + int errCode = RelationalSyncAbleStorage::GetTableReference(table, tableReference); + if (errCode != E_OK) { + LOGW("[RDBStorageEngine] Get table reference failed! errCode = %d", errCode); + return false; + } + return !tableReference.empty(); +} } #endif \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/single_ver_natural_store.h b/kv_store/frameworks/libs/distributeddb/storage/src/single_ver_natural_store.h index fb502b78..644a33b2 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/single_ver_natural_store.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/single_ver_natural_store.h @@ -30,7 +30,6 @@ public: virtual void AbortHandle(); int RemoveKvDB(const KvDBProperties &properties) override; - protected: struct TransPair { int index; diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/cloud_sync_log_table_manager.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/cloud_sync_log_table_manager.cpp index 29853a66..1348cb79 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/cloud_sync_log_table_manager.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/cloud_sync_log_table_manager.cpp @@ -108,7 +108,7 @@ std::string CloudSyncLogTableManager::GetInsertTrigger(const TableInfo &table, c insertTrigger += ") THEN (SELECT cloud_gid FROM " + logTblName + " WHERE hash_key = "; insertTrigger += CalcPrimaryKeyHash("NEW.", table, identity) + ") ELSE '' END, "; insertTrigger += table.GetTrackerTable().GetAssignValSql(); - insertTrigger += ", case when (SELECT count(1)<>0 FROM " + logTblName + ") then "; + insertTrigger += ", case when (SELECT MIN(_rowid_) IS NOT NULL FROM " + logTblName + ") then "; insertTrigger += " (SELECT case when (MAX(cursor) is null) then 1 else MAX(cursor) + 1 END"; insertTrigger += " FROM " + logTblName + ")"; insertTrigger += " ELSE new." + std::string(DBConstant::SQLITE_INNER_ROWID) + " end, '', '', 0);\n"; diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/simple_tracker_log_table_manager.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/simple_tracker_log_table_manager.cpp index 0b000a2c..4e6d2f06 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/simple_tracker_log_table_manager.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/simple_tracker_log_table_manager.cpp @@ -73,7 +73,7 @@ std::string SimpleTrackerLogTableManager::GetInsertTrigger(const TableInfo &tabl insertTrigger += " get_raw_sys_time(), get_raw_sys_time(), 0x02, "; insertTrigger += CalcPrimaryKeyHash("NEW.", table, identity) + ", '', "; insertTrigger += table.GetTrackerTable().GetAssignValSql(); - insertTrigger += ", case when (SELECT count(1)<>0 FROM " + logTblName + ") then "; + insertTrigger += ", case when (SELECT MIN(_rowid_) IS NOT NULL FROM " + logTblName + ") then "; insertTrigger += " (SELECT case when (MAX(cursor) is null) then 1 else MAX(cursor) + 1 END"; insertTrigger += " FROM " + logTblName + ")"; insertTrigger += " ELSE new." + std::string(DBConstant::SQLITE_INNER_ROWID) + " end, '', '', 0);\n"; 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 5500dd32..2d7baf19 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 @@ -32,7 +32,18 @@ SqliteRelationalDatabaseUpgrader::~SqliteRelationalDatabaseUpgrader() {} int SqliteRelationalDatabaseUpgrader::Upgrade() { - int errCode = BeginUpgrade(); + // read version first, if not newest, start transaction + std::string logTableVersion; + int errCode = SQLiteUtils::GetLogTableVersion(db_, logTableVersion); + if (errCode != E_OK) { + LOGW("[Relational][Upgrade] Get log table version return. %d", errCode); + return (errCode == -E_NOT_FOUND) ? E_OK : errCode; + } + if (IsNewestVersion(logTableVersion)) { + return E_OK; + } + + errCode = BeginUpgrade(); if (errCode != E_OK) { LOGE("[Relational][Upgrade] Begin upgrade failed. err=%d", errCode); return errCode; 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 5a453935..3a682d8d 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 @@ -29,7 +29,7 @@ namespace DistributedDB { namespace { - constexpr const char *DISTRIBUTED_TABLE_MODE = "distributed_table_mode"; +constexpr const char *DISTRIBUTED_TABLE_MODE = "distributed_table_mode"; } SQLiteRelationalStore::~SQLiteRelationalStore() @@ -49,7 +49,7 @@ void SQLiteRelationalStore::IncreaseConnectionCounter() RelationalStoreConnection *SQLiteRelationalStore::GetDBConnection(int &errCode) { std::lock_guard lock(connectMutex_); - RelationalStoreConnection* connection = new (std::nothrow) SQLiteRelationalStoreConnection(this); + RelationalStoreConnection *connection = new (std::nothrow) SQLiteRelationalStoreConnection(this); if (connection == nullptr) { errCode = -E_OUT_OF_MEMORY; return nullptr; @@ -76,7 +76,7 @@ int SQLiteRelationalStore::InitStorageEngine(const RelationalDBProperties &prope InitDataBaseOption(properties, option); std::string identifier = properties.GetStringProp(DBProperties::IDENTIFIER_DATA, ""); - StorageEngineAttr poolSize = {1, 1, 0, 16}; // at most 1 write 16 read. + StorageEngineAttr poolSize = { 1, 1, 0, 16 }; // at most 1 write 16 read. int errCode = sqliteStorageEngine_->InitSQLiteStorageEngine(poolSize, option, identifier); if (errCode != E_OK) { LOGE("Init the sqlite storage engine failed:%d", errCode); @@ -183,8 +183,8 @@ int SQLiteRelationalStore::CheckProperties(RelationalDBProperties properties) // Empty schema means no distributed table has been used, we may set DB to any table mode // If there is a schema but no table mode, it is the 'SPLIT_BY_DEVICE' mode of old version bool isSchemaEmpty = (errCode == -E_NOT_FOUND); - auto mode = static_cast(properties.GetIntProp(RelationalDBProperties::DISTRIBUTED_TABLE_MODE, - DistributedTableMode::SPLIT_BY_DEVICE)); + auto mode = static_cast( + properties.GetIntProp(RelationalDBProperties::DISTRIBUTED_TABLE_MODE, DistributedTableMode::SPLIT_BY_DEVICE)); errCode = CheckTableModeFromMeta(mode, isSchemaEmpty); if (errCode != E_OK) { LOGE("Get distributed table mode from meta failed. errcode=%d", errCode); @@ -287,7 +287,7 @@ int SQLiteRelationalStore::Open(const RelationalDBProperties &properties) // to guarantee the life cycle of sync module and syncAbleEngine_ are the same, then the sync module will not // be destructed when close store storageEngine_->SetSyncAbleEngine(syncAbleEngine_); - cloudSyncer_ = new(std::nothrow) CloudSyncer(StorageProxy::GetCloudDb(storageEngine_)); + cloudSyncer_ = new (std::nothrow) CloudSyncer(StorageProxy::GetCloudDb(storageEngine_)); errCode = CheckDBMode(); if (errCode != E_OK) { @@ -334,8 +334,8 @@ SQLiteSingleVerRelationalStorageExecutor *SQLiteRelationalStore::GetHandle(bool return nullptr; } - return static_cast(sqliteStorageEngine_->FindExecutor(isWrite, - OperatePerm::NORMAL_PERM, errCode)); + return static_cast( + sqliteStorageEngine_->FindExecutor(isWrite, OperatePerm::NORMAL_PERM, errCode)); } void SQLiteRelationalStore::ReleaseHandle(SQLiteSingleVerRelationalStorageExecutor *&handle) const { @@ -432,7 +432,7 @@ int SQLiteRelationalStore::CreateDistributedTable(const std::string &tableName, TableInfo tableInfo = localSchema.GetTable(tableName); if (!tableInfo.Empty()) { bool isSharedTable = tableInfo.GetSharedTableMark(); - if (isSharedTable) { + if (isSharedTable && !trackerSchemaChanged) { return E_OK; // shared table will create distributed table when use SetCloudDbSchema } } @@ -532,7 +532,7 @@ int SQLiteRelationalStore::RemoveDeviceData() return errCode; } - for (const auto &table: tableNameList) { + for (const auto &table : tableNameList) { errCode = handle->DeleteDistributedDeviceTable("", table); if (errCode != E_OK) { LOGE("delete device data failed. %d", errCode); @@ -637,7 +637,8 @@ int SQLiteRelationalStore::StartLifeCycleTimer(const DatabaseLifeCycleNotifier & } RefObject::IncObjRef(this); TimerId timerId = 0; - int errCode = runtimeCxt->SetTimer(DBConstant::DEF_LIFE_CYCLE_TIME, + int errCode = runtimeCxt->SetTimer( + DBConstant::DEF_LIFE_CYCLE_TIME, [this](TimerId id) -> int { std::lock_guard lock(lifeCycleMutex_); if (lifeCycleNotifier_) { @@ -655,9 +656,7 @@ int SQLiteRelationalStore::StartLifeCycleTimer(const DatabaseLifeCycleNotifier & return 0; }, [this]() { - int ret = RuntimeContext::GetInstance()->ScheduleTask([this]() { - RefObject::DecObjRef(this); - }); + int ret = RuntimeContext::GetInstance()->ScheduleTask([this]() { RefObject::DecObjRef(this); }); if (ret != E_OK) { LOGE("SQLiteSingleVerNaturalStore timer finalizer ScheduleTask, errCode %d", ret); } @@ -753,8 +752,8 @@ void SQLiteRelationalStore::Dump(int fd) label = sqliteStorageEngine_->GetProperties().GetStringProp(DBProperties::IDENTIFIER_DATA, ""); } label = DBCommon::TransferStringToHex(label); - DBDumpHelper::Dump(fd, "\tdb userId = %s, appId = %s, storeId = %s, label = %s\n", - userId.c_str(), appId.c_str(), storeId.c_str(), label.c_str()); + DBDumpHelper::Dump(fd, "\tdb userId = %s, appId = %s, storeId = %s, label = %s\n", userId.c_str(), appId.c_str(), + storeId.c_str(), label.c_str()); if (syncAbleEngine_ != nullptr) { syncAbleEngine_->Dump(fd); } @@ -776,8 +775,8 @@ int SQLiteRelationalStore::RemoteQuery(const std::string &device, const RemoteCo return -E_NOT_SUPPORT; } const auto &properties = sqliteStorageEngine_->GetProperties(); - int tableMode = properties.GetIntProp(RelationalDBProperties::DISTRIBUTED_TABLE_MODE, - DistributedTableMode::SPLIT_BY_DEVICE); + int tableMode = + properties.GetIntProp(RelationalDBProperties::DISTRIBUTED_TABLE_MODE, DistributedTableMode::SPLIT_BY_DEVICE); if (tableMode != DistributedTableMode::SPLIT_BY_DEVICE) { LOGW("only support split mode."); return -E_NOT_SUPPORT; @@ -805,8 +804,8 @@ int SQLiteRelationalStore::EraseAllDeviceWatermark(const std::vectorEraseDeviceWaterMark(device, false, tableName); if (errCode != E_OK) { return errCode; @@ -819,11 +818,9 @@ int SQLiteRelationalStore::EraseAllDeviceWatermark(const std::vectorGetProperties().GetStringProp(DBProperties::USER_ID, ""), + StoreInfo info = { sqliteStorageEngine_->GetProperties().GetStringProp(DBProperties::USER_ID, ""), sqliteStorageEngine_->GetProperties().GetStringProp(DBProperties::APP_ID, ""), - sqliteStorageEngine_->GetProperties().GetStringProp(DBProperties::STORE_ID, "") - }; + sqliteStorageEngine_->GetProperties().GetStringProp(DBProperties::STORE_ID, "") }; if (RuntimeContext::GetInstance()->TranslateDeviceId(device, info, devTableName) != E_OK) { devTableName = hashDev; } @@ -924,7 +921,7 @@ std::vector SQLiteRelationalStore::GetAllDistributedTableName() { TableInfoMap tables = sqliteStorageEngine_->GetSchema().GetTables(); // TableInfoMap std::vector tableNames; - for (const auto &table: tables) { + for (const auto &table : tables) { if (table.second.GetTableSyncType() == TableSyncType::CLOUD_COOPERATION) { continue; } @@ -1009,8 +1006,8 @@ bool SQLiteRelationalStore::PrepareSharedTable(const DataBaseSchema &schema, std sharedTableNamesMap[table.name] = table.sharedTableName; std::vector fields = table.fields; bool hasPrimaryKey = DBCommon::HasPrimaryKey(fields); - Field ownerField = {CloudDbConstant::CLOUD_OWNER, TYPE_INDEX, hasPrimaryKey}; - Field privilegeField = {CloudDbConstant::CLOUD_PRIVILEGE, TYPE_INDEX}; + Field ownerField = { CloudDbConstant::CLOUD_OWNER, TYPE_INDEX, hasPrimaryKey }; + Field privilegeField = { CloudDbConstant::CLOUD_PRIVILEGE, TYPE_INDEX }; fields.insert(fields.begin(), privilegeField); fields.insert(fields.begin(), ownerField); fieldsMap[table.name] = fields; @@ -1091,6 +1088,7 @@ int SQLiteRelationalStore::Sync(const CloudSyncOption &option, const SyncProcess if (errCode != E_OK) { return errCode; } + LOGI("sync mode:%d, pri:%d, comp:%d", option.mode, option.priorityTask, option.compensatedSyncOnly); if (option.compensatedSyncOnly) { CloudSyncer::CloudTaskInfo info = CloudSyncUtils::InitCompensatedSyncTaskInfo(); info.callback = onProcess; @@ -1192,7 +1190,7 @@ int SQLiteRelationalStore::CheckObjectValid(bool priorityTask, const std::vector std::string tableName = item.GetRelationTableName(); TableInfo tableInfo = localSchema.GetTable(tableName); if (!tableInfo.Empty()) { - const std::map& primaryKeyMap = tableInfo.GetPrimaryKey(); + const std::map &primaryKeyMap = tableInfo.GetPrimaryKey(); errCode = item.CheckPrimaryKey(primaryKeyMap); if (errCode != E_OK) { return errCode; @@ -1208,7 +1206,7 @@ int SQLiteRelationalStore::CheckTableName(const std::vector &tableN LOGE("[RelationalStore] sync with empty table"); return -E_INVALID_ARGS; } - for (const auto &table: tableNames) { + for (const auto &table : tableNames) { int errCode = ChkSchema(table); if (errCode != E_OK) { LOGE("[RelationalStore] schema check failed when sync"); @@ -1225,13 +1223,13 @@ void SQLiteRelationalStore::FillSyncInfo(const CloudSyncOption &option, const Sy if (syncObject.empty()) { QuerySyncObject querySyncObject(option.query); info.table = querySyncObject.GetRelationTableNames(); - for (const auto &item: info.table) { + for (const auto &item : info.table) { QuerySyncObject object(Query::Select()); object.SetTableName(item); info.queryList.push_back(object); } } else { - for (auto &item: syncObject) { + for (auto &item : syncObject) { info.table.push_back(item.GetRelationTableName()); info.queryList.push_back(std::move(item)); } @@ -1245,6 +1243,7 @@ void SQLiteRelationalStore::FillSyncInfo(const CloudSyncOption &option, const Sy info.users.push_back(""); info.lockAction = option.lockAction; info.merge = option.merge; + info.storeId = sqliteStorageEngine_->GetProperties().GetStringProp(DBProperties::STORE_ID, ""); } int SQLiteRelationalStore::SetTrackerTable(const TrackerSchema &trackerSchema) @@ -1370,8 +1369,7 @@ int SQLiteRelationalStore::ExecuteCreateSharedTable(const DataBaseSchema &schema } LOGI("[RelationalStore][ExecuteCreateSharedTable] upgrade shared table start"); // upgrade contains delete, alter, update and create - int errCode = sqliteStorageEngine_->UpgradeSharedTable(schema, deleteTableNames, updateTableNames, - alterTableNames); + int errCode = sqliteStorageEngine_->UpgradeSharedTable(schema, deleteTableNames, updateTableNames, alterTableNames); if (errCode != E_OK) { LOGE("[RelationalStore][ExecuteCreateSharedTable] upgrade shared table failed. %d", errCode); } else { @@ -1393,7 +1391,7 @@ int SQLiteRelationalStore::ReFillSyncInfoTable(const std::vector &a LOGD("[RelationalStore] Fill tables from %zu to %zu", info.table.size(), actualTable.size()); info.table = actualTable; info.queryList.clear(); - for (const auto &item: info.table) { + for (const auto &item : info.table) { QuerySyncObject object(Query::Select()); object.SetTableName(item); info.queryList.push_back(object); @@ -1488,9 +1486,17 @@ int SQLiteRelationalStore::CheckSchemaForUpsertData(const std::string &tableName for (auto &field : table.GetIdentifyKey()) { dbPkFields.insert(field); } + std::set schemaFields; + for (auto &fieldInfo : table.GetFieldInfos()) { + schemaFields.insert(fieldInfo.GetFieldName()); + } for (const auto &record : records) { std::set recordPkFields; for (const auto &item : record) { + if (schemaFields.find(item.first) == schemaFields.end()) { + LOGE("[RelationalStore][CheckSchemaForUpsertData] invalid field not exist in schema"); + return -E_INVALID_ARGS; + } if (dbPkFields.find(item.first) == dbPkFields.end()) { continue; } @@ -1551,5 +1557,15 @@ int SQLiteRelationalStore::CheckCloudSchema(const DataBaseSchema &schema) } return E_OK; } + +int SQLiteRelationalStore::SetCloudSyncConfig(const CloudSyncConfig &config) +{ + if (storageEngine_ == nullptr) { + LOGE("[RelationalStore][SetCloudSyncConfig] sqliteStorageEngine was not initialized"); + return -E_INVALID_DB; + } + storageEngine_->SetCloudSyncConfig(config); + return E_OK; +} } //namespace DistributedDB #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 00ec3023..d110eed9 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 @@ -104,6 +104,8 @@ public: int Pragma(PragmaCmd cmd, PragmaData &pragmaData); int UpsertData(RecordStatus status, const std::string &tableName, const std::vector &records); + + int SetCloudSyncConfig(const CloudSyncConfig &config); private: void ReleaseResources(); diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.cpp index cccf4c21..2c36a985 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.cpp @@ -440,5 +440,15 @@ int SQLiteRelationalStoreConnection::UpsertData(RecordStatus status, const std:: } return store->UpsertData(status, tableName, records); } + +int SQLiteRelationalStoreConnection::SetCloudSyncConfig(const CloudSyncConfig &config) +{ + auto *store = GetDB(); + if (store == nullptr) { + LOGE("[RelationalConnection] store is null, set cloud sync config failed!"); + return -E_INVALID_CONNECTION; + } + return store->SetCloudSyncConfig(config); +} } #endif \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.h b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.h index 5445aab5..6d248ea4 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store_connection.h @@ -64,6 +64,8 @@ public: int Pragma(PragmaCmd cmd, PragmaData &pragmaData) override; int UpsertData(RecordStatus status, const std::string &tableName, const std::vector &records) override; + + int SetCloudSyncConfig(const CloudSyncConfig &config) override; protected: int Pragma(int cmd, void *parameter) override; diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_utils.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_utils.cpp index 2d76fb9f..b61cf9d5 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_utils.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_utils.cpp @@ -128,7 +128,6 @@ int SQLiteRelationalUtils::GetCloudValueByType(sqlite3_stmt *statement, int type } default: { cloudValue = Nil(); - break; } } return E_OK; @@ -295,16 +294,11 @@ int SQLiteRelationalUtils::GetTypeValByStatement(sqlite3_stmt *stmt, int cid, Ty } case SQLITE_BLOB: { errCode = GetBlobByStatement(stmt, cid, typeVal); - if (errCode != E_OK) { - break; - } + break; } case SQLITE3_TEXT: { errCode = GetBlobByStatement(stmt, cid, typeVal); - if (errCode != E_OK) { - break; - } - if (typeVal.index() != TYPE_INDEX) { + if (errCode != E_OK || typeVal.index() != TYPE_INDEX) { break; } std::string str; @@ -314,7 +308,6 @@ int SQLiteRelationalUtils::GetTypeValByStatement(sqlite3_stmt *stmt, int cid, Ty } default: { typeVal = Nil(); - break; } } return errCode; 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 d070699e..4150ede8 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 @@ -225,6 +225,7 @@ int SQLiteSingleRelationalStorageEngine::CreateDistributedTable(const std::strin int errCode = CreateDistributedTable(tableName, isUpgraded, identity, schema, syncType); if (errCode != E_OK) { + LOGE("CreateDistributedTable failed. %d", errCode); return errCode; } if (isUpgraded && (schemaChanged || trackerSchemaChanged)) { @@ -826,6 +827,7 @@ int SQLiteSingleRelationalStorageEngine::DoAlterSharedTableName(SQLiteSingleVerR for (const auto &tableName : alterTableNames) { errCode = handle->DeleteTableTrigger(tableName.first); if (errCode != E_OK) { + LOGE("[RelationalStorageEngine] delete shared table trigger failed. %d", errCode); return errCode; } std::string oldDistributedName = DBCommon::GetLogTableName(tableName.first); diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_ver_relational_storage_executor.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_ver_relational_storage_executor.cpp index 1cb4a02c..d46bef53 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_ver_relational_storage_executor.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_ver_relational_storage_executor.cpp @@ -35,6 +35,7 @@ namespace { static constexpr const char *DATAKEY = "DATA_KEY"; static constexpr const char *DEVICE_FIELD = "DEVICE"; static constexpr const char *CLOUD_GID_FIELD = "CLOUD_GID"; +static constexpr const char *VERSION = "VERSION"; static constexpr const char *SHARING_RESOURCE = "SHARING_RESOURCE"; static constexpr const char *FLAG_IS_CLOUD = "FLAG & 0x02 = 0"; // see if 1th bit of a flag is cloud // set 1th bit of flag to one which is local, clean 5th bit of flag to one which is wait compensated sync @@ -65,7 +66,8 @@ 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), putDataMode_(PutDataMode::SYNC), markFlagOption_(MarkFlagOption::DEFAULT) + assetLoader_(nullptr), putDataMode_(PutDataMode::SYNC), markFlagOption_(MarkFlagOption::DEFAULT), + maxUploadCount_(0), maxUploadSize_(0) { bindCloudFieldFuncMap_[TYPE_INDEX] = &CloudStorageUtils::BindInt64; bindCloudFieldFuncMap_[TYPE_INDEX] = &CloudStorageUtils::BindBool; @@ -160,8 +162,10 @@ int SQLiteSingleVerRelationalStorageExecutor::GeneLogInfoForExistedData(sqlite3 std::string logTable = DBConstant::RELATIONAL_PREFIX + tableName + "_log"; std::string sql = "INSERT OR REPLACE INTO " + logTable + " SELECT " + std::string(DBConstant::SQLITE_INNER_ROWID) + ", '', '', " + timeOffsetStr + " + " + std::string(DBConstant::SQLITE_INNER_ROWID) + ", " + - timeOffsetStr + " + " + std::string(DBConstant::SQLITE_INNER_ROWID) + ", 0x02|0x20, " + - calPrimaryKeyHash + ", '', "; + timeOffsetStr + " + " + std::string(DBConstant::SQLITE_INNER_ROWID) + ", " + + std::to_string(static_cast(LogInfoFlag::FLAG_LOCAL) | + static_cast(LogInfoFlag::FLAG_DEVICE_CLOUD_CONSISTENCY)) + + ", " + calPrimaryKeyHash + ", '', "; if (tableInfo.GetTableSyncType() == TableSyncType::DEVICE_COOPERATION) { sql += "'', ''"; } else { @@ -535,7 +539,7 @@ static int GetLogData(sqlite3_stmt *logStatement, LogInfo &logInfo) } namespace { -void GetCloudLog(sqlite3_stmt *logStatement, VBucket &logInfo, uint32_t &totalSize, bool isShared) +void GetCloudLog(sqlite3_stmt *logStatement, VBucket &logInfo, uint32_t &totalSize) { logInfo.insert_or_assign(CloudDbConstant::MODIFY_FIELD, static_cast(sqlite3_column_int64(logStatement, TIMESTAMP_INDEX))); @@ -1542,9 +1546,8 @@ int SQLiteSingleVerRelationalStorageExecutor::GetExistsDeviceList(std::set ×tampVec, bool isCloudForcePush, bool isCompensatedTask, QuerySyncObject &query, int64_t &count) { - if (timestampVec.size() != 3) { // 3 is the number of three mode. + std::vector typeVec = DBCommon::GetWaterTypeVec(); + if (timestampVec.size() != typeVec.size()) { return -E_INVALID_ARGS; } int errCode; @@ -1584,11 +1588,9 @@ int SQLiteSingleVerRelationalStorageExecutor::GetAllUploadCount(const std::vecto if (errCode != E_OK) { return errCode; } - std::string tableName = query.GetRelationTableName(); count = 0; - std::vector typeVec = {CloudWaterType::DELETE, CloudWaterType::UPDATE, CloudWaterType::INSERT}; for (size_t i = 0; i < typeVec.size(); i++) { - std::string sql = helper.GetCountRelationalCloudQuerySql(isCloudForcePush, isCompensatedTask); + std::string sql = helper.GetCountRelationalCloudQuerySql(isCloudForcePush, isCompensatedTask, typeVec[i]); int64_t tempCount = 0; helper.AppendCloudQueryToGetDiffData(sql, typeVec[i]); errCode = GetUploadCountInner(timestampVec[i], helper, sql, tempCount); @@ -1621,7 +1623,7 @@ int SQLiteSingleVerRelationalStorageExecutor::UpdateCloudLogGid(const CloudSyncD } int SQLiteSingleVerRelationalStorageExecutor::GetSyncCloudData(CloudSyncData &cloudDataResult, - const uint32_t &maxSize, SQLiteSingleVerRelationalContinueToken &token) + SQLiteSingleVerRelationalContinueToken &token) { token.GetCloudTableSchema(tableSchema_); sqlite3_stmt *queryStmt = nullptr; @@ -1642,10 +1644,8 @@ int SQLiteSingleVerRelationalStorageExecutor::GetSyncCloudData(CloudSyncData &cl } } isStepNext = true; - errCode = GetCloudDataForSync(queryStmt, cloudDataResult, ++stepNum, totalSize, maxSize); + errCode = GetCloudDataForSync(queryStmt, cloudDataResult, ++stepNum, totalSize); } while (errCode == E_OK); - LOGD("Get cloud sync data, insData:%u, upData:%u, delLog:%u", cloudDataResult.insData.record.size(), - cloudDataResult.updData.record.size(), cloudDataResult.delData.extend.size()); if (errCode != -E_UNFINISHED) { (void)token.ReleaseCloudStatement(); } @@ -1683,12 +1683,12 @@ int SQLiteSingleVerRelationalStorageExecutor::GetSyncCloudGid(QuerySyncObject &q } int SQLiteSingleVerRelationalStorageExecutor::GetCloudDataForSync(sqlite3_stmt *statement, - CloudSyncData &cloudDataResult, uint32_t &stepNum, uint32_t &totalSize, const uint32_t &maxSize) + CloudSyncData &cloudDataResult, uint32_t &stepNum, uint32_t &totalSize) { VBucket log; VBucket extraLog; uint32_t preSize = totalSize; - GetCloudLog(statement, log, totalSize, cloudDataResult.isShared); + GetCloudLog(statement, log, totalSize); GetCloudExtraLog(statement, extraLog); VBucket data; @@ -1713,7 +1713,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetCloudDataForSync(sqlite3_stmt * } } - if (CloudStorageUtils::IsGetCloudDataContinue(stepNum, totalSize, maxSize)) { + if (CloudStorageUtils::IsGetCloudDataContinue(stepNum, totalSize, maxUploadSize_, maxUploadCount_)) { errCode = CloudStorageUtils::IdentifyCloudType(cloudDataResult, data, log, extraLog); } else { errCode = -E_UNFINISHED; @@ -1765,7 +1765,7 @@ void SQLiteSingleVerRelationalStorageExecutor::SetLocalSchema(const RelationalSc int SQLiteSingleVerRelationalStorageExecutor::CleanCloudDataOnLogTable(const std::string &logTableName) { std::string cleanLogSql = "UPDATE " + logTableName + " SET " + CloudDbConstant::FLAG + " = " + - SET_FLAG_LOCAL_AND_CLEAN_WAIT_COMPENSATED_SYNC + ", " + + SET_FLAG_LOCAL_AND_CLEAN_WAIT_COMPENSATED_SYNC + ", " + VERSION + " = '', " + DEVICE_FIELD + " = '', " + CLOUD_GID_FIELD + " = '', " + SHARING_RESOURCE + " = '' " + "WHERE (" + FLAG_IS_LOGIC_DELETE + ") OR " + CLOUD_GID_FIELD + " IS NOT NULL AND " + CLOUD_GID_FIELD + " != '';"; @@ -1858,7 +1858,8 @@ int SQLiteSingleVerRelationalStorageExecutor::GetUpdateLogRecordStatement(const updateLogSql += "cloud_gid = '', version = '', sharing_resource = '', flag = flag & " + std::to_string(SET_FLAG_ZERO_MASK); } else if (opType == OpType::LOCKED_NOT_HANDLE) { - updateLogSql += CloudDbConstant::TO_LOCAL_CHANGE; + updateLogSql += std::string(CloudDbConstant::TO_LOCAL_CHANGE) + ", cloud_gid = ?"; + updateColName.push_back(CloudDbConstant::GID_FIELD); } else { if (opType == OpType::DELETE) { updateLogSql += GetCloudDeleteSql(DBCommon::GetLogTableName(tableSchema.name)); diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_ver_relational_storage_executor.h b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_ver_relational_storage_executor.h index 1135145c..856a178e 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_ver_relational_storage_executor.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_ver_relational_storage_executor.h @@ -113,8 +113,7 @@ public: int UpdateCloudLogGid(const CloudSyncData &cloudDataResult, bool ignoreEmptyGid); - int GetSyncCloudData(CloudSyncData &cloudDataResult, const uint32_t &maxSize, - SQLiteSingleVerRelationalContinueToken &token); + int GetSyncCloudData(CloudSyncData &cloudDataResult, SQLiteSingleVerRelationalContinueToken &token); int GetSyncCloudGid(QuerySyncObject &query, const SyncTimeRange &syncTimeRange, bool isCloudForcePushStrategy, bool isCompensatedTask, std::vector &cloudGid); @@ -151,7 +150,7 @@ public: int DeleteTable(const std::vector &tableNames); int UpdateSharedTable(const std::map> &updateTableNames); int AlterTableName(const std::map &tableNames); - int DeleteTableTrigger(const std::string &table) const; + int DeleteTableTrigger(const std::string &missTable) const; int GetReferenceGid(const std::string &tableName, const CloudSyncBatch &syncBatch, const std::map> &tableReference, @@ -172,22 +171,24 @@ public: int CleanResourceForDroppedTable(const std::string &tableName); + void SetPutDataMode(PutDataMode mode); + + void SetMarkFlagOption(MarkFlagOption option); + int UpgradedLogForExistedData(TableInfo &tableInfo, bool schemaChanged); int UpdateRecordFlag(const std::string &tableName, bool recordConflict, const LogInfo &logInfo); int GetWaitCompensatedSyncDataPk(const TableSchema &table, std::vector &data); - void SetPutDataMode(PutDataMode mode); - - void SetMarkFlagOption(MarkFlagOption option); - int MarkFlagAsConsistent(const std::string &tableName, const DownloadData &downloadData, const std::set &gidFilters); int CheckInventoryData(const std::string &tableName); int UpdateRecordStatus(const std::string &tableName, const std::string &status, const Key &hashKey); + + void SetUploadConfig(int32_t maxUploadCount, int32_t maxUploadSize); private: int DoCleanLogs(const std::vector &tableNameList, const RelationalSchemaObject &localSchema); @@ -245,7 +246,7 @@ private: int CleanExtendAndCursorForDeleteData(sqlite3 *db, const std::string &tableName); int GetCloudDataForSync(sqlite3_stmt *statement, CloudSyncData &cloudDataResult, uint32_t &stepNum, - uint32_t &totalSize, const uint32_t &maxSize); + uint32_t &totalSize); int PutVBucketByType(VBucket &vBucket, const Field &field, Type &cloudValue); @@ -260,7 +261,7 @@ private: int GetQueryLogStatement(const TableSchema &tableSchema, const VBucket &vBucket, const std::string &querySql, const Key &hashKey, sqlite3_stmt *&selectStmt); - int GetQueryLogSql(const std::string &tableName, const VBucket &vBucket, std::set &pkSet, + int GetQueryLogSql(const std::string &tableName, const VBucket &vBucket, const std::set &pkSet, std::string &querySql); int GetQueryInfoSql(const std::string &tableName, const VBucket &vBucket, std::set &pkSet, @@ -274,7 +275,7 @@ private: int GetLogInfoByStatement(sqlite3_stmt *statement, LogInfo &logInfo); - int GetInfoByStatement(sqlite3_stmt *statement, std::vector &assetFields, + int GetInfoByStatement(sqlite3_stmt *statement, const std::vector &assetFields, const std::map &pkMap, DataInfoWithLog &dataInfoWithLog, VBucket &assetInfo); int InsertCloudData(VBucket &vBucket, const TableSchema &tableSchema, const TrackerTable &trackerTable, @@ -364,7 +365,7 @@ private: const std::vector &dataKeys); int CleanAssetsIdOnUserTable(const std::string &tableName, const std::string &fieldName, const int64_t rowId, - const std::vector assetsValue); + const std::vector &assetsValue); int InitGetAssetStmt(const std::string &sql, const std::string &gid, const Bytes &hashKey, sqlite3_stmt *&stmt); @@ -417,14 +418,14 @@ private: std::vector GetUpdateField(const VBucket &vBucket, const TableSchema &tableSchema); - int GetRecordFromStmt(sqlite3_stmt *stmt, const std::vector fields, int startIndex, VBucket &record); + int GetRecordFromStmt(sqlite3_stmt *stmt, const std::vector &fields, int startIndex, VBucket &record); + + int FillCloudVersionForUpload(const std::string &tableName, const CloudSyncBatch &batchData); int QueryCount(const std::string &tableName, int64_t &count); int GetUploadCountInner(const Timestamp ×tamp, SqliteQueryHelper &helper, std::string &sql, int64_t &count); - int FillCloudVersionForUpload(const std::string &tableName, const CloudSyncBatch &batchData); - static constexpr const char *CONSISTENT_FLAG = "0x20"; static constexpr const char *UPDATE_FLAG_CLOUD = "flag = flag & 0x20"; static constexpr const char *UPDATE_FLAG_WAIT_COMPENSATED_SYNC = "flag = flag | 0x10"; @@ -446,6 +447,9 @@ private: PutDataMode putDataMode_; MarkFlagOption markFlagOption_; + + std::atomic maxUploadCount_; + std::atomic maxUploadSize_; }; } // namespace DistributedDB #endif diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_ver_relational_storage_executor_extend.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_ver_relational_storage_executor_extend.cpp index 94ce13de..eaaa54ef 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_ver_relational_storage_executor_extend.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_ver_relational_storage_executor_extend.cpp @@ -108,7 +108,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetLogInfoByStatement(sqlite3_stmt } int SQLiteSingleVerRelationalStorageExecutor::GetInfoByStatement(sqlite3_stmt *statement, - std::vector &assetFields, const std::map &pkMap, DataInfoWithLog &dataInfoWithLog, + const std::vector &assetFields, const std::map &pkMap, DataInfoWithLog &dataInfoWithLog, VBucket &assetInfo) { int index = GetLogInfoByStatement(statement, dataInfoWithLog.logInfo); // start index of assetInfo or primary key @@ -223,7 +223,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetQueryLogStatement(const TableSc } int SQLiteSingleVerRelationalStorageExecutor::GetQueryLogSql(const std::string &tableName, const VBucket &vBucket, - std::set &pkSet, std::string &querySql) + const std::set &pkSet, std::string &querySql) { std::string cloudGid; int errCode = CloudStorageUtils::GetValueFromVBucket(CloudDbConstant::GID_FIELD, vBucket, cloudGid); @@ -505,15 +505,14 @@ int SQLiteSingleVerRelationalStorageExecutor::PutCloudSyncData(const std::string if (ret != E_OK) { LOGE("Fail to set log trigger on, %d", ret); } - LOGD("save cloud data: %d, insert cnt = %d, update cnt = %d, delete cnt = %d, only update gid cnt = %d, " - "set LCC flag zero cnt = %d, set LCC flag one cnt = %d, update timestamp cnt = %d, clear gid count = %d," - " not handle cnt = %d", + LOGI("save cloud data:%d, ins:%d, upd:%d, del:%d, only gid:%d, flag zero:%d, flag one:%d, upd timestamp:%d," + "clear gid:%d, not handle:%d, lock:%d", errCode, statisticMap[static_cast(OpType::INSERT)], statisticMap[static_cast(OpType::UPDATE)], statisticMap[static_cast(OpType::DELETE)], statisticMap[static_cast(OpType::ONLY_UPDATE_GID)], statisticMap[static_cast(OpType::SET_CLOUD_FORCE_PUSH_FLAG_ZERO)], statisticMap[static_cast(OpType::SET_CLOUD_FORCE_PUSH_FLAG_ONE)], statisticMap[static_cast(OpType::UPDATE_TIMESTAMP)], statisticMap[static_cast(OpType::CLEAR_GID)], - statisticMap[static_cast(OpType::NOT_HANDLE)]); + statisticMap[static_cast(OpType::NOT_HANDLE)], statisticMap[static_cast(OpType::LOCKED_NOT_HANDLE)]); return errCode == E_OK ? ret : errCode; } @@ -850,7 +849,7 @@ int SQLiteSingleVerRelationalStorageExecutor::UpdateCloudData(VBucket &vBucket, static inline bool IsAllowWithPrimaryKey(OpType opType) { return (opType == OpType::DELETE || opType == OpType::UPDATE_TIMESTAMP || opType == OpType::CLEAR_GID || - opType == OpType::ONLY_UPDATE_GID); + opType == OpType::ONLY_UPDATE_GID || opType == OpType::LOCKED_NOT_HANDLE); } int SQLiteSingleVerRelationalStorageExecutor::UpdateLogRecord(const VBucket &vBucket, const TableSchema &tableSchema, @@ -1033,5 +1032,10 @@ int SQLiteSingleVerRelationalStorageExecutor::UpdateRecordStatus(const std::stri return errCode == E_OK ? ret : errCode; } +void SQLiteSingleVerRelationalStorageExecutor::SetUploadConfig(int32_t maxUploadCount, int32_t maxUploadSize) +{ + maxUploadCount_ = maxUploadCount; + maxUploadSize_ = maxUploadSize; +} } // namespace DistributedDB #endif diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_ver_relational_storage_extend_executor.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_ver_relational_storage_extend_executor.cpp index fcb0f731..44d2ee02 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_ver_relational_storage_extend_executor.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_ver_relational_storage_extend_executor.cpp @@ -78,7 +78,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetFillDownloadAssetStatement(cons sqlite3_stmt *stmt = nullptr; int errCode = SQLiteUtils::GetStatement(dbHandle_, sql, stmt); if (errCode != E_OK) { - LOGE("Get fill asset statement failed, %d", errCode); + LOGE("Get fill asset statement failed, %d.", errCode); return errCode; } for (size_t i = 0; i < fields.size(); ++i) { @@ -98,7 +98,7 @@ int SQLiteSingleVerRelationalStorageExecutor::FillCloudAssetForDownload(const Ta std::string cloudGid; int errCode = CloudStorageUtils::GetValueFromVBucket(CloudDbConstant::GID_FIELD, vBucket, cloudGid); if (errCode != E_OK) { - LOGE("Miss gid when fill Asset"); + LOGE("Miss gid when fill Asset."); return errCode; } std::vector assetsField; @@ -147,7 +147,7 @@ int SQLiteSingleVerRelationalStorageExecutor::FillCloudAssetForUpload(OpType opT } errCode = SetLogTriggerStatus(false); if (errCode != E_OK) { - LOGE("Fail to set log trigger off, %d", errCode); + LOGE("Fail to set log trigger off, %d.", errCode); return errCode; } sqlite3_stmt *stmt = nullptr; @@ -168,7 +168,7 @@ int SQLiteSingleVerRelationalStorageExecutor::FillCloudAssetForUpload(OpType opT } errCode = SQLiteUtils::StepWithRetry(stmt, false); if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) { - LOGE("Fill upload asset failed:%d", errCode); + LOGE("Fill upload asset failed:%d.", errCode); break; } errCode = E_OK; @@ -182,7 +182,7 @@ int SQLiteSingleVerRelationalStorageExecutor::FillCloudAssetForUpload(OpType opT SQLiteUtils::ResetStatement(stmt, true, ret); int endCode = SetLogTriggerStatus(true); if (endCode != E_OK) { - LOGE("Fail to set log trigger off, %d", endCode); + LOGE("Fail to set log trigger off, %d.", endCode); return endCode; } return errCode != E_OK ? errCode : ret; @@ -211,7 +211,7 @@ int SQLiteSingleVerRelationalStorageExecutor::BindUpdateVersionStatement(const V LOGW("get version from vBucket failed."); } if (hashKey.empty()) { - LOGE("hash key is empty when update version"); + LOGE("hash key is empty when update version."); return -E_CLOUD_ERROR; } errCode = SQLiteUtils::BindTextToStatement(stmt, 1, version); @@ -227,7 +227,7 @@ int SQLiteSingleVerRelationalStorageExecutor::BindUpdateVersionStatement(const V errCode = E_OK; SQLiteUtils::ResetStatement(stmt, false, errCode); } else { - LOGE("step version stmt failed:%d", errCode); + LOGE("step version stmt failed: %d.", errCode); } return errCode; } @@ -263,6 +263,7 @@ int SQLiteSingleVerRelationalStorageExecutor::InitFillUploadAssetStatement(OpTyp errCode = GetAndBindFillUploadAssetStatement(tableSchema.name, dbAssets, statement); if (errCode != E_OK) { + LOGE("get and bind asset failed %d.", errCode); return errCode; } int64_t rowid = data.rowid[index]; @@ -294,13 +295,13 @@ int SQLiteSingleVerRelationalStorageExecutor::CreateTrackerTable(const TrackerTa if (isUpgrade) { errCode = CleanExtendAndCursorForDeleteData(dbHandle_, table.GetTableName()); if (errCode != E_OK) { - LOGE("clean tracker log info for deleted data failed. %d", errCode); + LOGE("clean tracker log info for deleted data failed %d.", errCode); return errCode; } } errCode = GeneLogInfoForExistedData(dbHandle_, trackerTable.GetTableName(), calPrimaryKeyHash, table); if (errCode != E_OK) { - LOGE("general tracker log info for existed data failed. %d", errCode); + LOGE("general tracker log info for existed data failed %d.", errCode); return errCode; } } @@ -333,7 +334,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetOrInitTrackerSchemaFromMeta(Rel DBCommon::VectorToString(schemaVal, schemaStr); errCode = schema.ParseFromTrackerSchemaString(schemaStr); if (errCode != E_OK) { - LOGE("Parse from tracker schema string err"); + LOGE("Parse from tracker schema string err."); } return errCode; } @@ -343,12 +344,12 @@ int SQLiteSingleVerRelationalStorageExecutor::ExecuteSql(const SqlCondition &con sqlite3_stmt *statement = nullptr; int errCode = SQLiteUtils::GetStatement(dbHandle_, condition.sql, statement); if (errCode != E_OK) { - LOGE("Execute sql failed when prepare stmt"); + LOGE("Execute sql failed when prepare stmt."); return errCode; } size_t bindCount = static_cast(sqlite3_bind_parameter_count(statement)); if (bindCount > condition.bindArgs.size() || bindCount < condition.bindArgs.size()) { - LOGE("sql bind args mismatch"); + LOGE("Sql bind args mismatch."); SQLiteUtils::ResetStatement(statement, true, errCode); return -E_INVALID_ARGS; } @@ -386,7 +387,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetClearWaterMarkTables( bool isExists = false; int errCode = SQLiteUtils::CheckTableExists(dbHandle_, logTableName, isExists); if (errCode != E_OK) { - LOGE("[GetClearWaterMarkTables] check table exists failed, errCode = %d", errCode); + LOGE("[GetClearWaterMarkTables] check table exists failed, errCode = %d.", errCode); return errCode; } if (!isExists) { // table maybe dropped after set reference @@ -397,7 +398,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetClearWaterMarkTables( bool isEmpty = true; errCode = SQLiteUtils::CheckTableEmpty(dbHandle_, logTableName, isEmpty); if (errCode != E_OK) { - LOGE("[GetClearWaterMarkTables] check table empty failed, errCode = %d", errCode); + LOGE("[GetClearWaterMarkTables] check table empty failed, errCode = %d.", errCode); clearWaterMarkTables.clear(); return errCode; } @@ -405,7 +406,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetClearWaterMarkTables( clearWaterMarkTables.insert(table); } } - LOGI("[GetClearWaterMarkTables] clearWaterMarkTables size = %zu", clearWaterMarkTables.size()); + LOGI("[GetClearWaterMarkTables] clearWaterMarkTables size = %zu.", clearWaterMarkTables.size()); return E_OK; } @@ -455,23 +456,23 @@ int SQLiteSingleVerRelationalStorageExecutor::CreateTempSyncTrigger(const Tracke for (const auto &sql: dropSql) { errCode = SQLiteUtils::ExecuteRawSQL(dbHandle_, sql); if (errCode != E_OK) { - LOGE("[RDBExecutor] execute drop sql failed %d", errCode); + LOGE("[RDBExecutor] execute drop sql failed %d.", errCode); return errCode; } } errCode = SQLiteUtils::ExecuteRawSQL(dbHandle_, trackerTable.GetTempInsertTriggerSql()); if (errCode != E_OK) { - LOGE("[RDBExecutor] create temp insert trigger failed %d", errCode); + LOGE("[RDBExecutor] create temp insert trigger failed %d.", errCode); return errCode; } errCode = SQLiteUtils::ExecuteRawSQL(dbHandle_, trackerTable.GetTempUpdateTriggerSql()); if (errCode != E_OK) { - LOGE("[RDBExecutor] create temp update trigger failed %d", errCode); + LOGE("[RDBExecutor] create temp update trigger failed %d.", errCode); return errCode; } errCode = SQLiteUtils::ExecuteRawSQL(dbHandle_, trackerTable.GetTempDeleteTriggerSql()); if (errCode != E_OK) { - LOGE("[RDBExecutor] create temp delete trigger failed %d", errCode); + LOGE("[RDBExecutor] create temp delete trigger failed %d.", errCode); } return errCode; } @@ -494,7 +495,7 @@ int SQLiteSingleVerRelationalStorageExecutor::ClearAllTempSyncTrigger() static const std::string sql = "SELECT name FROM sqlite_temp_master WHERE type = 'trigger';"; int errCode = SQLiteUtils::GetStatement(dbHandle_, sql, stmt); if (errCode != E_OK) { - LOGE("get clear all temp trigger stmt failed. %d", errCode); + LOGE("get clear all temp trigger stmt failed %d.", errCode); return errCode; } int ret = E_OK; @@ -508,7 +509,7 @@ int SQLiteSingleVerRelationalStorageExecutor::ClearAllTempSyncTrigger() std::string dropSql = "DROP TRIGGER IF EXISTS '" + str + "';"; errCode = SQLiteUtils::ExecuteRawSQL(dbHandle_, dropSql); if (errCode != E_OK) { - LOGE("drop temp trigger failed. %d", errCode); + LOGE("drop temp trigger failed %d.", errCode); SQLiteUtils::ResetStatement(stmt, true, ret); return errCode; } @@ -524,13 +525,13 @@ int SQLiteSingleVerRelationalStorageExecutor::CleanTrackerData(const std::string sqlite3_stmt *statement = nullptr; int errCode = SQLiteUtils::GetStatement(dbHandle_, sql, statement); if (errCode != E_OK) { - LOGE("get clean tracker data stmt failed. %d", errCode); + LOGE("get clean tracker data stmt failed %d.", errCode); return errCode; } errCode = SQLiteUtils::BindInt64ToStatement(statement, 1, cursor); int ret = E_OK; if (errCode != E_OK) { - LOGE("bind clean tracker data stmt failed. %d", errCode); + LOGE("bind clean tracker data stmt failed %d.", errCode); SQLiteUtils::ResetStatement(statement, true, ret); return errCode; } @@ -538,7 +539,7 @@ int SQLiteSingleVerRelationalStorageExecutor::CleanTrackerData(const std::string if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) { errCode = E_OK; } else { - LOGE("clean tracker step failed:%d", errCode); + LOGE("clean tracker step failed: %d.", errCode); } SQLiteUtils::ResetStatement(statement, true, ret); return errCode == E_OK ? ret : errCode; @@ -579,7 +580,7 @@ int SQLiteSingleVerRelationalStorageExecutor::CreateSharedTable(const TableSchem createTableSql += ");"; int errCode = SQLiteUtils::ExecuteRawSQL(dbHandle_, createTableSql); if (errCode != E_OK) { - LOGE("Create shared table failed, %d", errCode); + LOGE("Create shared table failed, %d.", errCode); } return errCode; } @@ -590,7 +591,7 @@ int SQLiteSingleVerRelationalStorageExecutor::DeleteTable(const std::vector(CloudDbConstant::GID_FIELD, cloudDataResult.insData.extend[i], val) != E_OK) { errCode = -E_INVALID_DATA; - LOGE("[RDBExecutor] Can't get string gid from extend"); + LOGE("[RDBExecutor] Can't get string gid from extend."); break; } if (val.empty()) { errCode = -E_CLOUD_ERROR; - LOGE("[RDBExecutor] Get empty gid from extend"); + LOGE("[RDBExecutor] Get empty gid from extend."); break; } errCode = BindStmtWithCloudGidInner(val, cloudDataResult.insData.rowid[i], stmt, fillGidCount); if (errCode != E_OK) { - LOGE("[RDBExecutor] Bind stmt error %d", errCode); + LOGE("[RDBExecutor] Bind stmt error %d.", errCode); break; } } - LOGD("[RDBExecutor] Fill gid count %d", fillGidCount); + LOGD("[RDBExecutor] Fill gid count %d.", fillGidCount); return errCode; } @@ -903,7 +904,7 @@ int SQLiteSingleVerRelationalStorageExecutor::CleanExtendAndCursorForDeleteData( std::string sql = "UPDATE " + logTable + " SET extend_field = NULL, cursor = NULL where flag&0x01=0x01;"; int errCode = SQLiteUtils::ExecuteRawSQL(db, sql); if (errCode != E_OK) { - LOGE("update extend field and cursor failed. %d", errCode); + LOGE("update extend field and cursor failed %d.", errCode); } return errCode; } @@ -914,17 +915,17 @@ int SQLiteSingleVerRelationalStorageExecutor::CheckIfExistUserTable(const std::s sqlite3_stmt *statement = nullptr; int errCode = SQLiteUtils::GetStatement(dbHandle_, sql, statement); if (errCode != E_OK) { - LOGE("[RDBExecutor] Prepare the sql statement error:%d", errCode); + LOGE("[RDBExecutor] Prepare the sql statement error: %d.", errCode); return errCode; } errCode = SQLiteUtils::BindTextToStatement(statement, 1, tableName); if (errCode != E_OK) { - LOGE("[RDBExecutor] Bind table name failed:%d", errCode); + LOGE("[RDBExecutor] Bind table name failed: %d.", errCode); SQLiteUtils::ResetStatement(statement, true, errCode); return errCode; } if (SQLiteUtils::StepWithRetry(statement) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) { - LOGE("[RDBExecutor] local exists user table which shared table name is same as"); + LOGE("[RDBExecutor] local exists user table which shared table name is same as."); SQLiteUtils::ResetStatement(statement, true, errCode); return -E_INVALID_ARGS; } @@ -972,7 +973,7 @@ int64_t SQLiteSingleVerRelationalStorageExecutor::GetLocalDataKey(size_t index, const DownloadData &downloadData) { if (index >= downloadData.existDataKey.size()) { - LOGW("[RDBExecutor] index out of range when get local data key"); // should not happen + LOGW("[RDBExecutor] index out of range when get local data key."); // should not happen return -1; // -1 means not exist } return downloadData.existDataKey[index]; @@ -995,7 +996,7 @@ int SQLiteSingleVerRelationalStorageExecutor::BindStmtWithCloudGidInner(const st fillGidCount++; SQLiteUtils::ResetStatement(stmt, false, errCode); } else { - LOGE("[RDBExecutor] Update cloud log failed:%d", errCode); + LOGE("[RDBExecutor] Update cloud log failed: %d.", errCode); } return errCode; } @@ -1020,7 +1021,7 @@ int SQLiteSingleVerRelationalStorageExecutor::DoCleanAssetId(const std::string & std::vector fieldInfos = localSchema.GetTable(tableName).GetFieldInfos(); errCode = CleanAssetId(tableName, fieldInfos, dataKeys); if (errCode != E_OK) { - LOGE("[Storage Executor] failed to clean asset id when clean cloud data, %d", errCode); + LOGE("[Storage Executor] failed to clean asset id when clean cloud data, %d.", errCode); } return errCode; } @@ -1112,13 +1113,13 @@ int SQLiteSingleVerRelationalStorageExecutor::GetAssetsAndUpdateAssetsId(const s "' WHERE " + std::string(DBConstant::SQLITE_INNER_ROWID) + " = " + std::to_string(rowId) + ";"; errCode = SQLiteUtils::GetStatement(dbHandle_, queryAssetsSql, selectStmt); if (errCode != E_OK) { - LOGE("Get select assets statement failed, %d", errCode); + LOGE("Get select assets statement failed, %d.", errCode); goto END; } Assets assets; errCode = GetAssetsByRowId(selectStmt, assets); if (errCode != E_OK) { - LOGE("Get assets by rowId failed, %d", errCode); + LOGE("Get assets by rowId failed, %d.", errCode); goto END; } SQLiteUtils::ResetStatement(selectStmt, true, ret); @@ -1132,7 +1133,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetAssetsAndUpdateAssetsId(const s std::vector assetsValue; errCode = RuntimeContext::GetInstance()->AssetsToBlob(assets, assetsValue); if (errCode != E_OK) { - LOGE("[CleanAssetsIdOnUserTable] failed to transfer assets to blob, %d", errCode); + LOGE("[CleanAssetsIdOnUserTable] failed to transfer assets to blob, %d.", errCode); return errCode; } errCode = CleanAssetsIdOnUserTable(tableName, fieldName, rowId, assetsValue); @@ -1148,7 +1149,7 @@ END: } int SQLiteSingleVerRelationalStorageExecutor::CleanAssetsIdOnUserTable(const std::string &tableName, - const std::string &fieldName, const int64_t rowId, const std::vector assetsValue) + const std::string &fieldName, const int64_t rowId, const std::vector &assetsValue) { std::string cleanAssetIdSql = "UPDATE " + tableName + " SET " + fieldName + " = ? WHERE " + std::string(DBConstant::SQLITE_INNER_ROWID) + " = " + std::to_string(rowId) + ";"; @@ -1216,11 +1217,11 @@ std::pair SQLiteSingleVerRelationalStorageExecutor::GetAssetsByGi // Gid is different, there may be duplicate primary keys in the cloud errCode = -E_CLOUD_GID_MISMATCH; } - status = sqlite3_column_int(stmt, index++); + status = static_cast(sqlite3_column_int(stmt, index++)); } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) { errCode = -E_NOT_FOUND; } else { - LOGE("step get asset stmt failed. %d", errCode); + LOGE("step get asset stmt failed %d.", errCode); } SQLiteUtils::ResetStatement(stmt, true, errCode); return res; @@ -1231,21 +1232,21 @@ int SQLiteSingleVerRelationalStorageExecutor::InitGetAssetStmt(const std::string { int errCode = SQLiteUtils::GetStatement(dbHandle_, sql, stmt); if (errCode != E_OK) { - LOGE("Get asset statement failed, %d", errCode); + LOGE("Get asset statement failed, %d.", errCode); return errCode; } int index = 1; if (!gid.empty()) { errCode = SQLiteUtils::BindTextToStatement(stmt, index++, gid); if (errCode != E_OK) { - LOGE("bind gid failed. %d", errCode); + LOGE("bind gid failed %d.", errCode); SQLiteUtils::ResetStatement(stmt, true, errCode); return errCode; } } errCode = SQLiteUtils::BindBlobToStatement(stmt, index, hashKey); if (errCode != E_OK) { - LOGE("bind hash failed. %d", errCode); + LOGE("bind hash failed %d.", errCode); SQLiteUtils::ResetStatement(stmt, true, errCode); } return errCode; @@ -1310,18 +1311,18 @@ int SQLiteSingleVerRelationalStorageExecutor::GetAssetsByRowId(sqlite3_stmt *&se std::vector blobValue; errCode = SQLiteUtils::GetColumnBlobValue(selectStmt, 0, blobValue); if (errCode != E_OK) { - LOGE("Get column blob value failed. %d", errCode); + LOGE("Get column blob value failed %d.", errCode); return errCode; } errCode = RuntimeContext::GetInstance()->BlobToAssets(blobValue, assets); if (errCode != E_OK) { - LOGE("Transfer blob to assets failed. %d", errCode); + LOGE("Transfer blob to assets failed %d", errCode); } return errCode; } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) { return E_OK; } else { - LOGE("Step select statement failed. %d", errCode); + LOGE("Step select statement failed %d.", errCode); return errCode; } } @@ -1336,7 +1337,7 @@ int SQLiteSingleVerRelationalStorageExecutor::ExecuteFillDownloadAssetStatement( { int errCode = SQLiteUtils::BindTextToStatement(stmt, beginIndex, cloudGid); if (errCode != E_OK) { - LOGE("Bind cloud gid to statement failed. %d", errCode); + LOGE("Bind cloud gid to statement failed %d.", errCode); int ret = E_OK; SQLiteUtils::ResetStatement(stmt, true, ret); return errCode; @@ -1345,7 +1346,7 @@ int SQLiteSingleVerRelationalStorageExecutor::ExecuteFillDownloadAssetStatement( if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) { errCode = E_OK; } else { - LOGE("Fill cloud asset failed:%d", errCode); + LOGE("Fill cloud asset failed: %d.", errCode); } int ret = E_OK; SQLiteUtils::ResetStatement(stmt, true, ret); @@ -1366,7 +1367,7 @@ int SQLiteSingleVerRelationalStorageExecutor::CleanDownloadChangedAssets( } int ret = assetLoader_->RemoveLocalAssets(toDeleteAssets); if (ret != OK) { - LOGE("remove local assets failed. %d", ret); + LOGE("remove local assets failed %d.", ret); return -E_REMOVE_ASSETS_FAILED; } return E_OK; @@ -1401,7 +1402,8 @@ int SQLiteSingleVerRelationalStorageExecutor::GetAndBindFillUploadAssetStatement int SQLiteSingleVerRelationalStorageExecutor::OnlyUpdateAssetId(const std::string &tableName, const TableSchema &tableSchema, const VBucket &vBucket, int64_t dataKey, OpType opType) { - if (opType != OpType::ONLY_UPDATE_GID && opType != OpType::NOT_HANDLE) { + if (opType != OpType::ONLY_UPDATE_GID && opType != OpType::NOT_HANDLE && + opType != OpType::SET_CLOUD_FORCE_PUSH_FLAG_ZERO) { return E_OK; } if (CloudStorageUtils::IsSharedTable(tableSchema)) { @@ -1420,10 +1422,7 @@ void SQLiteSingleVerRelationalStorageExecutor::UpdateLocalAssetId(const VBucket { for (const auto &[col, value] : vBucket) { if (value.index() == TYPE_INDEX && col == fieldName) { - Asset cloudAsset = std::get(value); - if (cloudAsset.name == asset.name) { - asset.assetId = cloudAsset.assetId; - } + asset = std::get(value); } } } @@ -1433,8 +1432,7 @@ void SQLiteSingleVerRelationalStorageExecutor::UpdateLocalAssetsId(const VBucket { for (const auto &[col, value] : vBucket) { if (value.index() == TYPE_INDEX && col == fieldName) { - Assets cloudAssets = std::get(value); - UpdateLocalAssetsIdInner(cloudAssets, assets); + assets = std::get(value); } } } @@ -1456,12 +1454,12 @@ int SQLiteSingleVerRelationalStorageExecutor::BindAssetToBlobStatement(const Ass std::vector blobValue; int errCode = RuntimeContext::GetInstance()->AssetToBlob(asset, blobValue); if (errCode != E_OK) { - LOGE("Transfer asset to blob failed, %d", errCode); + LOGE("Transfer asset to blob failed, %d.", errCode); return errCode; } errCode = SQLiteUtils::BindBlobToStatement(stmt, index, blobValue, false); if (errCode != E_OK) { - LOGE("Bind asset blob to statement failed, %d", errCode); + LOGE("Bind asset blob to statement failed, %d.", errCode); } return errCode; } @@ -1472,12 +1470,12 @@ int SQLiteSingleVerRelationalStorageExecutor::BindAssetsToBlobStatement(const As std::vector blobValue; int errCode = RuntimeContext::GetInstance()->AssetsToBlob(assets, blobValue); if (errCode != E_OK) { - LOGE("Transfer asset to blob failed, %d", errCode); + LOGE("Transfer asset to blob failed, %d.", errCode); return errCode; } errCode = SQLiteUtils::BindBlobToStatement(stmt, index, blobValue, false); if (errCode != E_OK) { - LOGE("Bind asset blob to statement failed, %d", errCode); + LOGE("Bind asset blob to statement failed, %d.", errCode); } return errCode; } @@ -1489,18 +1487,17 @@ int SQLiteSingleVerRelationalStorageExecutor::GetAssetOnTableInner(sqlite3_stmt std::vector blobValue; errCode = SQLiteUtils::GetColumnBlobValue(stmt, 0, blobValue); if (errCode != E_OK) { - LOGE("[RDBExecutor] Get column blob value failed, %d", errCode); + LOGE("[RDBExecutor][GetAssetOnTableInner] Get column blob value failed, %d.", errCode); return errCode; } errCode = RuntimeContext::GetInstance()->BlobToAsset(blobValue, asset); if (errCode != E_OK) { - LOGE("[RDBExecutor] Transfer blob to asset failed, %d", errCode); + LOGE("[RDBExecutor] Transfer blob to asset failed, %d.", errCode); } - return errCode; } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) { - return E_OK; + errCode = E_OK; } else { - LOGE("[RDBExecutor] Step failed when get asset from table, errCode = %d", errCode); + LOGE("[RDBExecutor] Step failed when get asset from table, errCode = %d.", errCode); } return errCode; } @@ -1513,7 +1510,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetAssetOnTable(const std::string "' WHERE " + std::string(DBConstant::SQLITE_INNER_ROWID) + " = " + std::to_string(dataKey) + ";"; int errCode = SQLiteUtils::GetStatement(dbHandle_, queryAssetSql, selectStmt); if (errCode != E_OK) { - LOGE("Get select asset statement failed, %d", errCode); + LOGE("Get select asset statement failed, %d.", errCode); return errCode; } errCode = GetAssetOnTableInner(selectStmt, asset); @@ -1529,18 +1526,17 @@ int SQLiteSingleVerRelationalStorageExecutor::GetAssetsOnTableInner(sqlite3_stmt std::vector blobValue; errCode = SQLiteUtils::GetColumnBlobValue(stmt, 0, blobValue); if (errCode != E_OK) { - LOGE("[RDBExecutor] Get column blob value failed, %d", errCode); + LOGE("[RDBExecutor][GetAssetsOnTableInner] Get column blob value failed, %d.", errCode); return errCode; } errCode = RuntimeContext::GetInstance()->BlobToAssets(blobValue, assets); if (errCode != E_OK) { - LOGE("[RDBExecutor] Transfer blob to assets failed, %d", errCode); + LOGE("[RDBExecutor] Transfer blob to assets failed, %d.", errCode); } - return errCode; } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) { - return E_OK; + errCode = E_OK; } else { - LOGE("[RDBExecutor] Step failed when get assets from table, errCode = %d", errCode); + LOGE("[RDBExecutor] Step failed when get assets from table, errCode = %d.", errCode); } return errCode; } @@ -1553,7 +1549,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetAssetsOnTable(const std::string "' WHERE " + std::string(DBConstant::SQLITE_INNER_ROWID) + " = " + std::to_string(dataKey) + ";"; int errCode = SQLiteUtils::GetStatement(dbHandle_, queryAssetsSql, selectStmt); if (errCode != E_OK) { - LOGE("Get select assets statement failed, %d", errCode); + LOGE("Get select assets statement failed, %d.", errCode); return errCode; } errCode = GetAssetsOnTableInner(selectStmt, assets); @@ -1574,7 +1570,7 @@ int SQLiteSingleVerRelationalStorageExecutor::BindAssetFiledToBlobStatement(cons } int errCode = BindAssetToBlobStatement(assetOfOneRecord[assetIndex], assetIndex + assetsIndex + 1, stmt); if (errCode != E_OK) { - LOGE("Bind asset to blob statement failed, %d", errCode); + LOGE("Bind asset to blob statement failed, %d.", errCode); return errCode; } assetIndex++; @@ -1584,7 +1580,7 @@ int SQLiteSingleVerRelationalStorageExecutor::BindAssetFiledToBlobStatement(cons } int errCode = BindAssetsToBlobStatement(assetsOfOneRecord[assetsIndex], assetIndex + assetsIndex + 1, stmt); if (errCode != E_OK) { - LOGE("Bind assets to blob statement failed, %d", errCode); + LOGE("Bind assets to blob statement failed, %d.", errCode); return errCode; } assetsIndex++; @@ -1601,12 +1597,12 @@ int SQLiteSingleVerRelationalStorageExecutor::UpdateAssetsIdForOneRecord(const T sqlite3_stmt *stmt = nullptr; errCode = SQLiteUtils::GetStatement(dbHandle_, sql, stmt); if (errCode != E_OK) { - LOGE("Get update asset statement failed, %d", errCode); + LOGE("Get update asset statement failed, %d.", errCode); return errCode; } errCode = BindAssetFiledToBlobStatement(tableSchema, assetOfOneRecord, assetsOfOneRecord, stmt); if (errCode != E_OK) { - LOGE("Asset field Bind asset to blob statement failed, %d", errCode); + LOGE("Asset field Bind asset to blob statement failed, %d.", errCode); SQLiteUtils::ResetStatement(stmt, true, ret); return errCode != E_OK ? errCode : ret; } @@ -1630,33 +1626,19 @@ int SQLiteSingleVerRelationalStorageExecutor::UpdateAssetId(const TableSchema &t for (const auto &field : tableSchema.fields) { if (field.type == TYPE_INDEX) { Asset asset; - errCode = GetAssetOnTable(tableSchema.name, field.colName, dataKey, asset); - if (errCode != E_OK) { - LOGE("[Storage Executor] failed to get asset on table, %d.", errCode); - return errCode; - } - if (asset.name.empty()) { - assetOfOneRecord.push_back(asset); - continue; - } UpdateLocalAssetId(vBucket, field.colName, asset); assetOfOneRecord.push_back(asset); - updateAssetIdSql += " " + field.colName + " = ?,"; + if (!asset.name.empty()) { + updateAssetIdSql += " " + field.colName + " = ?,"; + } } if (field.type == TYPE_INDEX) { Assets assets; - errCode = GetAssetsOnTable(tableSchema.name, field.colName, dataKey, assets); - if (errCode != E_OK) { - LOGE("[Storage Executor] failed to get and save assets on table, %d.", errCode); - return errCode; - } - if (assets.empty()) { - assetsOfOneRecord.push_back(assets); - continue; - } UpdateLocalAssetsId(vBucket, field.colName, assets); assetsOfOneRecord.push_back(assets); - updateAssetIdSql += " " + field.colName + " = ?,"; + if (!assets.empty()) { + updateAssetIdSql += " " + field.colName + " = ?,"; + } } } if (updateAssetIdSql == "UPDATE " + tableSchema.name + " SET") { @@ -1808,7 +1790,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetWaitCompensatedSyncDataPk(const 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); + LOGE("[RDBExecutor] Get stmt failed when get wait compensated sync pk! errCode = %d..", errCode); return errCode; } do { @@ -1817,7 +1799,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetWaitCompensatedSyncDataPk(const 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); + LOGE("[RDBExecutor] Get record failed when get wait compensated sync pk! errCode = %d.", errCode); break; } data.push_back(pkData); @@ -1825,7 +1807,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetWaitCompensatedSyncDataPk(const errCode = E_OK; break; } else { - LOGE("[RDBExecutor] Step failed when get wait compensated sync pk! errCode = %d", errCode); + LOGE("[RDBExecutor] Step failed when get wait compensated sync pk! errCode = %d.", errCode); break; } } while (errCode == E_OK); @@ -1834,7 +1816,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetWaitCompensatedSyncDataPk(const return errCode == E_OK ? ret : errCode; } -int SQLiteSingleVerRelationalStorageExecutor::GetRecordFromStmt(sqlite3_stmt *stmt, const std::vector fields, +int SQLiteSingleVerRelationalStorageExecutor::GetRecordFromStmt(sqlite3_stmt *stmt, const std::vector &fields, int startIndex, VBucket &record) { int errCode = E_OK; @@ -1921,22 +1903,6 @@ int SQLiteSingleVerRelationalStorageExecutor::MarkFlagAsConsistent(const std::st return errCode == E_OK ? ret : errCode; } -int SQLiteSingleVerRelationalStorageExecutor::QueryCount(const std::string &tableName, int64_t &count) -{ - return SQLiteRelationalUtils::QueryCount(dbHandle_, tableName, count); -} - -int SQLiteSingleVerRelationalStorageExecutor::CheckInventoryData(const std::string &tableName) -{ - int64_t dataCount = 0; - int errCode = SQLiteRelationalUtils::QueryCount(dbHandle_, tableName, dataCount); - if (errCode != E_OK) { - LOGE("Query count failed.", errCode); - return errCode; - } - return dataCount > 0 ? -E_WITH_INVENTORY_DATA : E_OK; -} - int SQLiteSingleVerRelationalStorageExecutor::FillCloudVersionForUpload(const std::string &tableName, const CloudSyncBatch &batchData) { @@ -1966,5 +1932,21 @@ int SQLiteSingleVerRelationalStorageExecutor::FillCloudVersionForUpload(const st SQLiteUtils::ResetStatement(stmt, true, ret); return ret; } + +int SQLiteSingleVerRelationalStorageExecutor::QueryCount(const std::string &tableName, int64_t &count) +{ + return SQLiteRelationalUtils::QueryCount(dbHandle_, tableName, count); +} + +int SQLiteSingleVerRelationalStorageExecutor::CheckInventoryData(const std::string &tableName) +{ + int64_t dataCount = 0; + int errCode = SQLiteRelationalUtils::QueryCount(dbHandle_, tableName, dataCount); + if (errCode != E_OK) { + LOGE("Query count failed.", errCode); + return errCode; + } + return dataCount > 0 ? -E_WITH_INVENTORY_DATA : E_OK; +} } // namespace DistributedDB #endif \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_cloud_kv_executor_utils.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_cloud_kv_executor_utils.cpp index 59d7272b..2e8b68aa 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_cloud_kv_executor_utils.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_cloud_kv_executor_utils.cpp @@ -16,14 +16,15 @@ #include "sqlite_cloud_kv_executor_utils.h" #include "cloud/cloud_db_constant.h" #include "cloud/cloud_storage_utils.h" +#include "db_base64_utils.h" #include "db_common.h" #include "res_finalizer.h" #include "runtime_context.h" #include "sqlite_single_ver_storage_executor_sql.h" namespace DistributedDB { -int SqliteCloudKvExecutorUtils::GetCloudData(sqlite3 *db, bool isMemory, SQLiteSingleVerContinueToken &token, - CloudSyncData &data) +int SqliteCloudKvExecutorUtils::GetCloudData(const CloudSyncConfig &config, sqlite3 *db, bool isMemory, + SQLiteSingleVerContinueToken &token, CloudSyncData &data) { bool stepNext = false; auto [errCode, stmt] = token.GetCloudQueryStmt(db, data.isCloudForcePushStrategy, stepNext, data.mode); @@ -42,18 +43,54 @@ int SqliteCloudKvExecutorUtils::GetCloudData(sqlite3 *db, bool isMemory, SQLiteS } } stepNext = true; - errCode = GetCloudDataForSync(stmt, data, ++stepNum, totalSize); + errCode = GetCloudDataForSync(config, stmt, data, stepNum, totalSize); + stepNum++; } while (errCode == E_OK); LOGI("[SqliteCloudKvExecutorUtils] Get cloud sync data, insData:%u, upData:%u, delLog:%u errCode:%d", data.insData.record.size(), data.updData.record.size(), data.delData.extend.size(), errCode); if (errCode != -E_UNFINISHED) { token.ReleaseCloudQueryStmt(); + } else if (isMemory && UpdateBeginTimeForMemoryDB(token, data)) { + token.ReleaseCloudQueryStmt(); } return errCode; } -int SqliteCloudKvExecutorUtils::GetCloudDataForSync(sqlite3_stmt *statement, CloudSyncData &cloudDataResult, - uint32_t &stepNum, uint32_t &totalSize) +Timestamp SqliteCloudKvExecutorUtils::GetMaxTimeStamp(std::vector &dataExtend) +{ + Timestamp maxTimeStamp = 0; + VBucket lastRecord = dataExtend.back(); + auto it = lastRecord.find(CloudDbConstant::MODIFY_FIELD); + if (it != lastRecord.end() && maxTimeStamp < static_cast(std::get(it->second))) { + maxTimeStamp = static_cast(std::get(it->second)); + } + return maxTimeStamp; +} + +bool SqliteCloudKvExecutorUtils::UpdateBeginTimeForMemoryDB(SQLiteSingleVerContinueToken &token, CloudSyncData &data) +{ + Timestamp maxTimeStamp = 0; + switch (data.mode) { + case DistributedDB::CloudWaterType::DELETE: + maxTimeStamp = GetMaxTimeStamp(data.delData.extend); + break; + case DistributedDB::CloudWaterType::UPDATE: + maxTimeStamp = GetMaxTimeStamp(data.updData.extend); + break; + case DistributedDB::CloudWaterType::INSERT: + maxTimeStamp = GetMaxTimeStamp(data.insData.extend); + break; + } + if (maxTimeStamp > token.GetQueryBeginTime()) { + token.SetNextBeginTime("", maxTimeStamp); + return true; + } + LOGW("[SqliteCloudKvExecutorUtils] The start time of the in memory database has not been updated."); + return false; +} + +int SqliteCloudKvExecutorUtils::GetCloudDataForSync(const CloudSyncConfig &config, sqlite3_stmt *statement, + CloudSyncData &cloudDataResult, uint32_t &stepNum, uint32_t &totalSize) { VBucket log; VBucket extraLog; @@ -75,13 +112,13 @@ int SqliteCloudKvExecutorUtils::GetCloudDataForSync(sqlite3_stmt *statement, Clo } } - if (CloudStorageUtils::IsGetCloudDataContinue(stepNum, totalSize, CloudDbConstant::MAX_UPLOAD_SIZE)) { + if (CloudStorageUtils::IsGetCloudDataContinue(stepNum, totalSize, config.maxUploadSize, config.maxUploadCount)) { errCode = CloudStorageUtils::IdentifyCloudType(cloudDataResult, data, log, extraLog); } else { errCode = -E_UNFINISHED; } if (errCode == E_OK) { - errCode = CheckIgnoreData(data, extraLog); + errCode = CheckIgnoreData(config, data, extraLog); } if (errCode == -E_IGNORE_DATA) { errCode = E_OK; @@ -162,23 +199,26 @@ int SqliteCloudKvExecutorUtils::GetCloudKvBlobData(const std::string &keyStr, in } std::string tmp = std::string(blob.begin(), blob.end()); if ((keyStr == CloudDbConstant::CLOUD_KV_FIELD_DEVICE || - keyStr == CloudDbConstant::CLOUD_KV_FIELD_ORI_DEVICE) && tmp.empty()) { - (void)RuntimeContext::GetInstance()->GetLocalIdentity(tmp); - tmp = DBCommon::TransferHashString(tmp); + keyStr == CloudDbConstant::CLOUD_KV_FIELD_ORI_DEVICE)) { + if (tmp.empty()) { + (void)RuntimeContext::GetInstance()->GetLocalIdentity(tmp); + tmp = DBCommon::TransferHashString(tmp); + } + tmp = DBBase64Utils::Encode(std::vector(tmp.begin(), tmp.end())); } totalSize += tmp.size(); data.insert_or_assign(keyStr, tmp); return E_OK; } -int SqliteCloudKvExecutorUtils::CheckIgnoreData(VBucket &data, VBucket &flags) +int SqliteCloudKvExecutorUtils::CheckIgnoreData(const CloudSyncConfig &config, VBucket &data, VBucket &flags) { auto iter = data.find(CloudDbConstant::CLOUD_KV_FIELD_VALUE); if (iter == data.end()) { return E_OK; } auto &valueStr = std::get(iter->second); - if (valueStr.size() <= CloudDbConstant::MAX_UPLOAD_SIZE) { + if (valueStr.size() <= static_cast(config.maxUploadSize)) { return E_OK; } Bytes *hashKey = std::get_if(&flags[CloudDbConstant::HASH_KEY]); @@ -226,9 +266,11 @@ std::pair SqliteCloudKvExecutorUtils::GetLogInfoStmt(sqlite3 std::pair res; auto &[errCode, stmt] = res; std::string sql = QUERY_CLOUD_SYNC_DATA_LOG; - std::string hashKey; + sql += " WHERE cloud_gid = ?"; if (existKey) { - sql += "OR key = ?"; + sql += " UNION "; + sql += QUERY_CLOUD_SYNC_DATA_LOG; + sql += " WHERE key = ?"; } errCode = SQLiteUtils::GetStatement(db, sql, stmt); return res; @@ -340,11 +382,11 @@ int SqliteCloudKvExecutorUtils::ExecutePutCloudData(sqlite3 *db, bool isMemory, if (errCode != E_OK) { break; } + [[fallthrough]]; case OpType::ONLY_UPDATE_GID: // fallthrough case OpType::NOT_HANDLE: // fallthrough - errCode = OnlyUpdateLogTable(db, isMemory, index, downloadData); - break; case OpType::CLEAR_GID: // fallthrough + errCode = OnlyUpdateLogTable(db, isMemory, index, op, downloadData); break; default: errCode = -E_CLOUD_ERROR; @@ -419,9 +461,9 @@ std::string SqliteCloudKvExecutorUtils::GetOperateDataSql(OpType opType) std::string SqliteCloudKvExecutorUtils::GetOperateLogSql(OpType opType) { switch (opType) { - case OpType::INSERT: + case OpType::INSERT: // fallthrough + case OpType::UPDATE: return INSERT_CLOUD_SYNC_DATA_LOG; - case OpType::UPDATE: // fallthrough case OpType::DELETE: return UPDATE_CLOUD_SYNC_DATA_LOG; default: @@ -443,6 +485,8 @@ int SqliteCloudKvExecutorUtils::BindStmt(sqlite3_stmt *logStmt, sqlite3_stmt *da return BindUpdateStmt(logStmt, dataStmt, downloadData.user, dataItem); case OpType::DELETE: dataItem.hashKey = downloadData.existDataHashKey[index]; + dataItem.gid.clear(); + dataItem.version.clear(); return BindDeleteStmt(logStmt, dataStmt, downloadData.user, dataItem); default: return E_OK; @@ -452,7 +496,7 @@ int SqliteCloudKvExecutorUtils::BindStmt(sqlite3_stmt *logStmt, sqlite3_stmt *da int SqliteCloudKvExecutorUtils::BindInsertStmt(sqlite3_stmt *logStmt, sqlite3_stmt *dataStmt, const std::string &user, const DataItem &dataItem) { - int errCode = BindInsertLogStmt(logStmt, user, dataItem); + int errCode = BindInsertLogStmt(logStmt, user, dataItem); // insert or replace LOG table for insert DATA table. if (errCode != E_OK) { return errCode; } @@ -489,7 +533,7 @@ int SqliteCloudKvExecutorUtils::BindInsertLogStmt(sqlite3_stmt *logStmt, const s int SqliteCloudKvExecutorUtils::BindUpdateStmt(sqlite3_stmt *logStmt, sqlite3_stmt *dataStmt, const std::string &user, const DataItem &dataItem) { - int errCode = BindUpdateLogStmt(logStmt, user, dataItem); + int errCode = BindInsertLogStmt(logStmt, user, dataItem); // insert or replace LOG table for update DATA table. if (errCode != E_OK) { return errCode; } @@ -532,7 +576,15 @@ int SqliteCloudKvExecutorUtils::BindDeleteStmt(sqlite3_stmt *logStmt, sqlite3_st dataItem.key = {}; dataItem.value = {}; dataItem.flag |= static_cast(LogInfoFlag::FLAG_DELETE); - return BindUpdateStmt(logStmt, dataStmt, user, dataItem); + int errCode = BindUpdateLogStmt(logStmt, user, dataItem); // update LOG table for delete DATA table. + if (errCode != E_OK) { + return errCode; + } + errCode = BindDataStmt(dataStmt, dataItem, false); + if (errCode != E_OK) { + return errCode; + } + return E_OK; } int SqliteCloudKvExecutorUtils::BindDataStmt(sqlite3_stmt *dataStmt, const DataItem &dataItem, bool isInsert) @@ -657,7 +709,8 @@ int SqliteCloudKvExecutorUtils::FillCloudLog(sqlite3 *db, OpType opType, const C } } -int SqliteCloudKvExecutorUtils::OnlyUpdateLogTable(sqlite3 *db, bool isMemory, int index, DownloadData &downloadData) +int SqliteCloudKvExecutorUtils::OnlyUpdateLogTable(sqlite3 *db, bool isMemory, int index, OpType op, + DownloadData &downloadData) { if (downloadData.existDataHashKey[index].empty()) { return E_OK; @@ -681,6 +734,15 @@ int SqliteCloudKvExecutorUtils::OnlyUpdateLogTable(sqlite3 *db, bool isMemory, i LOGE("[SqliteCloudKvExecutorUtils] Get data item failed %d", res.first); return res.first; } + bool clearCloudInfo = (op == OpType::CLEAR_GID); + if (res.second.hashKey.empty() || DBCommon::IsRecordDelete(downloadData.data[index])) { + res.second.hashKey = downloadData.existDataHashKey[index]; + clearCloudInfo = true; + } + if (clearCloudInfo) { + res.second.gid.clear(); + res.second.version.clear(); + } errCode = BindInsertLogStmt(logStmt, downloadData.user, res.second); if (errCode != E_OK) { return errCode; @@ -820,13 +882,22 @@ std::pair SqliteCloudKvExecutorUtils::GetDataItem(int index, Down std::string dev; (void)RuntimeContext::GetInstance()->GetLocalIdentity(dev); dev = DBCommon::TransferHashString(dev); + auto decodeDevice = DBBase64Utils::Decode(dataItem.dev); + if (!decodeDevice.empty()) { + dataItem.dev = std::string(decodeDevice.begin(), decodeDevice.end()); + } if (dataItem.dev == dev) { dataItem.dev = ""; } + decodeDevice = DBBase64Utils::Decode(dataItem.origDev); + if (!decodeDevice.empty()) { + dataItem.origDev = std::string(decodeDevice.begin(), decodeDevice.end()); + } if (dataItem.origDev == dev) { dataItem.origDev = ""; } - dataItem.timestamp = dataItem.modifyTime + downloadData.timeOffset; + dataItem.timestamp = static_cast(static_cast(dataItem.modifyTime) + downloadData.timeOffset); + dataItem.writeTimestamp = dataItem.timestamp; // writeTimestamp is process conflict time return res; } @@ -882,7 +953,7 @@ std::pair SqliteCloudKvExecutorUtils::CountAllCloudData(sqlite3 *d if (timestampVec.size() != 3) { // 3 is the number of three mode. return std::pair(-E_INVALID_ARGS, 0); } - std::vector typeVec = {CloudWaterType::DELETE, CloudWaterType::UPDATE, CloudWaterType::INSERT}; + std::vector typeVec = DBCommon::GetWaterTypeVec(); std::pair result = std::pair(E_OK, 0); for (size_t i = 0; i < typeVec.size(); i++) { std::string sql = SqliteQueryHelper::GetKvCloudQuerySql(true, forcePush); @@ -967,7 +1038,8 @@ std::pair SqliteCloudKvExecutorUtils::GetLocalCloudVersionIn }); std::string hashDev; (void)RuntimeContext::GetInstance()->GetLocalIdentity(hashDev); - hashDev = DBCommon::TransferHashString(hashDev); + std::string tempDev = DBCommon::TransferHashString(hashDev); + hashDev = DBCommon::TransferStringToHex(tempDev); std::string key = CloudDbConstant::CLOUD_VERSION_RECORD_PREFIX_KEY + hashDev; Key keyVec; DBCommon::StringToVector(key, keyVec); @@ -981,7 +1053,7 @@ std::pair SqliteCloudKvExecutorUtils::GetLocalCloudVersionIn } errCode = GetCloudVersionRecord(isMemory, stmt, syncData); if (errCode == -E_NOT_FOUND) { - InitDefaultCloudVersionRecord(key, hashDev, syncData); + InitDefaultCloudVersionRecord(key, tempDev, syncData); errCode = E_OK; } return res; @@ -991,7 +1063,6 @@ int SqliteCloudKvExecutorUtils::GetCloudVersionRecord(bool isMemory, sqlite3_stm { int errCode = SQLiteUtils::StepNext(stmt, isMemory); if (errCode == -E_FINISHED) { - LOGE("[SqliteCloudKvExecutorUtils] Not found local version record"); return -E_NOT_FOUND; } if (errCode != E_OK) { @@ -1000,21 +1071,25 @@ int SqliteCloudKvExecutorUtils::GetCloudVersionRecord(bool isMemory, sqlite3_stm } uint32_t stepNum = 0; uint32_t totalSize = 0; - errCode = GetCloudDataForSync(stmt, syncData, stepNum, totalSize); + CloudSyncConfig config; + config.maxUploadSize = CloudDbConstant::MAX_UPLOAD_SIZE; + config.maxUploadCount = 1; + errCode = GetCloudDataForSync(config, stmt, syncData, stepNum, totalSize); return errCode; } void SqliteCloudKvExecutorUtils::InitDefaultCloudVersionRecord(const std::string &key, const std::string &dev, CloudSyncData &syncData) { + LOGI("[SqliteCloudKvExecutorUtils] Not found local version record"); VBucket defaultRecord; defaultRecord[CloudDbConstant::CLOUD_KV_FIELD_KEY] = key; - defaultRecord[CloudDbConstant::CLOUD_KV_FIELD_VALUE] = {}; + defaultRecord[CloudDbConstant::CLOUD_KV_FIELD_VALUE] = std::string(""); defaultRecord[CloudDbConstant::CLOUD_KV_FIELD_DEVICE] = dev; defaultRecord[CloudDbConstant::CLOUD_KV_FIELD_ORI_DEVICE] = dev; syncData.insData.record.push_back(std::move(defaultRecord)); VBucket defaultExtend; - defaultExtend[CloudDbConstant::HASH_KEY_FIELD] = key; + defaultExtend[CloudDbConstant::HASH_KEY_FIELD] = DBCommon::TransferStringToHex(key); syncData.insData.extend.push_back(std::move(defaultExtend)); syncData.insData.assets.emplace_back(); Bytes bytesHashKey; @@ -1031,10 +1106,10 @@ int SqliteCloudKvExecutorUtils::BindVersionStmt(const std::string &device, const if (device == hashDevice) { DBCommon::StringToVector("", bytes); } else { - DBCommon::StringToVector(device, bytes); + hashDevice = DBCommon::TransferHashString(device); + DBCommon::StringToVector(hashDevice, bytes); } - int index = 1; - int errCode = SQLiteUtils::BindBlobToStatement(dataStmt, index, bytes); + int errCode = SQLiteUtils::BindBlobToStatement(dataStmt, BIND_CLOUD_VERSION_DEVICE_INDEX, bytes); if (errCode != E_OK) { LOGE("[SqliteCloudKvExecutorUtils] Bind device failed %d", errCode); } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_cloud_kv_executor_utils.h b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_cloud_kv_executor_utils.h index d95b296c..a347c750 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_cloud_kv_executor_utils.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_cloud_kv_executor_utils.h @@ -26,7 +26,8 @@ namespace DistributedDB { class SqliteCloudKvExecutorUtils { public: - static int GetCloudData(sqlite3 *db, bool isMemory, SQLiteSingleVerContinueToken &token, CloudSyncData &data); + static int GetCloudData(const CloudSyncConfig &config, sqlite3 *db, bool isMemory, + SQLiteSingleVerContinueToken &token, CloudSyncData &data); static std::pair GetLogInfo(sqlite3 *db, bool isMemory, const VBucket &cloudData); @@ -46,8 +47,8 @@ public: static int GetCloudVersionFromCloud(sqlite3 *db, bool isMemory, const std::string &user, const std::string &device, std::vector &dataVector); private: - static int GetCloudDataForSync(sqlite3_stmt *statement, CloudSyncData &cloudDataResult, uint32_t &stepNum, - uint32_t &totalSize); + static int GetCloudDataForSync(const CloudSyncConfig &config, sqlite3_stmt *statement, + CloudSyncData &cloudDataResult, uint32_t &stepNum, uint32_t &totalSize); static void GetCloudLog(sqlite3_stmt *stmt, VBucket &logInfo, uint32_t &totalSize); @@ -58,7 +59,7 @@ private: static int GetCloudKvBlobData(const std::string &keyStr, int index, sqlite3_stmt *stmt, VBucket &data, uint32_t &totalSize); - static int CheckIgnoreData(VBucket &data, VBucket &flags); + static int CheckIgnoreData(const CloudSyncConfig &config, VBucket &data, VBucket &flags); static std::pair GetLogInfoStmt(sqlite3 *db, const VBucket &cloudData, bool existKey); @@ -102,7 +103,7 @@ private: static int StepStmt(sqlite3_stmt *logStmt, sqlite3_stmt *dataStmt, bool isMemory); - static int OnlyUpdateLogTable(sqlite3 *db, bool isMemory, int index, DownloadData &downloadData); + static int OnlyUpdateLogTable(sqlite3 *db, bool isMemory, int index, OpType op, DownloadData &downloadData); static int OnlyUpdateSyncData(sqlite3 *db, bool isMemory, int index, OpType opType, DownloadData &downloadData); @@ -129,6 +130,10 @@ private: static int BindVersionStmt(const std::string &device, const std::string &user, sqlite3_stmt *dataStmt); static int GetCloudVersionRecordData(sqlite3_stmt *stmt, VBucket &data, uint32_t &totalSize); + + static Timestamp GetMaxTimeStamp(std::vector &dataExtend); + + static bool UpdateBeginTimeForMemoryDB(SQLiteSingleVerContinueToken &token, CloudSyncData &data); }; } #endif // SQLITE_CLOUD_KV_EXECUTOR_UTILS_H \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_cloud_kv_store.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_cloud_kv_store.cpp index b13f1690..f02f389e 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_cloud_kv_store.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_cloud_kv_store.cpp @@ -49,6 +49,9 @@ int SqliteCloudKvStore::SetCloudDbSchema(const DataBaseSchema &schema) int SqliteCloudKvStore::SetCloudDbSchema(const std::map &schema) { std::lock_guard autoLock(schemaMutex_); + if (!CheckSchema(schema)) { + return -E_INVALID_SCHEMA; + } schema_ = schema; return E_OK; } @@ -68,11 +71,12 @@ int SqliteCloudKvStore::GetCloudTableSchema(const TableName &tableName, LOGE("[SqliteCloudKvStore] not set cloud schema"); return -E_NOT_FOUND; } - for (const auto &table : schema_[user_].tables) { - if (table.name == tableName) { - tableSchema = table; - return E_OK; - } + auto it = std::find_if(schema_[user_].tables.begin(), schema_[user_].tables.end(), [&](const auto &table) { + return table.name == tableName; + }); + if (it != schema_[user_].tables.end()) { + tableSchema = *it; + return E_OK; } LOGW("[SqliteCloudKvStore] not found table schema"); return -E_NOT_FOUND; @@ -200,7 +204,7 @@ int SqliteCloudKvStore::GetCloudDataNext(ContinueToken &continueStmtToken, Cloud ReleaseCloudDataToken(continueStmtToken); return -E_INTERNAL_ERROR; } - int errCode = SqliteCloudKvExecutorUtils::GetCloudData(db, isMemory, *token, cloudDataResult); + int errCode = SqliteCloudKvExecutorUtils::GetCloudData(GetCloudSyncConfig(), db, isMemory, *token, cloudDataResult); if (errCode != -E_UNFINISHED) { ReleaseCloudDataToken(continueStmtToken); } else { @@ -256,11 +260,26 @@ int SqliteCloudKvStore::FillCloudLogAndAsset(OpType opType, const CloudSyncData LOGE("[SqliteCloudKvStore] get handle failed %d when fill log", errCode); return errCode; } + if (handle->IsMemory()) { + errCode = Commit(); + if (errCode != E_OK) { + LOGE("[SqliteCloudKvStore] commit failed %d before fill log", errCode); + storageHandle_->RecycleStorageExecutor(handle); + return errCode; + } + } sqlite3 *db = nullptr; (void)handle->GetDbHandle(db); errCode = SqliteCloudKvExecutorUtils::FillCloudLog(db, opType, data, user_, ignoreEmptyGid); + int ret = E_OK; + if (handle->IsMemory()) { + ret = StartTransaction(TransactType::DEFERRED); + if (ret != E_OK) { + LOGE("[SqliteCloudKvStore] restart transaction failed %d", ret); + } + } storageHandle_->RecycleStorageExecutor(handle); - return errCode; + return errCode == E_OK ? ret : errCode; } void SqliteCloudKvStore::FilterCloudVersionPrefixKey(std::vector> &changeValList) @@ -287,30 +306,29 @@ void SqliteCloudKvStore::FilterCloudVersionPrefixKey(std::vector triggerActions; { std::lock_guard autoLock(observerMapMutex_); - for (const auto &item : cloudObserverMap_) { - if (item.second) { - triggerActions.push_back(item.second); - } + if (cloudObserverMap_.empty()) { + return; } } - if (triggerActions.empty()) { - return; - } for (auto &changeValList : changedData.primaryData) { FilterCloudVersionPrefixKey(changeValList); } - int errCode = RuntimeContext::GetInstance()->ScheduleTask([triggerActions, deviceName, - changedData, isChangedData]() { - for (const auto &item : triggerActions) { - ChangedData observerChangeData = changedData; - item(deviceName, std::move(observerChangeData), isChangedData); + RefObject::IncObjRef(this); + int errCode = RuntimeContext::GetInstance()->ScheduleTask([this, deviceName, changedData, isChangedData]() { + { + std::lock_guard autoLock(observerMapMutex_); + for (const auto &item : cloudObserverMap_) { + ChangedData observerChangeData = changedData; + item.second(deviceName, std::move(observerChangeData), isChangedData); + } } + RefObject::DecObjRef(this); }); if (errCode != E_OK) { LOGW("[SqliteCloudKvStore] Trigger observer action failed %d", errCode); + RefObject::DecObjRef(this); } } @@ -438,4 +456,61 @@ void SqliteCloudKvStore::FillTimestamp(Timestamp rawSystemTime, Timestamp virtua } } } + +bool SqliteCloudKvStore::CheckSchema(std::map schema) +{ + if (schema.size() == 0) { + LOGE("[SqliteCloudKvStore] empty schema."); + return false; + } + for (auto it = schema.begin(); it != schema.end(); it++) { + std::vector tables = it->second.tables; + if (tables.size() != 1) { + LOGE("[SqliteCloudKvStore] invalid tables num: %zu", tables.size()); + return false; + } + TableSchema actualTable = tables[0]; + std::string expectTableName = CloudDbConstant::CLOUD_KV_TABLE_NAME; + std::string expectSharedTableName = ""; + std::vector expectFields = { + {CloudDbConstant::CLOUD_KV_FIELD_KEY, TYPE_INDEX, true, true}, + {CloudDbConstant::CLOUD_KV_FIELD_DEVICE, TYPE_INDEX, false, true}, + {CloudDbConstant::CLOUD_KV_FIELD_ORI_DEVICE, TYPE_INDEX, false, true}, + {CloudDbConstant::CLOUD_KV_FIELD_VALUE, TYPE_INDEX, false, true}, + {CloudDbConstant::CLOUD_KV_FIELD_DEVICE_CREATE_TIME, TYPE_INDEX, false, true} + }; + if (actualTable.name != expectTableName || actualTable.sharedTableName != expectSharedTableName || + actualTable.fields.size() != expectFields.size()) { + LOGE("[SqliteCloudKvStore] check table failed."); + return false; + } + for (uint32_t i = 0; i < actualTable.fields.size(); i++) { + Field actualField = actualTable.fields[i]; + auto it = std::find(expectFields.begin(), expectFields.end(), actualField); + if (it == expectFields.end()) { + LOGE("[SqliteCloudKvStore] check fields failed."); + return false; + } + } + } + return true; +} + +void SqliteCloudKvStore::SetCloudSyncConfig(const CloudSyncConfig &config) +{ + std::lock_guard autoLock(configMutex_); + config_ = config; +} + +CloudSyncConfig SqliteCloudKvStore::GetCloudSyncConfig() const +{ + std::lock_guard autoLock(configMutex_); + return config_; +} + +std::map SqliteCloudKvStore::GetDataBaseSchemas() +{ + std::lock_guard autoLock(schemaMutex_); + return schema_; +} } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_cloud_kv_store.h b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_cloud_kv_store.h index e7480cd0..9f905e31 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_cloud_kv_store.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_cloud_kv_store.h @@ -88,6 +88,12 @@ public: int GetCloudVersion(const std::string &device, std::map &versionMap); std::pair GetLocalCloudVersion() override; + + void SetCloudSyncConfig(const CloudSyncConfig &config); + + CloudSyncConfig GetCloudSyncConfig() const override; + + std::map GetDataBaseSchemas(); private: std::pair GetTransactionDbHandleAndMemoryStatus(); @@ -95,6 +101,8 @@ private: static void FilterCloudVersionPrefixKey(std::vector> &changeValList); + bool CheckSchema(std::map schema); + KvStorageHandle *storageHandle_; std::mutex schemaMutex_; @@ -107,6 +115,9 @@ private: std::mutex observerMapMutex_; std::map cloudObserverMap_; + + mutable std::mutex configMutex_; + CloudSyncConfig config_; }; } #endif // SQLITE_CLOUD_STORE_H \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_log_table_manager.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_log_table_manager.cpp index e1e3d2cb..9acd7e0d 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_log_table_manager.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_log_table_manager.cpp @@ -92,7 +92,12 @@ int SqliteLogTableManager::CreateKvSyncLogTable(sqlite3 *db) LOGE("[LogTableManager] execute create cloud log table schema failed, errCode=%d", errCode); return errCode; } - return E_OK; + std::string createIndexSql = "CREATE INDEX IF NOT EXISTS gid_hash_key ON " + tableName + "(cloud_gid, hash_key)"; + errCode = SQLiteUtils::ExecuteRawSQL(db, createIndexSql); + if (errCode != E_OK) { + LOGE("[LogTableManager] execute create gid index failed, errCode=%d", errCode); + } + return errCode; } void SqliteLogTableManager::GetIndexSql(const TableInfo &table, std::vector &schema) diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_multi_ver_transaction.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_multi_ver_transaction.cpp index 1d4ef5b1..aa2b5fa1 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_multi_ver_transaction.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_multi_ver_transaction.cpp @@ -579,7 +579,7 @@ int SQLiteMultiVerTransaction::GetPrePutValues(const Version &versionInfo, Times } // bind the clear timestamp - errCode = sqlite3_bind_int64(statement, 2, timestamp); // bind the second argument for timestamp; + errCode = sqlite3_bind_int64(statement, 2, timestamp); // 2 is timestamp; bind the second argument for timestamp; if (errCode != SQLITE_OK) { LOGE("bind the clear timestamp for delete ver data error:%d", errCode); errCode = SQLiteUtils::MapSQLiteErrno(errCode); @@ -626,7 +626,7 @@ int SQLiteMultiVerTransaction::RemovePrePutEntries(const Version &versionInfo, T } // bind the clear timestamp - errCode = sqlite3_bind_int64(statement, 2, timestamp); // bind the second argument for timestamp; + errCode = sqlite3_bind_int64(statement, 2, timestamp); // 2 is timestamp; bind the 2nd argument for timestamp; if (errCode != SQLITE_OK) { LOGE("bind the clear timestamp for delete ver data error:%d", errCode); errCode = SQLiteUtils::MapSQLiteErrno(errCode); @@ -884,7 +884,7 @@ int SQLiteMultiVerTransaction::GetOverwrittenClearTypeEntries(Version clearVersi goto END; } trimedVerData.operFlag = operFlag & OPERATE_MASK; - trimedVerData.version = static_cast(sqlite3_column_int64(statement, 2)); // get the 3rd for ver + trimedVerData.version = static_cast(sqlite3_column_int64(statement, 2)); // 2 is ver for getting data.push_front(trimedVerData); } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) { errCode = E_OK; @@ -930,7 +930,7 @@ int SQLiteMultiVerTransaction::GetOverwrittenNonClearTypeEntries(Version version } trimedVerData.operFlag = operFlag & OPERATE_MASK; // get the meta flag - trimedVerData.version = static_cast(sqlite3_column_int64(statement, 2)); // get the 3rd for ver + trimedVerData.version = static_cast(sqlite3_column_int64(statement, 2)); // 2 is ver for getting data.push_front(trimedVerData); } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) { errCode = E_OK; @@ -988,15 +988,15 @@ int SQLiteMultiVerTransaction::GetRawMultiVerEntry(sqlite3_stmt *statement, Mult return errCode; } - uint64_t flag = static_cast(sqlite3_column_int64(statement, 2)); // oper flag index + uint64_t flag = static_cast(sqlite3_column_int64(statement, 2)); // 2 is oper flag index keyEntry.auxData.operFlag = flag & OPERATE_MASK; // remove the local flag. - keyEntry.auxData.timestamp = static_cast(sqlite3_column_int64(statement, 3)); // timestamp index - keyEntry.auxData.oriTimestamp = static_cast(sqlite3_column_int64(statement, 4)); // ori timestamp index + keyEntry.auxData.timestamp = static_cast(sqlite3_column_int64(statement, 3)); // 3 is timestamp index + keyEntry.auxData.oriTimestamp = static_cast(sqlite3_column_int64(statement, 4)); // 4 is ori timestamp // if the data is deleted data, just use the hash key. if ((flag & OPERATE_MASK) != ADD_FLAG) { - errCode = SQLiteUtils::GetColumnBlobValue(statement, 5, keyEntry.key); // the hash key index. + errCode = SQLiteUtils::GetColumnBlobValue(statement, 5, keyEntry.key); // 5 is the hash key index. if (errCode != E_OK) { return errCode; } @@ -1186,13 +1186,13 @@ int SQLiteMultiVerTransaction::BindClearIdAndVersion(sqlite3_stmt *statement, in goto END; } - errCode = sqlite3_bind_int64(statement, index + 2, clearId_); // combination using with the clear time. + errCode = sqlite3_bind_int64(statement, index + 2, clearId_); // 2 is clearId combination using with the clear time. if (errCode != SQLITE_OK) { LOGE("Bind the clear id for query error:%d", errCode); goto END; } - errCode = sqlite3_bind_int64(statement, index + 3, version_); // version is after the clear rowid. + errCode = sqlite3_bind_int64(statement, index + 3, version_); // 3 is version after the clear rowid. if (errCode != SQLITE_OK) { LOGE("Bind the version for query error:%d", errCode); goto END; @@ -1209,7 +1209,7 @@ int SQLiteMultiVerTransaction::BindQueryEntryArgs(sqlite3_stmt *statement, return errCode; } - return BindClearIdAndVersion(statement, 2); // the third argument is clear id. + return BindClearIdAndVersion(statement, 2); // 2 is clear id. } int SQLiteMultiVerTransaction::BindQueryEntriesArgs(sqlite3_stmt *statement, @@ -1221,7 +1221,7 @@ int SQLiteMultiVerTransaction::BindQueryEntriesArgs(sqlite3_stmt *statement, return errCode; } - return BindClearIdAndVersion(statement, 3); // the third argument is clear id. + return BindClearIdAndVersion(statement, 3); // 3 is clear id. } int SQLiteMultiVerTransaction::BindAddRecordKeysToStatement(sqlite3_stmt *statement, const Key &key, @@ -1317,12 +1317,12 @@ int SQLiteMultiVerTransaction::GetOneEntry(const GetEntriesStatements &statement return STEP_NEXTKEY; } - errCode = SQLiteUtils::GetColumnBlobValue(statements.getEntriesStatement, 2, entry.value); // 3rd is value + errCode = SQLiteUtils::GetColumnBlobValue(statements.getEntriesStatement, 2, entry.value); // 2 is value if (errCode != E_OK) { return STEP_ERROR; } - Version curVer = static_cast(sqlite3_column_int64(statements.getEntriesStatement, 3)); // 4th is ver + Version curVer = static_cast(sqlite3_column_int64(statements.getEntriesStatement, 3)); // 3 is ver // select the version that is greater than the curEntryVer; Key hashKey; errCode = DBCommon::CalcValueHash(entry.key, hashKey); @@ -1334,11 +1334,11 @@ int SQLiteMultiVerTransaction::GetOneEntry(const GetEntriesStatements &statement return STEP_ERROR; } - errCode = sqlite3_bind_int64(statements.hashFilterStatement, 2, static_cast(curVer)); + errCode = sqlite3_bind_int64(statements.hashFilterStatement, 2, static_cast(curVer)); // 2 is curVer if (errCode != E_OK) { return STEP_ERROR; } - errCode = sqlite3_bind_int64(statements.hashFilterStatement, 3, static_cast(version_)); + errCode = sqlite3_bind_int64(statements.hashFilterStatement, 3, static_cast(version_)); // 3 is version if (errCode != E_OK) { return STEP_ERROR; } @@ -1399,8 +1399,8 @@ int SQLiteMultiVerTransaction::CheckIfNeedSaveRecord(sqlite3_stmt *statement, co } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) { auto readTime = static_cast(sqlite3_column_int64(statement, 0)); // the first for time auto readOriTime = static_cast(sqlite3_column_int64(statement, 1)); // the second for orig time. - auto readVersion = static_cast(sqlite3_column_int64(statement, 2)); // the third for version. - errCode = SQLiteUtils::GetColumnBlobValue(statement, 3, origVal); // the fourth for origin value. + auto readVersion = static_cast(sqlite3_column_int64(statement, 2)); // 2 is version. + errCode = SQLiteUtils::GetColumnBlobValue(statement, 3, origVal); // 3 is origin value. if (errCode != E_OK) { return errCode; } @@ -1506,7 +1506,7 @@ int SQLiteMultiVerTransaction::GetKeyAndValueByHashKey(sqlite3_stmt *statement, } } - return SQLiteUtils::GetColumnBlobValue(statement, 2, value); // 3rd column result is value. + return SQLiteUtils::GetColumnBlobValue(statement, 2, value); // 2 is value. } int SQLiteMultiVerTransaction::GetOriginKeyValueByHash(MultiVerEntryData &item, Value &value) const diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_query_helper.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_query_helper.cpp index 0554a057..94e34866 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_query_helper.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_query_helper.cpp @@ -300,6 +300,7 @@ int SqliteQueryHelper::GetQuerySql(std::string &sql, bool onlyRowid) sql = AssembleSqlForSuggestIndex(querySqlForUse, FILTER_NATIVE_DATA_SQL); sql = !hasPrefixKey_ ? sql : (sql + " AND (key>=? AND key<=?) "); sql = keys_.empty() ? sql : (sql + " AND " + MapKeysInToSql(keys_.size())); + sql += " AND (flag&0x200=0) "; if (sortType_ != SortType::NONE) { sql += (sortType_ == SortType::TIMESTAMP_ASC) ? "ORDER BY timestamp asc " : "ORDER BY timestamp desc "; } @@ -389,6 +390,7 @@ int SqliteQueryHelper::GetCountQuerySql(std::string &sql) sql = AssembleSqlForSuggestIndex(PRE_GET_COUNT_SQL, FILTER_NATIVE_DATA_SQL); sql = !hasPrefixKey_ ? sql : (sql + " AND (key>=? AND key<=?) "); sql = keys_.empty() ? sql : (sql + " AND " + MapKeysInToSql(keys_.size())); + sql += " AND (flag&0x200=0) "; sql += countSql_; return E_OK; } @@ -527,6 +529,7 @@ int SqliteQueryHelper::GetSyncDataQuerySql(std::string &sql, bool hasSubQuery) sql = !hasPrefixKey_ ? sql : (sql + " AND (key>=? AND key<=?) "); sql = keys_.empty() ? sql : (sql + " AND " + MapKeysInToSql(keys_.size())); sql = hasSubQuery ? sql : (sql + " AND (timestamp>=? AND timestamp ? AND (b.flag & 0x04 != 0x04)" : @@ -1209,7 +1215,8 @@ void SqliteQueryHelper::AppendCloudGidQuery(bool isCloudForcePush, bool isCompen sql += CloudStorageUtils::GetLeftJoinLogSql(tableName_, false); sql += " WHERE "; if (isCompensatedTask) { - sql += " b.status=1 AND "; + // deleted data does not have primary key, requires gid to compensate sync + sql += " (b.status = 1 AND (b.flag & 0x01 = 0x01)) OR "; } sql += isCloudForcePush ? " b.timestamp > ? AND (b.flag & 0x04 != 0x04)" : " b.timestamp > ?"; @@ -1261,6 +1268,7 @@ std::pair SqliteQueryHelper::GetKvCloudQueryStmt(sqlite3 *d int &errCode = res.first; std::string sql = GetKvCloudQuerySql(false, forcePush); AppendCloudQueryToGetDiffData(sql, mode, true); + sql += "order by modify_time asc"; errCode = SQLiteUtils::GetStatement(db, sql, stmt); return res; } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_query_helper.h b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_query_helper.h index 67bd1b3d..596ce743 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_query_helper.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_query_helper.h @@ -104,7 +104,7 @@ public: std::string GetRelationalCloudQuerySql(const std::vector &fields, const bool &isCloudForcePush, bool isCompensatedTask, CloudWaterType mode); - std::string GetCountRelationalCloudQuerySql(bool isCloudForcePush, bool isCompensatedTask); + std::string GetCountRelationalCloudQuerySql(bool isCloudForcePush, bool isCompensatedTask, CloudWaterType mode); std::string GetGidRelationalCloudQuerySql(const std::vector &fields, bool isCloudForcePush, bool isCompensatedTask); @@ -149,7 +149,7 @@ private: // Return the left string of symbol in compare clause. std::string GetFieldShape(const QueryObjNode &queryNode, const std::string &accessStr = ""); - void AppendCloudQuery(bool isCloudForcePush, bool isCompensatedTask, std::string &sql); + void AppendCloudQuery(bool isCloudForcePush, bool isCompensatedTask, std::string &sql, CloudWaterType mode); void AppendCloudGidQuery(bool isCloudForcePush, bool isCompensatedTask, std::string &sql); SchemaObject schema_; 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 a6cbf6c7..7fd9b73e 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 @@ -171,7 +171,8 @@ SQLiteSingleVerNaturalStore::SQLiteSingleVerNaturalStore() lifeTimerId_(0), autoLifeTime_(DBConstant::DEF_LIFE_CYCLE_TIME), createDBTime_(0), - dataInterceptor_(nullptr), + pushDataInterceptor_(nullptr), + receiveDataInterceptor_(nullptr), maxLogSize_(DBConstant::MAX_LOG_SIZE_DEFAULT), abortPerm_(OperatePerm::NORMAL_PERM), sqliteCloudKvStore_(nullptr) @@ -1202,8 +1203,8 @@ int SQLiteSingleVerNaturalStore::SaveSyncDataItems(const QueryObject &query, std return errCode; } if (offset != 0) { - item.modifyTime = item.timestamp - offset; - item.createTime = item.writeTimestamp - offset; + item.modifyTime = static_cast(static_cast(item.timestamp) - offset); + item.createTime = static_cast(static_cast(item.writeTimestamp) - offset); } } if (checkValueContent) { @@ -1451,7 +1452,7 @@ int SQLiteSingleVerNaturalStore::Export(const std::string &filePath, const Ciphe ReleaseHandle(handle); return errCode; } - LOGI("Begin export the kv store"); + LOGD("Begin export the kv store"); errCode = operation->Export(filePath, passwd); ReEnableConnection(OperatePerm::NORMAL_WRITE); @@ -1952,5 +1953,10 @@ int SQLiteSingleVerNaturalStore::SetCloudDbSchema(const std::mapSetCloudDbSchema(schema); } +std::map SQLiteSingleVerNaturalStore::GetDataBaseSchemas() +{ + std::lock_guard autoLock(cloudStoreMutex_); + return sqliteCloudKvStore_->GetDataBaseSchemas(); +} DEFINE_OBJECT_TAG_FACILITIES(SQLiteSingleVerNaturalStore) } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.h b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.h index 193e7bfd..6cd0ba57 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store.h @@ -178,9 +178,9 @@ public: int CheckAndInitQueryCondition(QueryObject &query) const override; int InterceptData(std::vector &entries, const std::string &sourceID, - const std::string &targetID) const override; + const std::string &targetID, bool isPush) const override; - void SetDataInterceptor(const PushDataInterceptor &interceptor) override; + void SetSendDataInterceptor(const PushDataInterceptor &interceptor) override; int AddSubscribe(const std::string &subscribeId, const QueryObject &query, bool needCacheSubscribe) override; @@ -215,12 +215,18 @@ public: int UnRegisterObserverAction(const KvStoreObserver *observer); int GetCloudVersion(const std::string &device, std::map &versionMap); + + void SetReceiveDataInterceptor(const DataInterceptor &interceptor) override; + + int SetCloudSyncConfig(const CloudSyncConfig &config); protected: void AsyncDataMigration(SQLiteSingleVerStorageEngine *storageEngine) const; void ReleaseResources(); ICloudSyncStorageInterface *GetICloudSyncInterface() const override; + + std::map GetDataBaseSchemas() override; private: int CheckDatabaseRecovery(const KvDBProperties &kvDBProp); @@ -313,7 +319,9 @@ private: mutable std::mutex createDBTimeMutex_; mutable std::shared_mutex dataInterceptorMutex_; - PushDataInterceptor dataInterceptor_; + PushDataInterceptor pushDataInterceptor_; + DataInterceptor receiveDataInterceptor_; + std::atomic maxLogSize_; mutable std::shared_mutex abortHandleMutex_; 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 acb39eae..5dd23d9e 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 @@ -27,6 +27,7 @@ #include "sqlite_single_ver_natural_store.h" #include "sqlite_single_ver_result_set.h" #include "store_types.h" +#include "time_helper.h" namespace DistributedDB { namespace { @@ -605,7 +606,7 @@ int SQLiteSingleVerNaturalStoreConnection::GetResultSet(const IOption &option, c } if (((queryObj.GetSortType() != SortType::NONE) && !queryObj.IsQueryOnlyByKey()) || queryObj.IsQueryByRange()) { - LOGE("[GetEntries][query] timestamp sort only support prefixKey and not support Range search"); + LOGE("[GetResultSet][query] timestamp sort only support prefixKey and not support range search"); return -E_NOT_SUPPORT; } bool isMemDb = naturalStore->GetMyProperties().GetBoolProp(KvDBProperties::MEMORY_MODE, false); @@ -958,23 +959,7 @@ int SQLiteSingleVerNaturalStoreConnection::SaveEntry(const Entry &entry, bool is return errCode; } } - - dataItem.timestamp = naturalStore->GetCurrentTimestamp(); - if (currentMaxTimestamp_ > dataItem.timestamp) { - dataItem.timestamp = currentMaxTimestamp_; - } - - if (timestamp != 0) { - dataItem.writeTimestamp = timestamp; - } else { - dataItem.writeTimestamp = dataItem.timestamp; - } - - auto offset = naturalStore->GetLocalTimeOffset(); - if (offset != 0) { - dataItem.modifyTime = dataItem.timestamp - offset; - dataItem.createTime = dataItem.writeTimestamp - offset; - } + RecordTimeIntoDataItem(timestamp, dataItem, *naturalStore); if (IsExtendedCacheDBMode()) { uint64_t recordVersion = naturalStore->GetCacheRecordVersion(); return SaveEntryInCacheMode(dataItem, recordVersion); @@ -1933,5 +1918,66 @@ int SQLiteSingleVerNaturalStoreConnection::GetCloudVersion(const std::string &de } return naturalStore->GetCloudVersion(device, versionMap); } + +int SQLiteSingleVerNaturalStoreConnection::GetEntries(const std::string &device, std::vector &entries) const +{ + int errCode = CheckReadDataControlled(); + if (errCode != E_OK) { + LOGE("[GetEntries] Existed cache database can not read data, errCode = [%d]!", errCode); + return errCode; + } + std::string localId; + errCode = RuntimeContext::GetInstance()->GetLocalIdentity(localId); + std::string getDevice; + // if device is local, just search with empty string + if (errCode != E_OK || localId != device) { + getDevice = device; + } + { + std::lock_guard lock(transactionMutex_); + if (writeHandle_ != nullptr) { + LOGD("[SQLiteSingleVerNaturalStoreConnection] Transaction started already."); + return writeHandle_->GetEntries(getDevice, entries); + } + } + + SQLiteSingleVerStorageExecutor *handle = GetExecutor(false, errCode); + if (handle == nullptr) { + LOGE("[SQLiteSingleVerNaturalStoreConnection]::[GetEntries] Get executor failed, errCode = [%d]", errCode); + return errCode; + } + + errCode = handle->GetEntries(getDevice, entries); + ReleaseExecutor(handle); + return errCode; +} + +int SQLiteSingleVerNaturalStoreConnection::SetCloudSyncConfig(const CloudSyncConfig &config) +{ + auto naturalStore = GetDB(); + if (naturalStore == nullptr) { + LOGE("[SingleVerConnection] DB is null when set config"); + return -E_INVALID_DB; + } + return naturalStore->SetCloudSyncConfig(config); +} + +void SQLiteSingleVerNaturalStoreConnection::RecordTimeIntoDataItem(Timestamp existCreateTime, DataItem &dataItem, + SQLiteSingleVerNaturalStore &naturalStore) +{ + dataItem.timestamp = naturalStore.GetCurrentTimestamp(); + if (currentMaxTimestamp_ > dataItem.timestamp) { + dataItem.timestamp = currentMaxTimestamp_; + } + + auto currentRawTime = TimeHelper::GetSysCurrentTime(); + if (existCreateTime != 0) { + dataItem.writeTimestamp = existCreateTime; + } else { + dataItem.writeTimestamp = dataItem.timestamp; + } + dataItem.createTime = currentRawTime; + dataItem.modifyTime = currentRawTime; +} DEFINE_OBJECT_TAG_FACILITIES(SQLiteSingleVerNaturalStoreConnection) } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store_connection.h b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store_connection.h index f6df1afe..b67eb9d4 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store_connection.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store_connection.h @@ -115,6 +115,10 @@ public: int RemoveDeviceData(const std::string &device, const std::string &user, ClearMode mode) override; int GetCloudVersion(const std::string &device, std::map &versionMap) override; + + int SetCloudSyncConfig(const CloudSyncConfig &config) override; + + int GetEntries(const std::string &device, std::vector &entries) const override; private: int CheckMonoStatus(OperatePerm perm); @@ -215,6 +219,9 @@ private: int GetEntriesInner(bool isGetValue, const IOption &option, const Key &keyPrefix, std::vector &entries) const; + void RecordTimeIntoDataItem(Timestamp existCreateTime, DataItem &dataItem, + SQLiteSingleVerNaturalStore &naturalStore); + DECLARE_OBJECT_TAG(SQLiteSingleVerNaturalStoreConnection); // ResultSet Related Info diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store_extend.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store_extend.cpp index 901b4b6b..665f0278 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store_extend.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_natural_store_extend.cpp @@ -350,22 +350,22 @@ int SQLiteSingleVerNaturalStore::CheckAndInitQueryCondition(QueryObject &query) return errCode; } -void SQLiteSingleVerNaturalStore::SetDataInterceptor(const PushDataInterceptor &interceptor) +void SQLiteSingleVerNaturalStore::SetSendDataInterceptor(const PushDataInterceptor &interceptor) { std::unique_lock lock(dataInterceptorMutex_); - dataInterceptor_ = interceptor; + pushDataInterceptor_ = interceptor; } int SQLiteSingleVerNaturalStore::InterceptData(std::vector &entries, const std::string &sourceID, - const std::string &targetID) const + const std::string &targetID, bool isPush) const { PushDataInterceptor interceptor = nullptr; { std::shared_lock lock(dataInterceptorMutex_); - if (dataInterceptor_ == nullptr) { + interceptor = isPush ? pushDataInterceptor_ : receiveDataInterceptor_; + if (interceptor == nullptr) { return E_OK; } - interceptor = dataInterceptor_; } InterceptedDataImpl data(entries, [this](const Value &newValue) -> int { @@ -377,7 +377,10 @@ int SQLiteSingleVerNaturalStore::InterceptData(std::vector & int errCode = interceptor(data, sourceID, targetID); if (data.IsError()) { - SingleVerKvEntry::Release(entries); + if (isPush) { + // receive data release by syncer + SingleVerKvEntry::Release(entries); + } LOGE("Intercept data failed:%d.", errCode); return -E_INTERCEPT_DATA_FAIL; } @@ -599,4 +602,21 @@ int SQLiteSingleVerNaturalStore::GetCloudVersion(const std::string &device, } return sqliteCloudKvStore_->GetCloudVersion(device, versionMap); } + +void SQLiteSingleVerNaturalStore::SetReceiveDataInterceptor(const DataInterceptor &interceptor) +{ + std::unique_lock lock(dataInterceptorMutex_); + receiveDataInterceptor_ = interceptor; +} + +int SQLiteSingleVerNaturalStore::SetCloudSyncConfig(const CloudSyncConfig &config) +{ + std::lock_guard autoLock(cloudStoreMutex_); + if (sqliteCloudKvStore_ == nullptr) { + LOGE("[SingleVerNStore] DB is null when set config"); + return -E_INTERNAL_ERROR; + } + sqliteCloudKvStore_->SetCloudSyncConfig(config); + return E_OK; +} } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_engine.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_engine.cpp index 3cd0e224..a8996fcf 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_engine.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_engine.cpp @@ -250,7 +250,7 @@ int SQLiteSingleVerStorageEngine::MigrateSyncData(SQLiteSingleVerStorageExecutor } } - LOGD("Begin migrate sync data, need migrate version[%" PRIu64 "]", GetCacheRecordVersion() - 1); + LOGD("Begin migrate sync data, need migrate version[%" PRIu64 "]", GetCacheRecordVersion()); uint64_t curMigrateVer = 0; // The migration process is asynchronous and continuous NotifyMigrateSyncData syncData; auto kvdbManager = KvDBManager::GetInstance(); @@ -903,6 +903,7 @@ int SQLiteSingleVerStorageEngine::Upgrade(sqlite3 *db) LOGD("Finish upgrade single ver database!"); isUpdated_ = true; // Identification to avoid repeated upgrades + std::unique_lock lock(schemaChangedMutex_); isSchemaChanged_ = upgrader->IsValueNeedUpgrade(); return errCode; } @@ -1096,11 +1097,16 @@ bool SQLiteSingleVerStorageEngine::IsUseExistedSecOption(const SecurityOption &e int SQLiteSingleVerStorageEngine::UpgradeLocalMetaData() { - std::shared_lock lock(schemaChangedMutex_); - if (isSchemaChanged_) { - int errCode = schemaChangedFunc_(); - isSchemaChanged_ = false; - return errCode; + std::function schemaChangedFunc = nullptr; + { + std::unique_lock lock(schemaChangedMutex_); + if (isSchemaChanged_) { + schemaChangedFunc = schemaChangedFunc_; + isSchemaChanged_ = false; + } + } + if (schemaChangedFunc) { + return schemaChangedFunc(); } return E_OK; } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_executor.h b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_executor.h index 97d7ed84..69f87fd7 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_executor.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_executor.h @@ -188,6 +188,8 @@ public: int UpdateKey(const UpdateKeyCallback &callback); int CreateCloudLogTable(); + + int GetEntries(const std::string &device, std::vector &entries) const; protected: virtual int SaveKvData(SingleVerDataType type, const Key &key, const Value &value, Timestamp timestamp); @@ -348,7 +350,8 @@ private: static int BindSyncDataTime(sqlite3_stmt *statement, const DataItem &dataItem, bool isUpdate); - int CloudExcuteRemoveOrUpdate(const std::string &sql, const std::string &deviceName, const std::string &user); + int CloudExcuteRemoveOrUpdate(const std::string &sql, const std::string &deviceName, const std::string &user, + bool isUserBlobType = false); int CloudCheckDataExist(const std::string &sql, const std::string &deviceName, const std::string &user, bool &isExist); diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_executor_extend.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_executor_extend.cpp index 9450ae90..c149945a 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_executor_extend.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_executor_extend.cpp @@ -21,6 +21,7 @@ #include "db_constant.h" #include "db_common.h" #include "db_errno.h" +#include "res_finalizer.h" #include "parcel.h" #include "platform_specific.h" #include "runtime_context.h" @@ -35,7 +36,7 @@ constexpr const char *HWM_HEAD = "naturalbase_cloud_meta_sync_data_"; } int SQLiteSingleVerStorageExecutor::CloudExcuteRemoveOrUpdate(const std::string &sql, const std::string &deviceName, - const std::string &user) + const std::string &user, bool isUserBlobType) { int errCode = E_OK; sqlite3_stmt *statement = nullptr; @@ -46,8 +47,12 @@ int SQLiteSingleVerStorageExecutor::CloudExcuteRemoveOrUpdate(const std::string // device name always hash string. int bindIndex = 1; // 1 is the first index for blob to bind. if (!user.empty()) { - std::vector useVect(user.begin(), user.end()); - errCode = SQLiteUtils::BindBlobToStatement(statement, bindIndex, useVect, true); // only one arg. + if (isUserBlobType) { + std::vector useVect(user.begin(), user.end()); + errCode = SQLiteUtils::BindBlobToStatement(statement, bindIndex, useVect, true); + } else { + errCode = SQLiteUtils::BindTextToStatement(statement, bindIndex, user); + } if (errCode != E_OK) { LOGE("Failed to bind the removed device:%d", errCode); SQLiteUtils::ResetStatement(statement, true, errCode); @@ -85,8 +90,7 @@ int SQLiteSingleVerStorageExecutor::CloudCheckDataExist(const std::string &sql, } int bindIndex = 1; // 1 is the first index for blob to bind. if (!user.empty()) { - std::vector useVect(user.begin(), user.end()); - errCode = SQLiteUtils::BindBlobToStatement(statement, bindIndex, useVect, true); // only one arg. + errCode = SQLiteUtils::BindTextToStatement(statement, bindIndex, user); // only one arg. if (errCode != E_OK) { LOGE("Failed to bind the removed device:%d", errCode); SQLiteUtils::ResetStatement(statement, true, errCode); @@ -94,7 +98,7 @@ int SQLiteSingleVerStorageExecutor::CloudCheckDataExist(const std::string &sql, } bindIndex++; if (sql == SELECT_CLOUD_LOG_DATA_BY_USERID_HASHKEY_SQL) { // the second argument is also userid. - errCode = SQLiteUtils::BindBlobToStatement(statement, bindIndex, useVect, true); // only one arg. + errCode = SQLiteUtils::BindTextToStatement(statement, bindIndex, user); // only one arg. if (errCode != E_OK) { LOGE("Failed to bind the removed device:%d", errCode); SQLiteUtils::ResetStatement(statement, true, errCode); @@ -127,7 +131,7 @@ int SQLiteSingleVerStorageExecutor::CloudCheckDataExist(const std::string &sql, int SQLiteSingleVerStorageExecutor::RemoveDeviceDataInner(ClearMode mode) { - int errCode = CloudExcuteRemoveOrUpdate(REMOVE_CLOUD_ALL_HWM_DATA_SQL, "", ""); + int errCode = CloudExcuteRemoveOrUpdate(REMOVE_CLOUD_ALL_HWM_DATA_SQL, "", "", true); if (errCode != E_OK) { return errCode; } @@ -145,7 +149,7 @@ int SQLiteSingleVerStorageExecutor::RemoveDeviceDataInner(ClearMode mode) int SQLiteSingleVerStorageExecutor::RemoveDeviceDataInner(const std::string &deviceName, ClearMode mode) { - int errCode = CloudExcuteRemoveOrUpdate(REMOVE_CLOUD_ALL_HWM_DATA_SQL, "", ""); + int errCode = CloudExcuteRemoveOrUpdate(REMOVE_CLOUD_ALL_HWM_DATA_SQL, "", "", true); if (errCode != E_OK) { return errCode; } @@ -163,7 +167,8 @@ int SQLiteSingleVerStorageExecutor::RemoveDeviceDataInner(const std::string &dev int SQLiteSingleVerStorageExecutor::RemoveDeviceDataWithUserInner(const std::string &user, ClearMode mode) { - int errCode = CloudExcuteRemoveOrUpdate(REMOVE_CLOUD_HWM_DATA_BY_USERID_SQL, "", std::string(HWM_HEAD) + user); + int errCode = CloudExcuteRemoveOrUpdate(REMOVE_CLOUD_HWM_DATA_BY_USERID_SQL, "", + std::string(HWM_HEAD) + user, true); if (errCode != E_OK) { return errCode; } @@ -190,7 +195,8 @@ int SQLiteSingleVerStorageExecutor::RemoveDeviceDataWithUserInner(const std::str int SQLiteSingleVerStorageExecutor::RemoveDeviceDataWithUserInner(const std::string &deviceName, const std::string &user, ClearMode mode) { - int errCode = CloudExcuteRemoveOrUpdate(REMOVE_CLOUD_HWM_DATA_BY_USERID_SQL, "", std::string(HWM_HEAD) + user); + int errCode = CloudExcuteRemoveOrUpdate(REMOVE_CLOUD_HWM_DATA_BY_USERID_SQL, "", + std::string(HWM_HEAD) + user, true); if (errCode != E_OK) { return errCode; } @@ -248,4 +254,37 @@ int SQLiteSingleVerStorageExecutor::RemoveDeviceData(const std::string &deviceNa } return CheckCorruptedStatus(RemoveDeviceDataWithUserInner(deviceName, user, mode)); } + +int SQLiteSingleVerStorageExecutor::GetEntries(const std::string &device, std::vector &entries) const +{ + const std::string sql = SELECT_SYNC_ENTRIES_BY_DEVICE_SQL; + sqlite3_stmt *stmt = nullptr; + int errCode = SQLiteUtils::GetStatement(dbHandle_, sql, stmt); + if (errCode != E_OK) { + LOGE("[SQLiteSingleVerStorageExecutor] Get entries by device statement failed:%d", errCode); + return errCode; + } + ResFinalizer finalizer([stmt]() { + sqlite3_stmt *statement = stmt; + int ret = E_OK; + SQLiteUtils::ResetStatement(statement, true, ret); + if (ret != E_OK) { + LOGW("[SQLiteSingleVerStorageExecutor] Reset get entries statement failed:%d", ret); + } + }); + auto hashDev = DBCommon::TransferHashString(device); + Value blobDev; + DBCommon::StringToVector(hashDev, blobDev); + errCode = SQLiteUtils::BindBlobToStatement(stmt, BIND_GET_ENTRIES_DEVICE_INDEX, blobDev); + if (errCode != E_OK) { + LOGE("[SQLiteSingleVerStorageExecutor] Bind hash device to statement failed:%d", errCode); + return errCode; + } + errCode = StepForResultEntries(true, stmt, entries); + if (errCode != E_OK) { + return errCode; + } + LOGD("[SQLiteSingleVerStorageExecutor] Get %zu entries by device", entries.size()); + return errCode; +} } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_executor_sql.h b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_executor_sql.h index 892eb69d..4d005021 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_executor_sql.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_executor_sql.h @@ -97,7 +97,7 @@ namespace DistributedDB { "SELECT * FROM sync_data WHERE key=?;"; const std::string SELECT_SYNC_VALUE_WTIMESTAMP_SQL = - "SELECT value, w_timestamp FROM sync_data WHERE key=?;"; + "SELECT value, w_timestamp FROM sync_data WHERE key=? AND (flag&0x200=0);"; const std::string SELECT_SYNC_HASH_SQL = "SELECT * FROM sync_data WHERE hash_key=?;"; @@ -142,7 +142,8 @@ namespace DistributedDB { "ORDER BY timestamp ASC;"; const std::string SELECT_SYNC_PREFIX_SQL = - "SELECT key, value FROM sync_data WHERE key>=? AND key<=? AND (flag&0x01=0) ORDER BY key ASC;"; + "SELECT key, value FROM sync_data WHERE key>=? AND key<=? AND (flag&0x01=0) AND (flag&0x200=0) " + "ORDER BY key ASC;"; const std::string SELECT_SYNC_KEY_PREFIX_SQL = "SELECT key FROM sync_data WHERE key>=? AND key<=? AND (flag&0x01=0) AND (flag&0x200=0) ORDER BY key ASC;"; @@ -157,7 +158,7 @@ namespace DistributedDB { "SELECT key, value FROM local_data WHERE key>=? AND key<=? ORDER BY key ASC;"; const std::string SELECT_COUNT_SYNC_PREFIX_SQL = - "SELECT count(key) FROM sync_data WHERE key>=? AND key<=? AND (flag&0x01=0);"; + "SELECT count(key) FROM sync_data WHERE key>=? AND key<=? AND (flag&0x01=0) AND (flag&0x200=0);"; const std::string REMOVE_DEV_DATA_SQL = "DELETE FROM sync_data WHERE device=? AND (flag&0x02=0) AND (flag&0x100=0);"; @@ -268,22 +269,22 @@ namespace DistributedDB { const std::string REMOVE_CLOUD_LOG_DATA_BY_DEVID_SQL = "DELETE FROM naturalbase_kv_aux_sync_data_log WHERE hash_key IN" \ - "(SELECT hash_key FROM sync_data WHERE device =? AND (flag&0x100!=0));"; + "(SELECT hash_key FROM sync_data WHERE device =?);"; const std::string REMOVE_CLOUD_LOG_DATA_BY_USERID_SQL = "DELETE FROM naturalbase_kv_aux_sync_data_log WHERE userid =?;"; const std::string REMOVE_CLOUD_LOG_DATA_BY_USERID_DEVID_SQL = "DELETE FROM naturalbase_kv_aux_sync_data_log WHERE userid =? AND hash_key IN" \ - "(SELECT hash_key FROM sync_data WHERE device =? AND (flag&0x100!=0));"; + "(SELECT hash_key FROM sync_data WHERE device =?);"; const std::string SELECT_CLOUD_LOG_DATA_BY_DEVID_SQL = "SELECT * FROM naturalbase_kv_aux_sync_data_log WHERE hash_key IN" \ - "(SELECT hash_key FROM sync_data WHERE device =? AND (flag&0x100!=0));"; + "(SELECT hash_key FROM sync_data WHERE device =?);"; const std::string SELECT_CLOUD_LOG_DATA_BY_USERID_DEVID_SQL = "SELECT * FROM naturalbase_kv_aux_sync_data_log WHERE userid =? AND hash_key IN" \ - "(SELECT hash_key FROM sync_data WHERE device =? AND (flag&0x100!=0));"; + "(SELECT hash_key FROM sync_data WHERE device =?);"; // Check whether the hashKey is the same but the userId is different const std::string SELECT_CLOUD_LOG_DATA_BY_USERID_HASHKEY_SQL = @@ -317,14 +318,15 @@ namespace DistributedDB { " AS log_table ON sync_data.hash_key = log_table.hash_key "; constexpr const char *QUERY_CLOUD_SYNC_DATA_CONDITION = - "WHERE modify_time > ? AND (cloud_gid is not null or (cloud_gid is null and flag&0x01=0)) AND flag&0x200=0"; + "WHERE modify_time > ? AND ((cloud_gid is not null and cloud_gid != '') OR " + "((cloud_gid is null OR cloud_gid = '') and flag&0x01=0)) AND flag&0x200=0"; constexpr const char *QUERY_CLOUD_VERSION_RECORD_CONDITION = "WHERE key = ? AND flag & 0x200 != 0"; constexpr const char *QUERY_CLOUD_SYNC_DATA_LOG = "SELECT sync_data.rowid, flag, device, ori_device, " "modify_time, create_time, cloud_gid, sync_data.hash_key, sync_data.key, version FROM " "sync_data LEFT JOIN naturalbase_kv_aux_sync_data_log ON " - "sync_data.hash_key = naturalbase_kv_aux_sync_data_log.hash_key WHERE cloud_gid = ? "; + "sync_data.hash_key = naturalbase_kv_aux_sync_data_log.hash_key "; constexpr const char *QUERY_CLOUD_VERSION_RECORD_SQL_HEAD = "SELECT key, value, flag, device, sync_data.hash_key " "FROM sync_data WHERE key LIKE 'naturalbase_cloud_version_%' "; @@ -345,6 +347,9 @@ namespace DistributedDB { constexpr const char *UPDATE_TIMESTAMP = "UPDATE sync_data SET timestamp=?, modify_time=? WHERE hash_key=?"; + constexpr const char *SELECT_SYNC_ENTRIES_BY_DEVICE_SQL = + "SELECT key,value FROM sync_data WHERE device=? AND flag&0x200=0"; + const int BIND_KV_KEY_INDEX = 1; const int BIND_KV_VAL_INDEX = 2; const int BIND_LOCAL_TIMESTAMP_INDEX = 3; @@ -427,6 +432,9 @@ namespace DistributedDB { constexpr int BIND_CLOUD_VERSION_RECORD_USER_INDEX = 1; constexpr int BIND_CLOUD_VERSION_RECORD_KEY_INDEX = 2; + constexpr int BIND_CLOUD_VERSION_DEVICE_INDEX = 1; + + constexpr int BIND_GET_ENTRIES_DEVICE_INDEX = 1; const Key REMOVE_DEVICE_DATA_KEY = {'r', 'e', 'm', 'o', 'v', 'e'}; } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_utils.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_utils.cpp index f49e9fff..4ae58476 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_utils.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_utils.cpp @@ -49,6 +49,11 @@ namespace { const int USING_STR_LEN = -1; const int MAX_BLOB_READ_SIZE = 5 * 1024 * 1024; // 5M limit const int MAX_TEXT_READ_SIZE = 5 * 1024 * 1024; // 5M limit + const int HEAD_SIZE = 3; + const int END_SIZE = 3; + constexpr int MIN_SIZE = HEAD_SIZE + END_SIZE + 3; + const std::string REPLACE_CHAIN = "***"; + const std::string DEFAULT_ANONYMOUS = "******"; const std::string WAL_MODE_SQL = "PRAGMA journal_mode=WAL;"; const std::string SYNC_MODE_FULL_SQL = "PRAGMA synchronous=FULL;"; const std::string USER_VERSION_SQL = "PRAGMA user_version;"; @@ -96,10 +101,24 @@ std::string GetTriggerModeString(TriggerModeEnum mode) } } +std::string SQLiteUtils::Anonymous(const std::string &name) +{ + if (name.length() <= HEAD_SIZE) { + return DEFAULT_ANONYMOUS; + } + + if (name.length() < MIN_SIZE) { + return (name.substr(0, HEAD_SIZE) + REPLACE_CHAIN); + } + + return (name.substr(0, HEAD_SIZE) + REPLACE_CHAIN + name.substr(name.length() - END_SIZE, END_SIZE)); +} + void SQLiteUtils::SqliteLogCallback(void *data, int err, const char *msg) { bool verboseLog = (data != nullptr); auto errType = static_cast(err); + std::string logMsg = msg == nullptr ? "NULL" : msg; errType &= 0xFF; if (errType == 0 || errType == SQLITE_CONSTRAINT || errType == SQLITE_SCHEMA || errType == SQLITE_NOTICE || err == SQLITE_WARNING_AUTOINDEX) { @@ -108,9 +127,10 @@ void SQLiteUtils::SqliteLogCallback(void *data, int err, const char *msg) } } else if (errType == SQLITE_WARNING || errType == SQLITE_IOERR || errType == SQLITE_CORRUPT || errType == SQLITE_CANTOPEN) { - LOGI("[SQLite] Error[%d], sys[%d], %s", err, errno, sqlite3_errstr(err)); + LOGI("[SQLite] Error[%d], sys[%d], %s, msg: %s ", err, errno, + sqlite3_errstr(err), SQLiteUtils::Anonymous(logMsg).c_str()); } else { - LOGE("[SQLite] Error[%d], sys[%d]", err, errno); + LOGE("[SQLite] Error[%d], sys[%d], msg: %s ", err, errno, logMsg.c_str()); return; } @@ -168,7 +188,6 @@ int SQLiteUtils::OpenDatabase(const OpenDbProperties &properties, sqlite3 *&db, if (!g_configLog) { sqlite3_config(SQLITE_CONFIG_LOG, &SqliteLogCallback, &properties.createIfNecessary); sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 0, 0); - LOGW("close look aside config"); g_configLog = true; } } @@ -663,7 +682,7 @@ int SQLiteUtils::CheckIntegrity(sqlite3 *db, const std::string &sql) namespace { // anonymous namespace for schema analysis int AnalysisSchemaSqlAndTrigger(sqlite3 *db, const std::string &tableName, TableInfo &table, bool caseSensitive) { - std::string sql = "select type, sql from sqlite_master where tbl_name = ? "; + std::string sql = "SELECT type, sql FROM sqlite_master WHERE tbl_name = ? "; if (!caseSensitive) { sql += "COLLATE NOCASE"; } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_utils.h b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_utils.h index 639b9848..12736fda 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_utils.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_utils.h @@ -246,6 +246,8 @@ private: static int UpdateCipherShaAlgo(sqlite3 *db, bool setWal, CipherType type, const CipherPassword &passwd, uint32_t iterTimes); + static std::string Anonymous(const std::string &name); + static std::mutex logMutex_; static std::string lastErrorMsg_; }; 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 234625f4..80f66065 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/storage_proxy.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/storage_proxy.cpp @@ -15,7 +15,9 @@ #include "storage_proxy.h" +#include "cloud/cloud_storage_utils.h" #include "cloud/schema_mgr.h" +#include "db_common.h" #include "store_types.h" namespace DistributedDB { @@ -73,11 +75,7 @@ int StorageProxy::GetLocalWaterMarkByMode(const std::string &tableName, Timestam LOGE("the write transaction has been started, can not get meta"); return -E_BUSY; } - if (user_.empty()) { - return cloudMetaData_->GetLocalWaterMarkByType(tableName, mode, localMark); - } else { - return cloudMetaData_->GetLocalWaterMarkByType(tableName + "_" + user_, mode, localMark); - } + return cloudMetaData_->GetLocalWaterMarkByType(AppendWithUserIfNeed(tableName), mode, localMark); } int StorageProxy::PutLocalWaterMark(const std::string &tableName, Timestamp &localMark) @@ -103,11 +101,7 @@ int StorageProxy::PutWaterMarkByMode(const std::string &tableName, Timestamp &lo LOGE("the write transaction has been started, can not put meta"); return -E_BUSY; } - if (user_.empty()) { - return cloudMetaData_->SetLocalWaterMarkByType(tableName, mode, localMark); - } else { - return cloudMetaData_->SetLocalWaterMarkByType(tableName + "_" + user_, mode, localMark); - } + return cloudMetaData_->SetLocalWaterMarkByType(AppendWithUserIfNeed(tableName), mode, localMark); } int StorageProxy::GetCloudWaterMark(const std::string &tableName, std::string &cloudMark) @@ -169,7 +163,7 @@ int StorageProxy::Rollback() } int StorageProxy::GetUploadCount(const QuerySyncObject &query, const bool isCloudForcePush, - bool isCompensatedTask, bool isPriorityTask, int64_t &count) + bool isCompensatedTask, bool isUseWaterMark, int64_t &count) { std::shared_lock readLock(storeMutex_); if (store_ == nullptr) { @@ -180,12 +174,12 @@ int StorageProxy::GetUploadCount(const QuerySyncObject &query, const bool isClou return -E_TRANSACT_STATE; } std::vector timeStampVec; - std::vector waterTypeVec = {CloudWaterType::DELETE, CloudWaterType::UPDATE, - CloudWaterType::INSERT}; + std::vector waterTypeVec = DBCommon::GetWaterTypeVec(); for (size_t i = 0; i < waterTypeVec.size(); i++) { Timestamp tmpMark = 0u; - if (!isPriorityTask && !isCompensatedTask && !isCloudForcePush) { - int errCode = cloudMetaData_->GetLocalWaterMarkByType(query.GetTableName(), waterTypeVec[i], tmpMark); + if (isUseWaterMark) { + int errCode = cloudMetaData_->GetLocalWaterMarkByType(AppendWithUserIfNeed(query.GetTableName()), + waterTypeVec[i], tmpMark); if (errCode != E_OK) { return errCode; } @@ -646,4 +640,22 @@ std::pair StorageProxy::GetLocalCloudVersion() } return store_->GetLocalCloudVersion(); } + +CloudSyncConfig StorageProxy::GetCloudSyncConfig() const +{ + std::shared_lock readLock(storeMutex_); + if (store_ == nullptr) { + return {}; + } + return store_->GetCloudSyncConfig(); +} + +bool StorageProxy::IsTableExistReference(const std::string &table) +{ + std::shared_lock readLock(storeMutex_); + if (store_ == nullptr) { + return false; + } + return store_->IsTableExistReference(table); +} } 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 22957101..89215ff5 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 @@ -15,12 +15,10 @@ #include "cloud_db_proxy.h" #include "db_errno.h" #include "log_print.h" -#include "runtime_context.h" namespace DistributedDB { CloudDBProxy::CloudDBProxy() - : timeout_(0), - asyncTaskCount_(0) + : timeout_(0) { } @@ -39,6 +37,12 @@ int CloudDBProxy::SetCloudDB(const std::map> CloudDBProxy::GetCloudDB() const +{ + std::shared_lock readLock(cloudMutex_); + return cloudDbs_; +} + void CloudDBProxy::SwitchCloudDB(const std::string &user) { std::unique_lock writeLock(cloudMutex_); @@ -165,16 +169,8 @@ int CloudDBProxy::Close() } cloudDbs_.clear(); } - { - std::unique_lock uniqueLock(asyncTaskMutex_); - LOGD("[CloudDBProxy] wait for all asyncTask begin"); - asyncTaskCv_.wait(uniqueLock, [this]() { - return asyncTaskCount_ <= 0; - }); - LOGD("[CloudDBProxy] wait for all asyncTask end"); - } LOGD("[CloudDBProxy] call cloudDb close begin"); - DBStatus status; + DBStatus status = OK; if (iCloudDb != nullptr) { status = iCloudDb->Close(); } @@ -213,6 +209,9 @@ int CloudDBProxy::Download(const std::string &tableName, const std::string &gid, LOGE("Asset loader has not been set %d", -E_NOT_SET); return -E_NOT_SET; } + if (assets.empty()) { + return E_OK; + } DBStatus status = iAssetLoader_->Download(tableName, gid, prefix, assets); if (status != OK) { LOGW("[CloudDBProxy] download asset failed %d", static_cast(status)); @@ -257,28 +256,8 @@ int CloudDBProxy::InnerAction(const std::shared_ptr &context if (action >= InnerActionCode::INVALID_ACTION) { return -E_INVALID_ARGS; } - { - std::lock_guard uniqueLock(asyncTaskMutex_); - asyncTaskCount_++; - } - int errCode = RuntimeContext::GetInstance()->ScheduleTask([cloudDb, context, action, this]() { - InnerActionTask(context, cloudDb, action); - }); - if (errCode != E_OK) { - { - std::lock_guard uniqueLock(asyncTaskMutex_); - asyncTaskCount_--; - } - asyncTaskCv_.notify_all(); - LOGW("[CloudDBProxy] Schedule async task error %d", errCode); - return errCode; - } - if (context->WaitForRes(timeout_)) { - errCode = context->GetActionRes(); - } else { - errCode = -E_TIMEOUT; - } - return errCode; + InnerActionTask(context, cloudDb, action); + return context->GetActionRes(); } DBStatus CloudDBProxy::DMLActionTask(const std::shared_ptr &context, @@ -365,7 +344,6 @@ void CloudDBProxy::InnerActionTask(const std::shared_ptr &co } context->FinishAndNotify(); - DecAsyncTaskCount(); } DBStatus CloudDBProxy::InnerActionLock(const std::shared_ptr &context, @@ -439,15 +417,6 @@ DBStatus CloudDBProxy::QueryAction(const std::shared_ptr &co return status; } -void CloudDBProxy::DecAsyncTaskCount() -{ - { - std::lock_guard uniqueLock(asyncTaskMutex_); - asyncTaskCount_--; - } - asyncTaskCv_.notify_all(); -} - CloudDBProxy::CloudActionContext::CloudActionContext() : actionFinished_(false), actionRes_(OK), @@ -517,20 +486,6 @@ void CloudDBProxy::CloudActionContext::MoveOutCursorStatus(std::pair uniqueLock(actionMutex_); - if (timeout == 0) { - actionCv_.wait(uniqueLock, [this]() { - return actionFinished_; - }); - return true; - } - return actionCv_.wait_for(uniqueLock, std::chrono::milliseconds(timeout), [this]() { - return actionFinished_; - }); -} - void CloudDBProxy::CloudActionContext::FinishAndNotify() { { diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_db_proxy.h b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_db_proxy.h index d527230a..56a65fef 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_db_proxy.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_db_proxy.h @@ -32,6 +32,8 @@ public: int SetCloudDB(const std::map> &cloudDBs); + const std::map> GetCloudDB() const; + void SwitchCloudDB(const std::string &user); void SetIAssetLoader(const std::shared_ptr &loader); @@ -93,8 +95,6 @@ protected: void MoveOutCursorStatus(std::pair &cursorStatus); - bool WaitForRes(int64_t timeout); - void SetActionRes(int res); int GetActionRes(); @@ -157,8 +157,6 @@ protected: static DBStatus QueryAction(const std::shared_ptr &context, const std::shared_ptr &cloudDb); - void DecAsyncTaskCount(); - mutable std::shared_mutex cloudMutex_; mutable std::shared_mutex assetLoaderMutex_; std::shared_ptr iCloudDb_; @@ -166,10 +164,6 @@ protected: std::shared_ptr iAssetLoader_; std::atomic timeout_; - std::mutex asyncTaskMutex_; - std::condition_variable asyncTaskCv_; - int32_t asyncTaskCount_; - mutable std::mutex genVersionMutex_; GenerateCloudVersionCallback genVersionCallback_; }; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_pull_strategy.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_pull_strategy.cpp index a2b45d13..d5959e70 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_pull_strategy.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_force_pull_strategy.cpp @@ -23,6 +23,9 @@ OpType CloudForcePullStrategy::TagSyncDataStatus(bool existInLocal, const LogInf return OpType::LOCKED_NOT_HANDLE; } if (existInLocal) { + if (IsIgnoreUpdate(localInfo)) { + return OpType::NOT_HANDLE; + } if (!IsDelete(localInfo) && IsDelete(cloudInfo)) { return OpType::DELETE; } else if (IsDelete(cloudInfo)) { diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_merge_strategy.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_merge_strategy.cpp index a0a684a9..cdb4a481 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_merge_strategy.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_merge_strategy.cpp @@ -31,6 +31,9 @@ OpType CloudMergeStrategy::TagSyncDataStatus(bool existInLocal, const LogInfo &l } return OpType::INSERT; } + if (IsIgnoreUpdate(localInfo)) { + return OpType::NOT_HANDLE; + } if (localInfo.timestamp > cloudInfo.timestamp) { return TagLocallyNewer(localInfo, cloudInfo, isCloudDelete, isLocalDelete); } @@ -43,7 +46,7 @@ OpType CloudMergeStrategy::TagSyncDataStatus(bool existInLocal, const LogInfo &l // avoid local data insert to cloud success but return failed // we just fill back gid here bool isTimeSame = (localInfo.timestamp == cloudInfo.timestamp) && (localInfo.wTimestamp == cloudInfo.wTimestamp); - if (isTimeSame && (localInfo.cloudGid.empty() || IsLogNeedUpdate(cloudInfo, localInfo))) { + if (isTimeSame && (localInfo.cloudGid.empty() || cloudInfo.sharingResource != localInfo.sharingResource)) { return OpType::ONLY_UPDATE_GID; } return TagUpdateLocal(cloudInfo, localInfo); diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_state_machine.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_state_machine.cpp index b07e4836..b080e2b6 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_state_machine.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_state_machine.cpp @@ -43,7 +43,11 @@ namespace { // In DO_UPLOAD state {State::DO_UPLOAD, Event::UPLOAD_FINISHED_EVENT, State::DO_FINISHED}, {State::DO_UPLOAD, Event::ERROR_EVENT, State::DO_FINISHED}, - {State::DO_UPLOAD, Event::REPEAT_DOWNLOAD_EVENT, State::DO_DOWNLOAD}, + {State::DO_UPLOAD, Event::REPEAT_CHECK_EVENT, State::DO_REPEAT_CHECK}, + + // Repeat download check state + {State::DO_REPEAT_CHECK, Event::REPEAT_DOWNLOAD_EVENT, State::DO_DOWNLOAD}, + {State::DO_REPEAT_CHECK, Event::ERROR_EVENT, State::DO_FINISHED}, // In DO_FINISHED state {State::DO_FINISHED, Event::ALL_TASK_FINISHED_EVENT, State::IDLE}, @@ -119,7 +123,7 @@ int CloudSyncStateMachine::SwitchMachineState(uint8_t event) { auto tableIter = std::find_if(stateSwitchTables_.begin(), stateSwitchTables_.end(), [](const CloudStateSwitchTable &table) { - return table.version <= 0; + return table.version == 0; }); if (tableIter == stateSwitchTables_.end()) { LOGE("[CloudSyncStateMachine][SwitchState] Can't find a compatible state switch table."); diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_state_machine.h b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_state_machine.h index b53fe410..19d85ebe 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_state_machine.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_state_machine.h @@ -39,7 +39,7 @@ public: ~CloudSyncStateMachine() = default; // Init the CloudSyncStateMachine - int Initialize(); + static int Initialize(); void SwitchStateAndStep(uint8_t event); diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_strategy.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_strategy.cpp index 493084ae..e79b0ae1 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_strategy.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_strategy.cpp @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "cloud/cloud_sync_strategy.h" +#include "cloud_sync_strategy.h" namespace DistributedDB { CloudSyncStrategy::CloudSyncStrategy() : policy_(SingleVerConflictResolvePolicy::DEFAULT_LAST_WIN) diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_tag_assets.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_tag_assets.cpp index 5d7f4bc7..0b19450d 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_tag_assets.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_tag_assets.cpp @@ -18,26 +18,23 @@ namespace DistributedDB { namespace { - -void TagSingleAsset(AssetOpType flag, AssetStatus status, Asset &asset, Assets &res, int &errCode) +void TagSingleAssetForDownload(AssetOpType flag, Asset &asset, Assets &res, int &errCode) { - uint32_t newStatus = static_cast(status); - if (flag == AssetOpType::DELETE && status == AssetStatus::DOWNLOADING && + uint32_t newStatus = static_cast(AssetStatus::DOWNLOADING); + if (flag == AssetOpType::DELETE && (AssetOperationUtils::EraseBitMask(asset.status) == AssetStatus::ABNORMAL || - asset.status == (AssetStatus::DOWNLOADING | AssetStatus::DOWNLOAD_WITH_NULL))) { + asset.status == (AssetStatus::DOWNLOADING | AssetStatus::DOWNLOAD_WITH_NULL))) { asset.flag = static_cast(AssetOpType::DELETE); res.push_back(asset); return; } if (AssetOperationUtils::EraseBitMask(asset.status) == static_cast(AssetStatus::DELETE)) { - if (status == AssetStatus::DOWNLOADING) { - newStatus = AssetStatus::DELETE; - } + newStatus = AssetStatus::DELETE; asset.flag = static_cast(AssetOpType::DELETE); } else { asset.flag = static_cast(flag); } - if (flag == AssetOpType::INSERT && status == AssetStatus::DOWNLOADING) { + if (flag == AssetOpType::INSERT) { newStatus |= AssetStatus::DOWNLOAD_WITH_NULL; } asset.status = static_cast(newStatus); @@ -54,14 +51,46 @@ void TagSingleAsset(AssetOpType flag, AssetStatus status, Asset &asset, Assets & res.push_back(asset); } +void TagSingleAssetForUpload(AssetOpType flag, Asset &asset, Assets &res, int &errCode) +{ + uint32_t lowBitStatus = AssetOperationUtils::EraseBitMask(asset.status); + if (lowBitStatus == static_cast(AssetStatus::DELETE)) { + return; + } + switch (flag) { + case AssetOpType::INSERT: { + asset.assetId.clear(); + asset.status = static_cast(AssetStatus::INSERT); + break; + } + case AssetOpType::DELETE: { + if (lowBitStatus != static_cast(AssetStatus::DELETE)) { + asset.status = static_cast(AssetStatus::DELETE | AssetStatus::HIDDEN); + } + break; + } + case AssetOpType::UPDATE: { + asset.status = static_cast(AssetStatus::UPDATE); + break; + } + case AssetOpType::NO_CHANGE: { + asset.status = static_cast(AssetStatus::NORMAL); + break; + } + default: + break; + } + res.push_back(asset); +} + void TagAssetWithNormalStatus(const bool isNormalStatus, AssetOpType flag, Asset &asset, Assets &res, int &errCode) { if (isNormalStatus) { - TagSingleAsset(flag, AssetStatus::NORMAL, asset, res, errCode); + TagSingleAssetForUpload(flag, asset, res, errCode); return; } - TagSingleAsset(flag, AssetStatus::DOWNLOADING, asset, res, errCode); + TagSingleAssetForDownload(flag, asset, res, errCode); } void TagAssetsWithNormalStatus(const bool isNormalStatus, AssetOpType flag, @@ -105,39 +134,41 @@ void TagAssetWithSameHash(const bool isNormalStatus, Asset &beCoveredAsset, Asse AssetOpType::INSERT : AssetOpType::NO_CHANGE, coveredAsset, res, errCode); } -Type &GetAssetsCaseInsensitive(const std::string &assetFieldName, VBucket &vBucket) -{ - for (auto &item : vBucket) { - if (DBCommon::CaseInsensitiveCompare(item.first, assetFieldName)) { - return item.second; - } - } - return vBucket[assetFieldName]; -} - -// AssetOpType and AssetStatus will be tagged, assets to be changed will be returned -// use VBucket rather than Type because we need to check whether it is empty -Assets TagAssets(const std::string &assetFieldName, VBucket &coveredData, VBucket &beCoveredData, - bool setNormalStatus, int &errCode) +std::pair TagForNotContainsAsset(const std::string &assetFieldName, VBucket &coveredData, + VBucket &beCoveredData, bool setNormalStatus, int &errCode) { - Assets res = {}; + std::pair res = { true, {} }; bool beCoveredHasAssets = IsDataContainField(assetFieldName, beCoveredData); bool coveredHasAssets = IsDataContainField(assetFieldName, coveredData); if (!beCoveredHasAssets) { if (coveredHasAssets) { // all the element in assets will be set to INSERT TagAssetsWithNormalStatus(setNormalStatus, AssetOpType::INSERT, - std::get(GetAssetsCaseInsensitive(assetFieldName, coveredData)), res, errCode); + std::get(GetAssetsCaseInsensitive(assetFieldName, coveredData)), res.second, errCode); } return res; } if (!coveredHasAssets) { // all the element in assets will be set to DELETE TagAssetsWithNormalStatus(setNormalStatus, AssetOpType::DELETE, - std::get(GetAssetsCaseInsensitive(assetFieldName, beCoveredData)), res, errCode); - GetAssetsCaseInsensitive(assetFieldName, coveredData) = res; + std::get(GetAssetsCaseInsensitive(assetFieldName, beCoveredData)), res.second, errCode); + GetAssetsCaseInsensitive(assetFieldName, coveredData) = res.second; return res; } + return { false, {} }; +} + +// AssetOpType and AssetStatus will be tagged, assets to be changed will be returned +// use VBucket rather than Type because we need to check whether it is empty +Assets TagAssets(const std::string &assetFieldName, VBucket &coveredData, VBucket &beCoveredData, + bool setNormalStatus, int &errCode) +{ + auto [isReturn, resAsset] = TagForNotContainsAsset(assetFieldName, coveredData, beCoveredData, + setNormalStatus, errCode); + if (isReturn) { + return resAsset; + } + Assets res = {}; Assets &covered = std::get(GetAssetsCaseInsensitive(assetFieldName, coveredData)); Assets &beCovered = std::get(GetAssetsCaseInsensitive(assetFieldName, beCoveredData)); std::map coveredAssetsIndexMap = CloudStorageUtils::GenAssetsIndexMap(covered); @@ -149,6 +180,10 @@ Assets TagAssets(const std::string &assetFieldName, VBucket &coveredData, VBucke continue; } Asset &coveredAsset = covered[it->second]; + if (setNormalStatus) { + // fill asset id for upload data + coveredAsset.assetId = beCoveredAsset.assetId; + } if (beCoveredAsset.hash != coveredAsset.hash) { TagAssetWithNormalStatus(setNormalStatus, AssetOpType::UPDATE, coveredAsset, res, errCode); } else { @@ -216,6 +251,10 @@ Assets TagAsset(const std::string &assetFieldName, VBucket &coveredData, VBucket TagAssetWithNormalStatus(setNormalStatus, AssetOpType::DELETE, beCovered, res, errCode); return res; } + if (setNormalStatus) { + // fill asset id for upload data + covered.assetId = beCovered.assetId; + } if (covered.hash != beCovered.hash) { TagAssetWithNormalStatus(setNormalStatus, AssetOpType::UPDATE, covered, res, errCode); } else { @@ -224,6 +263,53 @@ Assets TagAsset(const std::string &assetFieldName, VBucket &coveredData, VBucket } return res; } + +void MarkAssetForUpload(Asset &asset, bool isInsert) +{ + uint32_t newStatus = static_cast(AssetStatus::NORMAL); + uint32_t lowBitStatus = AssetOperationUtils::EraseBitMask(asset.status); + if (lowBitStatus == AssetStatus::DELETE) { + asset.flag = static_cast(AssetOpType::DELETE); + } else if (isInsert) { + asset.flag = static_cast(AssetOpType::INSERT); + } else if (asset.status == AssetStatus::NORMAL) { + asset.flag = static_cast(AssetOpType::NO_CHANGE); + } else if (asset.assetId.empty()) { + asset.flag = static_cast(AssetOpType::INSERT); + } else if (!asset.assetId.empty()) { + asset.flag = static_cast(AssetOpType::UPDATE); + } else { + asset.flag = static_cast(AssetOpType::NO_CHANGE); + } + asset.status = newStatus; + Timestamp timestamp; + int errCode = OS::GetCurrentSysTimeInMicrosecond(timestamp); + if (errCode != E_OK) { + LOGE("Can not get current timestamp. %d", errCode); + return; + } + asset.timestamp = static_cast(timestamp / CloudDbConstant::TEN_THOUSAND); +} + +void TagAssetsForUpload(const std::string &filedName, VBucket &coveredData, bool isInsert) +{ + if (!IsDataContainField(filedName, coveredData)) { + return; + } + Assets &covered = std::get(GetAssetsCaseInsensitive(filedName, coveredData)); + for (auto &asset: covered) { + MarkAssetForUpload(asset, isInsert); + } +} + +void TagAssetForUpload(const std::string &filedName, VBucket &coveredData, bool isInsert) +{ + if (!IsDataContainField(filedName, coveredData)) { + return; + } + Asset &asset = std::get(GetAssetsCaseInsensitive(filedName, coveredData)); + MarkAssetForUpload(asset, isInsert); +} } // namespace Assets TagAssetsInSingleCol( @@ -246,4 +332,31 @@ Assets TagAssetsInSingleCol( } return assets; } + +Type &GetAssetsCaseInsensitive(const std::string &assetFieldName, VBucket &vBucket) +{ + for (auto &item : vBucket) { + if (DBCommon::CaseInsensitiveCompare(item.first, assetFieldName)) { + return item.second; + } + } + return vBucket[assetFieldName]; +} + +void TagAssetsInSingleCol(const Field &assetField, VBucket &coveredData, bool isInsert) +{ + switch (assetField.type) { + case TYPE_INDEX: { + TagAssetsForUpload(assetField.colName, coveredData, isInsert); + break; + } + case TYPE_INDEX: { + TagAssetForUpload(assetField.colName, coveredData, isInsert); + break; + } + default: + LOGW("[CloudSyncer] Meet an unexpected type %d", assetField.type); + break; + } +} } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_tag_assets.h b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_tag_assets.h index 76780056..cdea9a05 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_tag_assets.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_tag_assets.h @@ -30,5 +30,7 @@ namespace DistributedDB { Assets TagAssetsInSingleCol( VBucket &coveredData, VBucket &beCoveredData, const Field &assetField, bool setNormalStatus, int &errCode); +Type &GetAssetsCaseInsensitive(const std::string &assetFieldName, VBucket &vBucket); +void TagAssetsInSingleCol(const Field &assetField, VBucket &coveredData, bool isInsert); } // namespace DistributedDB #endif // CLOUD_SYNC_TAG_ASSETS_H \ No newline at end of file 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 47bdb9fa..43fd6434 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 @@ -430,7 +430,7 @@ void CloudSyncUtils::ClearWithoutData(ICloudSyncer::SyncParam ¶m) int CloudSyncUtils::FillAssetIdToAssets(CloudSyncBatch &data, int errorCode) { if (data.extend.size() != data.assets.size()) { - LOGE("[CloudSyncUtils][FillAssetIdToAssets] Extend size does not match the assets size."); + LOGE("[CloudSyncUtils] size not match, extend:%zu assets:%zu.", data.extend.size(), data.assets.size()); return -E_CLOUD_ERROR; } int errCode = E_OK; @@ -450,18 +450,19 @@ int CloudSyncUtils::FillAssetIdToAssets(CloudSyncBatch &data, int errorCode) } auto extendIt = data.extend[i].find(col); if (extendIt == data.extend[i].end()) { - LOGE("[CloudSyncUtils][FillAssetIdToAssets] Asset field name can not find in extend."); + LOGE("[CloudSyncUtils] Asset field name can not find in extend."); errCode = -E_CLOUD_ERROR; continue; } if (extendIt->second.index() != value.index()) { - LOGE("[CloudSyncUtils][FillAssetIdToAssets] Asset field type and type in extend is not the same."); + LOGE("[CloudSyncUtils] Asset field type not same. extend:%zu, data:%zu", + extendIt->second.index(), value.index()); errCode = -E_CLOUD_ERROR; continue; } int ret = FillAssetIdToAssetData(extendIt->second, value); if (ret != E_OK) { - LOGE("[CloudSyncUtils][FillAssetIdToAssets] Failed to fill assetId to Asset, %d.", ret); + LOGE("[CloudSyncUtils] fail to fill assetId, %d.", ret); errCode = -E_CLOUD_ERROR; } } 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 17182395..dee07b3e 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 @@ -24,6 +24,7 @@ #include "cloud/icloud_db.h" #include "cloud_sync_tag_assets.h" #include "cloud_sync_utils.h" +#include "db_dfx_adapter.h" #include "db_errno.h" #include "log_print.h" #include "runtime_context.h" @@ -39,8 +40,6 @@ CloudSyncer::CloudSyncer(std::shared_ptr storageProxy, SingleVerCo queuedManualSyncLimit_(DBConstant::QUEUED_SYNC_LIMIT_DEFAULT), closed_(false), timerId_(0u), - heartBeatCount_(0), - failedHeartBeatCount_(0), policy_(policy) { if (storageProxy_ != nullptr) { @@ -49,20 +48,6 @@ CloudSyncer::CloudSyncer(std::shared_ptr storageProxy, SingleVerCo InitCloudSyncStateMachine(); } -void CloudSyncer::InitCloudSyncStateMachine() -{ - cloudSyncStateMachine_.Initialize(); - cloudSyncStateMachine_.RegisterFunc(CloudSyncState::DO_DOWNLOAD, [this]() { - return SyncMachineDoDownload(); - }); - cloudSyncStateMachine_.RegisterFunc(CloudSyncState::DO_UPLOAD, [this]() { - return SyncMachineDoUpload(); - }); - cloudSyncStateMachine_.RegisterFunc(CloudSyncState::DO_FINISHED, [this]() { - return SyncMachineDoFinished(); - }); -} - int CloudSyncer::Sync(const std::vector &devices, SyncMode mode, const std::vector &tables, const SyncProcessCallback &callback, int64_t waitTime) { @@ -112,6 +97,11 @@ void CloudSyncer::SetCloudDB(const std::shared_ptr &cloudDB) LOGI("[CloudSyncer] SetCloudDB finish"); } +const std::map> CloudSyncer::GetCloudDB() const +{ + return cloudDB_.GetCloudDB(); +} + void CloudSyncer::SetIAssetLoader(const std::shared_ptr &loader) { storageProxy_->SetIAssetLoader(loader); @@ -131,32 +121,37 @@ void CloudSyncer::Close() SetTaskFailed(currentTask, -E_DB_CLOSED); UnlockIfNeed(); cloudDB_.Close(); - { - LOGD("[CloudSyncer] begin wait current task finished"); - std::unique_lock uniqueLock(dataLock_); - contextCv_.wait(uniqueLock, [this]() { - return currentContext_.currentTaskId == INVALID_TASK_ID; - }); - LOGD("[CloudSyncer] current task has been finished"); - } + WaitCurTaskFinished(); // copy all task from queue - std::vector infoList; + std::vector infoList = CopyAndClearTaskInfos(); + for (auto &info: infoList) { + LOGI("[CloudSyncer] finished taskId %" PRIu64 " with db closed.", info.taskId); + } + storageProxy_->Close(); +} + +void CloudSyncer::StopAllTasks() +{ + CloudSyncer::TaskId currentTask; { std::lock_guard autoLock(dataLock_); - for (const auto &item: cloudTaskInfos_) { - infoList.push_back(item.second); - } - taskQueue_.clear(); - priorityTaskQueue_.clear(); - cloudTaskInfos_.clear(); - resumeTaskInfos_.clear(); - currentContext_.notifier = nullptr; + currentTask = currentContext_.currentTaskId; } + // mark current task user_change + SetTaskFailed(currentTask, -E_USER_CHANGE); + UnlockIfNeed(); + WaitCurTaskFinished(); + + std::vector infoList = CopyAndClearTaskInfos(); for (auto &info: infoList) { - LOGI("[CloudSyncer] finished taskId %" PRIu64 " with db closed.", info.taskId); + LOGI("[CloudSyncer] finished taskId %" PRIu64 " with user changed.", info.taskId); + auto processNotifier = std::make_shared(this); + processNotifier->Init(info.table, info.devices, info.users); + info.errCode = -E_USER_CHANGE; + info.status = ProcessStatus::FINISHED; + processNotifier->NotifyProcess(info, {}, true); } - storageProxy_->Close(); } int CloudSyncer::TriggerSync() @@ -227,6 +222,7 @@ void CloudSyncer::DoSyncIfNeed() int CloudSyncer::DoSync(TaskId taskId) { std::lock_guard lock(syncMutex_); + ResetCurrentTableUploadBatchIndex(); CloudTaskInfo taskInfo; { std::lock_guard autoLock(dataLock_); @@ -247,10 +243,7 @@ int CloudSyncer::DoSync(TaskId taskId) if (isNeedFirstDownload) { // do first download errCode = DoDownloadInNeed(taskInfo, needUpload, isFirstDownload); - { - std::lock_guard autoLock(dataLock_); - cloudTaskInfos_[currentContext_.currentTaskId].errCode = errCode; - } + SetTaskFailed(taskId, errCode); if (errCode != E_OK) { SyncMachineDoFinished(); return errCode; @@ -288,11 +281,15 @@ int CloudSyncer::PrepareAndUpload(const CloudTaskInfo &taskInfo, size_t index) LOGE("[CloudSyncer] task is invalid, abort sync"); return errCode; } + if (taskInfo.table.empty()) { + LOGE("[CloudSyncer] Invalid taskInfo table"); + return -E_INVALID_ARGS; + } errCode = DoUpload(taskInfo.taskId, index == (taskInfo.table.size() - 1u), taskInfo.lockAction); if (errCode == -E_CLOUD_VERSION_CONFLICT) { { std::lock_guard autoLock(dataLock_); - currentContext_.isDownloadFinished[taskInfo.table[index]] = false; + currentContext_.isDownloadFinished[currentContext_.currentUserIndex][taskInfo.table[index]] = false; LOGI("[CloudSyncer] upload version conflict, index:%zu", index); } return errCode; @@ -350,14 +347,26 @@ CloudSyncEvent CloudSyncer::SyncMachineDoDownload() needUpload = currentContext_.isRealNeedUpload; isFirstDownload = currentContext_.isFirstDownload; } - int errCode = DoDownloadInNeed(taskInfo, needUpload, isFirstDownload); + int errCode = E_OK; + if (IsLockInDownload()) { + errCode = LockCloudIfNeed(taskInfo.taskId); + } if (errCode != E_OK) { - { - std::lock_guard autoLock(dataLock_); - cloudTaskInfos_[currentContext_.currentTaskId].errCode = errCode; + return SetCurrentTaskFailedInMachine(errCode); + } + errCode = DoDownloadInNeed(taskInfo, needUpload, isFirstDownload); + if (errCode != E_OK) { + if (errCode == -E_TASK_PAUSED) { + DBDfxAdapter::ReportBehavior( + {__func__, Scene::CLOUD_SYNC, State::END, Stage::CLOUD_DOWNLOAD, StageResult::CANCLE, errCode}); + } else { + DBDfxAdapter::ReportBehavior( + {__func__, Scene::CLOUD_SYNC, State::END, Stage::CLOUD_DOWNLOAD, StageResult::FAIL, errCode}); } - return CloudSyncEvent::ERROR_EVENT; + return SetCurrentTaskFailedInMachine(errCode); } + DBDfxAdapter::ReportBehavior( + {__func__, Scene::CLOUD_SYNC, State::END, Stage::CLOUD_DOWNLOAD, StageResult::SUCC, errCode}); return CloudSyncEvent::DOWNLOAD_FINISHED_EVENT; } @@ -370,23 +379,36 @@ CloudSyncEvent CloudSyncer::SyncMachineDoUpload() taskInfo = cloudTaskInfos_[currentContext_.currentTaskId]; needUpload = currentContext_.isRealNeedUpload; } + DBDfxAdapter::ReportBehavior( + {__func__, Scene::CLOUD_SYNC, State::BEGIN, Stage::CLOUD_UPLOAD, StageResult::SUCC, E_OK}); int errCode = DoUploadInNeed(taskInfo, needUpload); if (errCode == -E_CLOUD_VERSION_CONFLICT) { - return CloudSyncEvent::REPEAT_DOWNLOAD_EVENT; + DBDfxAdapter::ReportBehavior( + {__func__, Scene::CLOUD_SYNC, State::END, Stage::CLOUD_UPLOAD, StageResult::FAIL, errCode}); + return CloudSyncEvent::REPEAT_CHECK_EVENT; } if (errCode != E_OK) { { std::lock_guard autoLock(dataLock_); cloudTaskInfos_[currentContext_.currentTaskId].errCode = errCode; } + if (errCode == -E_TASK_PAUSED) { + DBDfxAdapter::ReportBehavior( + {__func__, Scene::CLOUD_SYNC, State::END, Stage::CLOUD_UPLOAD, StageResult::CANCLE, errCode}); + } else { + DBDfxAdapter::ReportBehavior( + {__func__, Scene::CLOUD_SYNC, State::END, Stage::CLOUD_UPLOAD, StageResult::FAIL, errCode}); + } return CloudSyncEvent::ERROR_EVENT; } - + DBDfxAdapter::ReportBehavior( + {__func__, Scene::CLOUD_SYNC, State::END, Stage::CLOUD_UPLOAD, StageResult::SUCC, errCode}); return CloudSyncEvent::UPLOAD_FINISHED_EVENT; } CloudSyncEvent CloudSyncer::SyncMachineDoFinished() { + UnlockIfNeed(); TaskId taskId; int errCode; int currentUserIndex; @@ -397,10 +419,18 @@ CloudSyncEvent CloudSyncer::SyncMachineDoFinished() errCode = cloudTaskInfos_[currentContext_.currentTaskId].errCode; cloudTaskInfos_[currentContext_.currentTaskId].errCode = E_OK; currentUserIndex = currentContext_.currentUserIndex; - userListSize = cloudTaskInfos_[taskId].users.size(); + userListSize = static_cast(cloudTaskInfos_[taskId].users.size()); } if (currentUserIndex >= userListSize) { DoFinished(taskId, errCode); + } else { + CloudTaskInfo taskInfo; + { + std::lock_guard autoLock(dataLock_); + taskInfo = cloudTaskInfos_[currentContext_.currentTaskId]; + } + taskInfo.status = ProcessStatus::FINISHED; + currentContext_.notifier->NotifyProcess(taskInfo, {}); } return CloudSyncEvent::ALL_TASK_FINISHED_EVENT; } @@ -408,6 +438,8 @@ CloudSyncEvent CloudSyncer::SyncMachineDoFinished() int CloudSyncer::DoSyncInner(const CloudTaskInfo &taskInfo, const bool needUpload, bool isFirstDownload) { cloudSyncStateMachine_.SwitchStateAndStep(CloudSyncEvent::START_SYNC_EVENT); + DBDfxAdapter::ReportBehavior( + {__func__, Scene::CLOUD_SYNC, State::BEGIN, Stage::CLOUD_SYNC, StageResult::SUCC, E_OK}); return E_OK; } @@ -415,6 +447,8 @@ void CloudSyncer::DoFinished(TaskId taskId, int errCode) { storageProxy_->OnSyncFinish(); if (errCode == -E_TASK_PAUSED) { + DBDfxAdapter::ReportBehavior( + {__func__, Scene::CLOUD_SYNC, State::END, Stage::CLOUD_SYNC, StageResult::CANCLE, errCode}); LOGD("[CloudSyncer] taskId %" PRIu64 " was paused, it won't be finished now", taskId); { std::lock_guard autoLock(dataLock_); @@ -503,7 +537,6 @@ bool CloudSyncer::IsDataContainAssets() return false; } if (currentContext_.assetFields[currentContext_.tableName].empty()) { - LOGI("[CloudSyncer] Current table do not contain assets, thereby we needn't download assets"); return false; } return true; @@ -713,14 +746,9 @@ int CloudSyncer::TagDownloadAssets(const Key &hashKey, size_t idx, SyncParam &pa case OpType::NOT_HANDLE: case OpType::ONLY_UPDATE_GID: case OpType::SET_CLOUD_FORCE_PUSH_FLAG_ZERO: { // means upload need this data - // Save the asset info into context - std::map assetsMap = GetAssetsFromVBucket(param.downloadData.data[idx]); - { - std::lock_guard autoLock(dataLock_); - if (currentContext_.assetsInfo.find(param.tableName) == currentContext_.assetsInfo.end()) { - currentContext_.assetsInfo[param.tableName] = {}; - } - currentContext_.assetsInfo[param.tableName][dataInfo.cloudLogInfo.cloudGid] = assetsMap; + (void)TagAssetsInSingleRecord(localAssetInfo, param.downloadData.data[idx], true, ret); + for (const auto &[col, value]: localAssetInfo) { + param.downloadData.data[idx].insert_or_assign(col, value); } break; } @@ -755,7 +783,7 @@ int CloudSyncer::HandleTagAssets(const Key &hashKey, const DataInfo &dataInfo, s LOGE("[CloudSyncer] TagAssetsInSingleRecord report ERROR in download data"); return ret; } - + strategy = CloudSyncUtils::CalOpType(param, idx); if (!param.isSinglePrimaryKey && strategy == OpType::INSERT) { param.withoutRowIdData.assetInsertData.push_back(std::make_tuple(idx, param.assetsDownloadList.size())); } @@ -801,7 +829,7 @@ int CloudSyncer::SaveDatum(SyncParam ¶m, size_t idx, std::vector(lastData[CloudDbConstant::CURSOR_FIELD]); + if (!IsQueryListEmpty(taskId) && param.isLastBatch) { + // the last batch of cursor in the conditional query is useless + param.cloudWaterMark = {}; + } else { + param.cloudWaterMark = std::get(lastData[CloudDbConstant::CURSOR_FIELD]); + } return UpdateFlagForSavedRecord(param); } @@ -907,6 +940,8 @@ int CloudSyncer::NotifyChangedData(ChangedData &&changedData) std::lock_guard autoLock(dataLock_); std::vector devices = currentContext_.notifier->GetDevices(); if (devices.empty()) { + DBDfxAdapter::ReportBehavior( + {__func__, Scene::CLOUD_SYNC, State::END, Stage::CLOUD_NOTIFY, StageResult::FAIL, -E_CLOUD_ERROR}); LOGE("[CloudSyncer] CurrentContext do not contain device info"); return -E_CLOUD_ERROR; } @@ -915,8 +950,12 @@ int CloudSyncer::NotifyChangedData(ChangedData &&changedData) } int ret = storageProxy_->NotifyChangedData(deviceName, std::move(changedData)); if (ret != E_OK) { + DBDfxAdapter::ReportBehavior( + {__func__, Scene::CLOUD_SYNC, State::END, Stage::CLOUD_NOTIFY, StageResult::FAIL, ret}); LOGE("[CloudSyncer] Cannot notify changed data while downloading, %d.", ret); } + DBDfxAdapter::ReportBehavior( + {__func__, Scene::CLOUD_SYNC, State::END, Stage::CLOUD_NOTIFY, StageResult::FAIL, ret}); return ret; } @@ -953,7 +992,7 @@ int CloudSyncer::SaveDataInTransaction(CloudSyncer::TaskId taskId, SyncParam &pa param.changedData.field = param.pkColNames; param.changedData.type = ChangedDataType::DATA; } - ret = SaveData(param); + ret = SaveData(taskId, param); param.insertPk.clear(); if (ret != E_OK) { LOGE("[CloudSyncer] cannot save data: %d.", ret); @@ -1220,7 +1259,8 @@ int CloudSyncer::DoUpload(CloudSyncer::TaskId taskId, bool lastTable, LockAction int64_t count = 0; ret = storageProxy_->GetUploadCount(GetQuerySyncObject(tableName), IsModeForcePush(taskId), - IsCompensatedTask(taskId), IsPriorityTask(taskId), count); + IsCompensatedTask(taskId), IsNeedGetLocalWater(taskId), count); + LOGI("get upload count:%zu", count); if (ret != E_OK) { // GetUploadCount will return E_OK when upload count is zero. LOGE("[CloudSyncer] Failed to get Upload Data Count, %d.", ret); @@ -1238,62 +1278,6 @@ int CloudSyncer::DoUpload(CloudSyncer::TaskId taskId, bool lastTable, LockAction return DoUploadInner(tableName, param); } -int CloudSyncer::TagUploadAssets(CloudSyncData &uploadData) -{ - int errCode = E_OK; - if (!IsDataContainAssets()) { - return E_OK; - } - std::map> cloudAssets; - { - std::lock_guard autoLock(dataLock_); - cloudAssets = currentContext_.assetsInfo[currentContext_.tableName]; - } - // for delete scenario, assets should not appear in the records. Thereby we needn't tag the assests. - // for insert scenario, gid does not exist. Thereby, we needn't compare with cloud asset get in download procedure - for (size_t i = 0; i < uploadData.insData.extend.size(); i++) { - VBucket cloudAsset; // cloudAsset must be empty - (void)TagAssetsInSingleRecord(uploadData.insData.record[i], cloudAsset, true, errCode); - if (errCode != E_OK) { - LOGE("[CloudSyncer] TagAssetsInSingleRecord report ERROR in DELETE/INSERT option"); - return errCode; - } - } - // for update scenario, assets shoulb be compared with asset get in download procedure. - for (size_t i = 0; i < uploadData.updData.extend.size(); i++) { - VBucket cloudAsset; - // gid must exist in UPDATE scenario, cause we have re-fill gid during download procedure - // But we need to check for safety - auto gidIter = uploadData.updData.extend[i].find(CloudDbConstant::GID_FIELD); - if (gidIter == uploadData.updData.extend[i].end()) { - LOGE("[CloudSyncer] Datum to be upload must contain gid"); - return -E_INVALID_DATA; - } - // update data must contain gid, however, we could only pull data after water mark - // Therefore, we need to check whether we contain the data - std::string &gid = std::get(gidIter->second); - if (cloudAssets.find(gid) == cloudAssets.end()) { - // In this case, we directly upload data without compartion and tagging - std::vector assetFields; - { - std::lock_guard autoLock(dataLock_); - assetFields = currentContext_.assetFields[currentContext_.tableName]; - } - CloudSyncUtils::StatusToFlagForAssetsInRecord(assetFields, uploadData.updData.record[i]); - continue; - } - for (const auto &it : cloudAssets[gid]) { - cloudAsset[it.first] = it.second; - } - (void)TagAssetsInSingleRecord(uploadData.updData.record[i], cloudAsset, true, errCode); - if (errCode != E_OK) { - LOGE("[CloudSyncer] TagAssetsInSingleRecord report ERROR in UPDATE option"); - return errCode; - } - } - return E_OK; -} - int CloudSyncer::PreProcessBatchUpload(UploadParam &uploadParam, const InnerProcessInfo &innerProcessInfo, CloudSyncData &uploadData) { @@ -1329,11 +1313,14 @@ int CloudSyncer::SaveCloudWaterMark(const TableName &tableName, const TaskId tas bool isUpdateCloudCursor = true; { std::lock_guard autoLock(dataLock_); - if (currentContext_.cloudWaterMarks.find(tableName) == currentContext_.cloudWaterMarks.end()) { + if (currentContext_.cloudWaterMarks.find(currentContext_.currentUserIndex) == + currentContext_.cloudWaterMarks.end() || + currentContext_.cloudWaterMarks[currentContext_.currentUserIndex].find(tableName) == + currentContext_.cloudWaterMarks[currentContext_.currentUserIndex].end()) { LOGD("[CloudSyncer] Not found water mark just return"); return E_OK; } - cloudWaterMark = currentContext_.cloudWaterMarks[tableName]; + cloudWaterMark = currentContext_.cloudWaterMarks[currentContext_.currentUserIndex][tableName]; isUpdateCloudCursor = currentContext_.strategy->JudgeUpdateCursor(); } isUpdateCloudCursor = isUpdateCloudCursor && !(IsPriorityTask(taskId) && !IsQueryListEmpty(taskId)); @@ -1354,7 +1341,7 @@ void CloudSyncer::SetUploadDataFlag(const TaskId taskId, CloudSyncData& uploadDa uploadData.isCompensatedTask = cloudTaskInfos_[taskId].compensatedTask; } -bool CloudSyncer::IsModeForcePush(const TaskId taskId) +bool CloudSyncer::IsModeForcePush(TaskId taskId) { std::lock_guard autoLock(dataLock_); return cloudTaskInfos_[taskId].mode == SYNC_MODE_CLOUD_FORCE_PUSH; @@ -1387,6 +1374,7 @@ int CloudSyncer::DoUploadByMode(const std::string &tableName, UploadParam &uploa return ret; } uploadParam.count -= uploadData.ignoredCount; + info.upLoadInfo.total -= static_cast(uploadData.ignoredCount); ret = HandleBatchUpload(uploadParam, info, uploadData, continueStmtToken); if (ret != -E_TASK_PAUSED) { // reset watermark to zero when task no paused @@ -1444,11 +1432,7 @@ int CloudSyncer::QueryCloudData(TaskId taskId, const std::string &tableName, std return ret; } ret = cloudDB_.Query(tableName, extend, downloadData.data); - if (ret == -E_QUERY_END) { - LOGD("[CloudSyncer] Download data from cloud database success and no more data need to be downloaded"); - return -E_QUERY_END; - } - if (ret == E_OK && downloadData.data.empty()) { + if ((ret == E_OK || ret == -E_QUERY_END) && downloadData.data.empty()) { if (extend[CloudDbConstant::CURSOR_FIELD].index() != TYPE_INDEX) { LOGE("[CloudSyncer] cursor type is not valid=%d", extend[CloudDbConstant::CURSOR_FIELD].index()); return -E_CLOUD_ERROR; @@ -1457,6 +1441,10 @@ int CloudSyncer::QueryCloudData(TaskId taskId, const std::string &tableName, std LOGD("[CloudSyncer] Download data is empty, try to use other cursor=%s", cloudWaterMark.c_str()); return ret; } + if (ret == -E_QUERY_END) { + LOGD("[CloudSyncer] Download data from cloud database success and no more data need to be downloaded"); + return -E_QUERY_END; + } if (ret != E_OK) { LOGE("[CloudSyncer] Download data from cloud database unsuccess %d", ret); } @@ -1529,9 +1517,10 @@ int CloudSyncer::PrepareSync(TaskId taskId) } else { currentContext_.notifier = std::make_shared(this); currentContext_.strategy = StrategyFactory::BuildSyncStrategy(cloudTaskInfos_[taskId].mode, policy_); - currentContext_.notifier->Init(cloudTaskInfos_[taskId].table, cloudTaskInfos_[taskId].devices); + currentContext_.notifier->Init(cloudTaskInfos_[taskId].table, cloudTaskInfos_[taskId].devices, + cloudTaskInfos_[taskId].users); } - LOGI("[CloudSyncer] exec taskId %" PRIu64, taskId); + LOGI("[CloudSyncer] exec storeId %.3s taskId %" PRIu64, cloudTaskInfos_[taskId].storeId.c_str(), taskId); return E_OK; } @@ -1556,7 +1545,6 @@ int CloudSyncer::UnlockCloud() { FinishHeartBeatTimer(); int errCode = cloudDB_.UnLock(); - WaitAllHeartBeatTaskExit(); return errCode; } @@ -1589,30 +1577,27 @@ void CloudSyncer::FinishHeartBeatTimer() LOGD("[CloudSyncer] Finish heartbeat timer ok"); } -void CloudSyncer::WaitAllHeartBeatTaskExit() -{ - std::unique_lock uniqueLock(heartbeatMutex_); - if (heartBeatCount_ <= 0) { - return; - } - LOGD("[CloudSyncer] Begin wait all heartbeat task exit"); - heartbeatCv_.wait(uniqueLock, [this]() { - return heartBeatCount_ <= 0; - }); - LOGD("[CloudSyncer] End wait all heartbeat task exit"); -} - void CloudSyncer::HeartBeat(TimerId timerId, TaskId taskId) { if (timerId_ != timerId) { return; } + IncObjRef(this); { std::lock_guard autoLock(heartbeatMutex_); - heartBeatCount_++; + heartbeatCount_[taskId]++; } int errCode = RuntimeContext::GetInstance()->ScheduleTask([this, taskId]() { - if (heartBeatCount_ >= HEARTBEAT_PERIOD) { + { + std::lock_guard guard(dataLock_); + if (currentContext_.currentTaskId != taskId) { + heartbeatCount_.erase(taskId); + failedHeartbeatCount_.erase(taskId); + DecObjRef(this); + return; + } + } + if (heartbeatCount_[taskId] >= HEARTBEAT_PERIOD) { // heartbeat block twice should finish task now SetTaskFailed(taskId, -E_CLOUD_ERROR); } else { @@ -1620,29 +1605,29 @@ void CloudSyncer::HeartBeat(TimerId timerId, TaskId taskId) if (ret != E_OK) { HeartBeatFailed(taskId, ret); } else { - failedHeartBeatCount_ = 0; + failedHeartbeatCount_[taskId] = 0; } } { std::lock_guard autoLock(heartbeatMutex_); - heartBeatCount_--; + heartbeatCount_[taskId]--; + if (currentContext_.currentTaskId != taskId) { + heartbeatCount_.erase(taskId); + failedHeartbeatCount_.erase(taskId); + } } - heartbeatCv_.notify_all(); + DecObjRef(this); }); if (errCode != E_OK) { LOGW("[CloudSyncer] schedule heartbeat task failed %d", errCode); - { - std::lock_guard autoLock(heartbeatMutex_); - heartBeatCount_--; - } - heartbeatCv_.notify_all(); + DecObjRef(this); } } void CloudSyncer::HeartBeatFailed(TaskId taskId, int errCode) { - failedHeartBeatCount_++; - if (failedHeartBeatCount_ < MAX_HEARTBEAT_FAILED_LIMIT) { + failedHeartbeatCount_[taskId]++; + if (failedHeartbeatCount_[taskId] < MAX_HEARTBEAT_FAILED_LIMIT) { return; } LOGW("[CloudSyncer] heartbeat failed too much times!"); @@ -1665,7 +1650,7 @@ void CloudSyncer::SetTaskFailed(TaskId taskId, int errCode) int32_t CloudSyncer::GetCloudSyncTaskCount() { std::lock_guard autoLock(dataLock_); - return taskQueue_.size(); + return static_cast(taskQueue_.size() + priorityTaskQueue_.size()); } int CloudSyncer::CleanCloudData(ClearMode mode, const std::vector &tableNameList, @@ -1726,7 +1711,7 @@ void CloudSyncer::UpdateCloudWaterMark(TaskId taskId, const SyncParam ¶m) { { std::lock_guard autoLock(dataLock_); - currentContext_.cloudWaterMarks[param.info.tableName] = param.cloudWaterMark; + currentContext_.cloudWaterMarks[currentContext_.currentUserIndex][param.info.tableName] = param.cloudWaterMark; } } @@ -1778,6 +1763,39 @@ int CloudSyncer::TagStatusByStrategy(bool isExist, SyncParam ¶m, DataInfo &d return E_OK; } +int CloudSyncer::GetLocalInfo(size_t index, SyncParam ¶m, DataInfoWithLog &logInfo, + std::map &localLogInfoCache, VBucket &localAssetInfo) +{ + int errCode = storageProxy_->GetInfoByPrimaryKeyOrGid(param.tableName, param.downloadData.data[index], + logInfo, localAssetInfo); + if (errCode != E_OK && errCode != -E_NOT_FOUND) { + return errCode; + } + std::string hashKey(logInfo.logInfo.hashKey.begin(), logInfo.logInfo.hashKey.end()); + if (hashKey.empty()) { + return errCode; + } + param.downloadData.existDataKey[index] = logInfo.logInfo.dataKey; + param.downloadData.existDataHashKey[index] = logInfo.logInfo.hashKey; + if (localLogInfoCache.find(hashKey) != localLogInfoCache.end()) { + LOGD("[CloudSyncer] exist same record in one batch, override from cache record! hash=%.3s", + DBCommon::TransferStringToHex(hashKey).c_str()); + logInfo.logInfo.flag = localLogInfoCache[hashKey].flag; + logInfo.logInfo.wTimestamp = localLogInfoCache[hashKey].wTimestamp; + logInfo.logInfo.timestamp = localLogInfoCache[hashKey].timestamp; + logInfo.logInfo.cloudGid = localLogInfoCache[hashKey].cloudGid; + logInfo.logInfo.device = localLogInfoCache[hashKey].device; + logInfo.logInfo.sharingResource = localLogInfoCache[hashKey].sharingResource; + logInfo.logInfo.status = localLogInfoCache[hashKey].status; + // delete record should remove local asset info + if ((localLogInfoCache[hashKey].flag & DataItem::DELETE_FLAG) == DataItem::DELETE_FLAG) { + localAssetInfo.clear(); + } + errCode = E_OK; + } + return errCode; +} + TaskId CloudSyncer::GetNextTaskId() { std::lock_guard autoLock(dataLock_); @@ -1855,6 +1873,8 @@ void CloudSyncer::UnlockIfNeed() void CloudSyncer::ClearCurrentContextWithoutLock() { + heartbeatCount_.erase(currentContext_.currentTaskId); + failedHeartbeatCount_.erase(currentContext_.currentTaskId); currentContext_.currentTaskId = INVALID_TASK_ID; currentContext_.notifier = nullptr; currentContext_.strategy = nullptr; @@ -1867,6 +1887,7 @@ void CloudSyncer::ClearCurrentContextWithoutLock() currentContext_.isDownloadFinished.clear(); currentContext_.currentState = CloudSyncState::IDLE; currentContext_.currentUserIndex = 0; + currentContext_.repeatCount = 0; } void CloudSyncer::ClearContextAndNotify(TaskId taskId, int errCode) @@ -1891,14 +1912,16 @@ void CloudSyncer::ClearContextAndNotify(TaskId taskId, int errCode) if (info.errCode == E_OK) { info.errCode = errCode; } - LOGI("[CloudSyncer] finished taskId %" PRIu64 " errCode %d", taskId, info.errCode); + LOGI("[CloudSyncer] finished storeId %.3s taskId %" PRIu64 " errCode %d", info.storeId.c_str(), taskId, + info.errCode); info.status = ProcessStatus::FINISHED; if (notifier != nullptr) { notifier->NotifyProcess(info, {}, true); } // generate compensated sync - if (!info.priorityTask) { + if (!info.compensatedTask) { CloudTaskInfo taskInfo = CloudSyncUtils::InitCompensatedSyncTaskInfo(); + taskInfo.lockAction = info.lockAction; GenerateCompensatedSync(taskInfo); } } @@ -1947,10 +1970,21 @@ int CloudSyncer::DownloadOneAssetRecord(const std::set &dupHashKeySet, cons if (errorCode == -E_NOT_SET) { return -E_NOT_SET; } + } else { + // share table will not download asset, need to reset the status + for (auto &entry: downloadItem.assets) { + for (auto &asset: entry.second) { + asset.status = AssetStatus::NORMAL; + } + } } if (errorCode != E_OK) { info.downLoadInfo.failCount += 1; - info.downLoadInfo.successCount -= 1; + if (info.downLoadInfo.successCount == 0) { + LOGW("[CloudSyncer] Invalid successCount"); + } else { + info.downLoadInfo.successCount -= 1; + } } if (dupHashKeySet.find(downloadItem.hashKey) == dupHashKeySet.end()) { changedAssets.primaryData[CloudSyncUtils::OpTypeToChangeType(downloadItem.strategy)].push_back( @@ -2045,6 +2079,8 @@ int CloudSyncer::DownloadDataFromCloud(TaskId taskId, SyncParam ¶m, bool &ab if (ret == E_OK || isFirstDownload) { LOGD("[CloudSyncer] try to query cloud data use increment water mark"); UpdateCloudWaterMark(taskId, param); + // Cloud water may change on the cloud, it needs to be saved here + SaveCloudWaterMark(param.tableName, taskId); } if (isFirstDownload) { NotifyInEmptyDownload(taskId, param.info); @@ -2088,6 +2124,12 @@ uint32_t CloudSyncer::GetCurrentTableUploadBatchIndex() return currentContext_.notifier->GetUploadBatchIndex(currentContext_.tableName); } +void CloudSyncer::ResetCurrentTableUploadBatchIndex() +{ + std::lock_guard autoLock(dataLock_); + currentContext_.notifier->ResetUploadBatchIndex(currentContext_.tableName); +} + void CloudSyncer::RecordWaterMark(TaskId taskId, Timestamp waterMark) { std::lock_guard autoLock(dataLock_); @@ -2113,4 +2155,29 @@ void CloudSyncer::SetGenCloudVersionCallback(const GenerateCloudVersionCallback { cloudDB_.SetGenCloudVersionCallback(callback); } + +std::vector CloudSyncer::CopyAndClearTaskInfos() +{ + std::vector infoList; + std::lock_guard autoLock(dataLock_); + for (const auto &item: cloudTaskInfos_) { + infoList.push_back(item.second); + } + taskQueue_.clear(); + priorityTaskQueue_.clear(); + cloudTaskInfos_.clear(); + resumeTaskInfos_.clear(); + currentContext_.notifier = nullptr; + return infoList; +} + +void CloudSyncer::WaitCurTaskFinished() +{ + LOGD("[CloudSyncer] begin wait current task finished"); + std::unique_lock uniqueLock(dataLock_); + contextCv_.wait(uniqueLock, [this]() { + return currentContext_.currentTaskId == INVALID_TASK_ID; + }); + LOGD("[CloudSyncer] current task has been finished"); +} } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer.h b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer.h index e92c91d1..b73c70bf 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_syncer.h @@ -20,13 +20,13 @@ #include #include +#include "cloud/cloud_db_proxy.h" #include "cloud/cloud_store_types.h" #include "cloud/cloud_sync_state_machine.h" #include "cloud/cloud_sync_strategy.h" #include "cloud/icloud_db.h" #include "cloud/icloud_syncer.h" #include "cloud/process_notifier.h" -#include "cloud_db_proxy.h" #include "cloud_locker.h" #include "data_transformer.h" #include "db_common.h" @@ -63,6 +63,8 @@ public: void Close(); + void StopAllTasks(); + std::string GetIdentify() const override; bool IsClosed() const override; @@ -71,6 +73,8 @@ public: int SetCloudDB(const std::map> &cloudDBs); + const std::map> GetCloudDB() const; + void CleanAllWaterMark(); CloudSyncEvent SyncMachineDoDownload(); @@ -91,14 +95,16 @@ protected: DownloadList assetDownloadList; // store GID and assets, using in upload procedure std::map>> assetsInfo; - std::map cloudWaterMarks; + // struct: > + std::map> cloudWaterMarks; std::shared_ptr locker; bool isNeedUpload = false; // whether the current task need do upload CloudSyncState currentState = CloudSyncState::IDLE; bool isRealNeedUpload = false; bool isFirstDownload = false; - std::map isDownloadFinished; + std::map> isDownloadFinished; // struct: > int currentUserIndex = 0; + int repeatCount = 0; }; struct UploadParam { int64_t count = 0; @@ -140,10 +146,10 @@ protected: int DoUploadInNeed(const CloudTaskInfo &taskInfo, const bool needUpload); - void DoNotifyInNeed(CloudSyncer::TaskId taskId, const std::vector &needNotifyTables, + void DoNotifyInNeed(const CloudSyncer::TaskId &taskId, const std::vector &needNotifyTables, const bool isFirstDownload); - int GetUploadCountByTable(CloudSyncer::TaskId taskId, int64_t &count); + int GetUploadCountByTable(const CloudSyncer::TaskId &taskId, int64_t &count); void UpdateProcessInfoWithoutUpload(CloudSyncer::TaskId taskId, const std::string &tableName, bool needNotify); @@ -175,7 +181,7 @@ protected: void SetUploadDataFlag(const TaskId taskId, CloudSyncData& uploadData); - bool IsModeForcePush(const TaskId taskId); + bool IsModeForcePush(TaskId taskId); bool IsModeForcePull(const TaskId taskId); @@ -210,8 +216,6 @@ protected: void FinishHeartBeatTimer(); - void WaitAllHeartBeatTaskExit(); - void HeartBeat(TimerId timerId, TaskId taskId); void HeartBeatFailed(TaskId taskId, int errCode); @@ -221,7 +225,7 @@ protected: int SaveDatum(SyncParam ¶m, size_t idx, std::vector> &deletedList, std::map &localLogInfoCache); - int SaveData(SyncParam ¶m); + int SaveData(CloudSyncer::TaskId taskId, SyncParam ¶m); void NotifyInDownload(CloudSyncer::TaskId taskId, SyncParam ¶m, bool isFirstDownload); @@ -323,13 +327,15 @@ protected: uint32_t GetCurrentTableUploadBatchIndex(); + void ResetCurrentTableUploadBatchIndex(); + void RecordWaterMark(TaskId taskId, Timestamp waterMark); Timestamp GetResumeWaterMark(TaskId taskId); void ReloadWaterMarkIfNeed(TaskId taskId, WaterMark &waterMark); - void ReloadCloudWaterMarkIfNeed(const std::string tableName, std::string &cloudWaterMark); + void ReloadCloudWaterMarkIfNeed(const std::string &tableName, std::string &cloudWaterMark); void ReloadUploadInfoIfNeed(TaskId taskId, const UploadParam ¶m, InnerProcessInfo &info); @@ -353,6 +359,9 @@ protected: std::pair GetDBAssets(bool isSharedTable, const InnerProcessInfo &info, const DownloadItem &downloadItem, VBucket &dbAssets); + std::map BackFillAssetsAfterDownload(std::map tmpAssets, + std::map> tmpFlags, int downloadCode); + int DownloadAssetsOneByOneInner(bool isSharedTable, const InnerProcessInfo &info, DownloadItem &downloadItem, std::map &downloadAssets); @@ -371,18 +380,13 @@ protected: void SetProxyUser(const std::string &user); - std::pair GetLocalWater(const std::string &tableName, UploadParam &uploadParam); - - int HandleBatchUpload(UploadParam &uploadParam, InnerProcessInfo &info, CloudSyncData &uploadData, - ContinueToken &continueStmtToken); - - bool IsNeedLock(const UploadParam ¶m); - bool MergeTaskInfo(const std::shared_ptr &cloudSchema, TaskId taskId); std::pair TryMergeTask(const std::shared_ptr &cloudSchema, TaskId tryTaskId); - bool IsTaskCantMerge(TaskId taskId, TaskId tryTaskId); + bool IsTaskCanMerge(const CloudTaskInfo &taskInfo); + + bool IsTasksCanMerge(TaskId taskId, TaskId tryMergeTaskId); bool MergeTaskTablesIfConsistent(TaskId sourceId, TaskId targetId); @@ -392,7 +396,27 @@ protected: bool IsQueryListEmpty(TaskId taskId); + std::pair GetLocalWater(const std::string &tableName, UploadParam &uploadParam); + + int HandleBatchUpload(UploadParam &uploadParam, InnerProcessInfo &info, CloudSyncData &uploadData, + ContinueToken &continueStmtToken); + + bool IsNeedLock(const UploadParam ¶m); + int UploadVersionRecordIfNeed(const UploadParam &uploadParam); + + std::vector CopyAndClearTaskInfos(); + + void WaitCurTaskFinished(); + + bool IsLockInDownload(); + + CloudSyncEvent SetCurrentTaskFailedInMachine(int errCode); + + CloudSyncEvent SyncMachineDoRepeatCheck(); + + void MarkDownloadFinishIfNeed(const std::string &downloadTable); + std::mutex dataLock_; TaskId lastTaskId_; std::list taskQueue_; @@ -414,8 +438,8 @@ protected: std::atomic timerId_; std::mutex heartbeatMutex_; std::condition_variable heartbeatCv_; - int32_t heartBeatCount_; - std::atomic failedHeartBeatCount_; + std::map heartbeatCount_; + std::map failedHeartbeatCount_; std::string id_; std::atomic policy_; 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 9d9d683f..166a7376 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 @@ -39,10 +39,10 @@ void CloudSyncer::ReloadWaterMarkIfNeed(TaskId taskId, WaterMark &waterMark) RecordWaterMark(taskId, 0u); } -void CloudSyncer::ReloadCloudWaterMarkIfNeed(const std::string tableName, std::string &cloudWaterMark) +void CloudSyncer::ReloadCloudWaterMarkIfNeed(const std::string &tableName, std::string &cloudWaterMark) { std::lock_guard autoLock(dataLock_); - std::string cacheCloudWaterMark = currentContext_.cloudWaterMarks[tableName]; + std::string cacheCloudWaterMark = currentContext_.cloudWaterMarks[currentContext_.currentUserIndex][tableName]; cloudWaterMark = cacheCloudWaterMark.empty() ? cloudWaterMark : cacheCloudWaterMark; } @@ -110,6 +110,7 @@ int CloudSyncer::GetCloudGid(TaskId taskId, const std::string &tableName, QueryS } else if (!cloudGid.empty()) { obj.SetCloudGid(cloudGid); } + LOGI("[CloudSyncer] get cloud gid size:%zu", cloudGid.size()); return errCode; } @@ -131,6 +132,7 @@ void CloudSyncer::NotifyUploadFailed(int errCode, InnerProcessInfo &info) { if (errCode == -E_CLOUD_VERSION_CONFLICT) { LOGI("[CloudSyncer] Stop upload due to version conflict, %d", errCode); + return; } else { LOGE("[CloudSyncer] Failed to do upload, %d", errCode); } @@ -261,16 +263,34 @@ std::pair CloudSyncer::GetDBAssets(bool isSharedTable, const Inne return res; } +std::map CloudSyncer::BackFillAssetsAfterDownload(std::map tmpAssets, + std::map> tmpFlags, int downloadCode) +{ + for (auto &[col, assets] : tmpAssets) { + int i = 0; + for (auto &asset : assets) { + asset.flag = tmpFlags[col][i++]; + if (asset.flag == static_cast(AssetOpType::NO_CHANGE)) { + continue; + } + if (downloadCode == E_OK) { + asset.status = NORMAL; + } else { + asset.status = (asset.status == NORMAL) ? NORMAL : ABNORMAL; + } + } + } + return tmpAssets; +} + int CloudSyncer::DownloadAssetsOneByOneInner(bool isSharedTable, const InnerProcessInfo &info, DownloadItem &downloadItem, std::map &downloadAssets) { int errCode = E_OK; + std::map tmpAssets; + std::map> tmpFlags; for (auto &[col, assets] : downloadAssets) { - Assets callDownloadAssets; for (auto &asset : assets) { - std::map tmpAssets; - tmpAssets[col] = { asset }; - uint32_t tmpFlag = asset.flag; VBucket dbAssets; auto [tmpCode, status] = GetDBAssets(isSharedTable, info, downloadItem, dbAssets); if (tmpCode == -E_CLOUD_GID_MISMATCH) { @@ -289,28 +309,26 @@ int CloudSyncer::DownloadAssetsOneByOneInner(bool isSharedTable, const InnerProc } if (!isSharedTable && AssetOperationUtils::CalAssetOperation(col, asset, dbAssets, AssetOperationUtils::CloudSyncAction::START_DOWNLOAD) == AssetOperationUtils::AssetOpType::HANDLE) { - tmpCode = cloudDB_.Download(info.tableName, downloadItem.gid, downloadItem.prefix, tmpAssets); + tmpAssets[col].push_back(asset); + tmpFlags[col].push_back(asset.flag); } else { 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; - } - asset = tmpAssets[col][0]; // copy asset back - asset.flag = tmpFlag; - if (asset.flag != static_cast(AssetOpType::NO_CHANGE)) { - asset.status = (tmpCode == E_OK) ? NORMAL : ABNORMAL; - } - callDownloadAssets.push_back(asset); } - assets = callDownloadAssets; } + auto downloadCode = cloudDB_.Download(info.tableName, downloadItem.gid, downloadItem.prefix, tmpAssets); + if (downloadCode == -E_CLOUD_RECORD_EXIST_CONFLICT) { + downloadItem.recordConflict = true; + return E_OK; + } + errCode = (errCode != E_OK) ? errCode : downloadCode; + if (downloadCode == -E_NOT_SET) { + return errCode; + } + + // copy asset back + downloadAssets = BackFillAssetsAfterDownload(tmpAssets, tmpFlags, downloadCode); return errCode; } @@ -334,9 +352,11 @@ int CloudSyncer::CommitDownloadAssets(const DownloadItem &downloadItem, const st for (auto &[key, asset] : assetsMap) { assets[key] = std::move(asset); } - errCode = FillCloudAssets(tableName, normalAssets, failedAssets); - if (errCode != E_OK) { - break; + if (!downloadItem.recordConflict) { + errCode = FillCloudAssets(tableName, normalAssets, failedAssets); + if (errCode != E_OK) { + break; + } } LogInfo logInfo; logInfo.cloudGid = gid; @@ -371,13 +391,12 @@ void CloudSyncer::GenerateCompensatedSync(CloudTaskInfo &taskInfo) LOGD("[CloudSyncer] Not need generate compensated sync"); return; } - taskInfo.users.push_back(""); for (const auto &query : syncQuery) { taskInfo.table.push_back(query.GetRelationTableName()); taskInfo.queryList.push_back(query); } Sync(taskInfo); - LOGD("[CloudSyncer] Generate compensated sync finished"); + LOGI("[CloudSyncer] Generate compensated sync finished"); } void CloudSyncer::ChkIgnoredProcess(InnerProcessInfo &info, const CloudSyncData &uploadData, UploadParam &uploadParam) @@ -428,7 +447,6 @@ int CloudSyncer::PrepareAndDownload(const std::string &table, const CloudTaskInf { int errCode = SaveCursorIfNeed(table); if (errCode != E_OK) { - LOGE("[CloudSyncer] save cursor failed %d", errCode); return errCode; } bool isShared = false; @@ -451,39 +469,6 @@ int CloudSyncer::PrepareAndDownload(const std::string &table, const CloudTaskInf return errCode; } -int CloudSyncer::GetLocalInfo(size_t index, SyncParam ¶m, DataInfoWithLog &logInfo, - std::map &localLogInfoCache, VBucket &localAssetInfo) -{ - int errCode = storageProxy_->GetInfoByPrimaryKeyOrGid(param.tableName, param.downloadData.data[index], - logInfo, localAssetInfo); - if (errCode != E_OK && errCode != -E_NOT_FOUND) { - return errCode; - } - std::string hashKey(logInfo.logInfo.hashKey.begin(), logInfo.logInfo.hashKey.end()); - if (hashKey.empty()) { - return errCode; - } - param.downloadData.existDataKey[index] = logInfo.logInfo.dataKey; - param.downloadData.existDataHashKey[index] = logInfo.logInfo.hashKey; - if (localLogInfoCache.find(hashKey) != localLogInfoCache.end()) { - LOGD("[CloudSyncer] exist same record in one batch, override from cache record! hash=%.3s", - DBCommon::TransferStringToHex(hashKey).c_str()); - logInfo.logInfo.flag = localLogInfoCache[hashKey].flag; - logInfo.logInfo.wTimestamp = localLogInfoCache[hashKey].wTimestamp; - logInfo.logInfo.timestamp = localLogInfoCache[hashKey].timestamp; - logInfo.logInfo.cloudGid = localLogInfoCache[hashKey].cloudGid; - logInfo.logInfo.device = localLogInfoCache[hashKey].device; - logInfo.logInfo.sharingResource = localLogInfoCache[hashKey].sharingResource; - logInfo.logInfo.status = localLogInfoCache[hashKey].status; - // delete record should remove local asset info - if ((localLogInfoCache[hashKey].flag & DataItem::DELETE_FLAG) == DataItem::DELETE_FLAG) { - localAssetInfo.clear(); - } - errCode = E_OK; - } - return errCode; -} - bool CloudSyncer::IsClosed() const { return closed_ || IsKilled(); @@ -546,7 +531,7 @@ void CloudSyncer::GetDownloadItem(const DownloadList &downloadList, size_t i, Do downloadItem.timestamp = std::get(downloadList[i]); } -void CloudSyncer::DoNotifyInNeed(CloudSyncer::TaskId taskId, const std::vector &needNotifyTables, +void CloudSyncer::DoNotifyInNeed(const CloudSyncer::TaskId &taskId, const std::vector &needNotifyTables, const bool isFirstDownload) { bool isNeedNotify = false; @@ -564,7 +549,7 @@ void CloudSyncer::DoNotifyInNeed(CloudSyncer::TaskId taskId, const std::vectorGetLocalWaterMark(tableName, localMark); - if (ret != E_OK) { - LOGE("[CloudSyncer] Failed to get local water mark when upload, %d.", ret); - return ret; - } - } - ReloadWaterMarkIfNeed(taskId, localMark); ret = storageProxy_->StartTransaction(); if (ret != E_OK) { @@ -588,8 +564,8 @@ int CloudSyncer::GetUploadCountByTable(CloudSyncer::TaskId taskId, int64_t &coun return ret; } - ret = storageProxy_->GetUploadCount(GetQuerySyncObject(tableName), localMark, IsModeForcePush(taskId), - IsCompensatedTask(taskId), count); + ret = storageProxy_->GetUploadCount(GetQuerySyncObject(tableName), IsModeForcePush(taskId), + IsCompensatedTask(taskId), IsNeedGetLocalWater(taskId), count); if (ret != E_OK) { // GetUploadCount will return E_OK when upload count is zero. LOGE("[CloudSyncer] Failed to get Upload Data Count, %d.", ret); @@ -621,13 +597,13 @@ int CloudSyncer::DoDownloadInNeed(const CloudTaskInfo &taskInfo, const bool need { std::vector needNotifyTables; for (size_t i = 0; i < taskInfo.table.size(); ++i) { - if (currentContext_.isDownloadFinished[taskInfo.table[i]] == true) { - continue; - } - LOGD("[CloudSyncer] try download table, index: %zu", i); std::string table; { std::lock_guard autoLock(dataLock_); + if (currentContext_.isDownloadFinished[currentContext_.currentUserIndex][taskInfo.table[i]] == true) { + continue; + } + LOGD("[CloudSyncer] try download table, index: %zu", i); currentContext_.tableName = taskInfo.table[i]; table = currentContext_.tableName; } @@ -635,6 +611,7 @@ int CloudSyncer::DoDownloadInNeed(const CloudTaskInfo &taskInfo, const bool need if (errCode != E_OK) { return errCode; } + MarkDownloadFinishIfNeed(table); // needUpload indicate that the syncMode need push if (needUpload) { int64_t count = 0; @@ -658,10 +635,6 @@ int CloudSyncer::DoDownloadInNeed(const CloudTaskInfo &taskInfo, const bool need LOGE("[CloudSyncer] Can not save cloud water mark after downloading %d", errCode); return errCode; } - { - std::lock_guard autoLock(dataLock_); - currentContext_.isDownloadFinished[taskInfo.table[i]] = true; - } } DoNotifyInNeed(taskInfo.taskId, needNotifyTables, isFirstDownload); return E_OK; @@ -669,65 +642,8 @@ int CloudSyncer::DoDownloadInNeed(const CloudTaskInfo &taskInfo, const bool need bool CloudSyncer::IsNeedGetLocalWater(TaskId taskId) { - return !IsModeForcePush(taskId) && !IsPriorityTask(taskId) && !IsCompensatedTask(taskId); -} - -bool CloudSyncer::IsNeedLock(const UploadParam ¶m) -{ - return param.lockAction == LockAction::INSERT && param.mode == CloudWaterType::INSERT; -} - -std::pair CloudSyncer::GetLocalWater(const std::string &tableName, UploadParam &uploadParam) -{ - std::pair res = { E_OK, 0u }; - if (IsNeedGetLocalWater(uploadParam.taskId)) { - res.first = storageProxy_->GetLocalWaterMarkByMode(tableName, res.second, uploadParam.mode); - } - uploadParam.localMark = res.second; - return res; -} - -int CloudSyncer::HandleBatchUpload(UploadParam &uploadParam, InnerProcessInfo &info, - CloudSyncData &uploadData, ContinueToken &continueStmtToken) -{ - int ret = E_OK; - uint32_t batchIndex = GetCurrentTableUploadBatchIndex(); - bool isLocked = false; - while (!CloudSyncUtils::CheckCloudSyncDataEmpty(uploadData)) { - ret = PreProcessBatchUpload(uploadParam, info, uploadData); - if (ret != E_OK) { - break; - } - if (IsNeedLock(uploadParam) && !isLocked) { - ret = LockCloudIfNeed(uploadParam.taskId); - if (ret != E_OK) { - break; - } - isLocked = true; - } - info.upLoadInfo.batchIndex = ++batchIndex; - ret = DoBatchUpload(uploadData, uploadParam, info); - if (ret != E_OK) { - NotifyUploadFailed(ret, info); - break; - } - uploadData = CloudSyncData(uploadData.tableName, uploadParam.mode); - if (continueStmtToken == nullptr) { - break; - } - SetUploadDataFlag(uploadParam.taskId, uploadData); - RecordWaterMark(uploadParam.taskId, uploadParam.localMark); - ret = storageProxy_->GetCloudDataNext(continueStmtToken, uploadData); - if ((ret != E_OK) && (ret != -E_UNFINISHED)) { - LOGE("[CloudSyncer] Failed to get cloud data next when doing upload, %d.", ret); - break; - } - ChkIgnoredProcess(info, uploadData, uploadParam); - } - if (isLocked && IsNeedLock(uploadParam)) { - UnlockIfNeed(); - } - return ret; + return !IsModeForcePush(taskId) && (!IsPriorityTask(taskId) || IsQueryListEmpty(taskId)) && + !IsCompensatedTask(taskId); } int CloudSyncer::TryToAddSyncTask(CloudTaskInfo &&taskInfo) @@ -758,7 +674,8 @@ int CloudSyncer::TryToAddSyncTask(CloudTaskInfo &&taskInfo) } else { if (!MergeTaskInfo(cloudSchema, lastTaskId_)) { taskQueue_.push_back(lastTaskId_); - LOGI("[CloudSyncer] Add task ok, taskId %" PRIu64, cloudTaskInfos_[lastTaskId_].taskId); + LOGI("[CloudSyncer] Add task ok, storeId %.3s, taskId %" PRIu64, + cloudTaskInfos_[lastTaskId_].storeId.c_str(), cloudTaskInfos_[lastTaskId_].taskId); } } return E_OK; @@ -774,7 +691,7 @@ bool CloudSyncer::MergeTaskInfo(const std::shared_ptr &cloudSche TaskId checkTaskId = taskId; do { std::tie(isMerge, checkTaskId) = TryMergeTask(cloudSchema, checkTaskId); - mergeHappen |= isMerge; + mergeHappen = mergeHappen || isMerge; } while (isMerge); return mergeHappen; } @@ -789,7 +706,7 @@ std::pair CloudSyncer::TryMergeTask(const std::shared_ptr CloudSyncer::TryMergeTask(const std::shared_ptr(this); - processNotifier->Init(cloudTaskInfos_[beMergeTask].table, cloudTaskInfos_[beMergeTask].devices); + processNotifier->Init(cloudTaskInfos_[beMergeTask].table, cloudTaskInfos_[beMergeTask].devices, + cloudTaskInfos_[beMergeTask].users); cloudTaskInfos_[beMergeTask].errCode = -E_CLOUD_SYNC_TASK_MERGED; cloudTaskInfos_[beMergeTask].status = ProcessStatus::FINISHED; + processNotifier->SetAllTableFinish(); processNotifier->NotifyProcess(cloudTaskInfos_[beMergeTask], {}, true); cloudTaskInfos_.erase(beMergeTask); taskQueue_.remove(beMergeTask); @@ -823,14 +742,18 @@ std::pair CloudSyncer::TryMergeTask(const std::shared_ptr } } -std::pair CloudSyncer::SwapTwoTaskAndCopyTable(TaskId target, TaskId source) +std::pair CloudSyncer::SwapTwoTaskAndCopyTable(TaskId source, TaskId target) { - cloudTaskInfos_[target].table = cloudTaskInfos_[source].table; - cloudTaskInfos_[target].queryList = cloudTaskInfos_[source].queryList; - return {source, target}; + cloudTaskInfos_[source].table = cloudTaskInfos_[target].table; + cloudTaskInfos_[source].queryList = cloudTaskInfos_[target].queryList; + return {target, source}; } bool CloudSyncer::IsQueryListEmpty(TaskId taskId) { std::lock_guard autoLock(dataLock_); - for (const auto &item : cloudTaskInfos_[taskId].queryList) { - if (item.IsContainQueryNodes()) { - return false; + return !std::any_of(cloudTaskInfos_[taskId].queryList.begin(), cloudTaskInfos_[taskId].queryList.end(), + [](const auto &item) { + return item.IsContainQueryNodes(); + }); +} + +bool CloudSyncer::IsNeedLock(const UploadParam ¶m) +{ + return param.lockAction == LockAction::INSERT && param.mode == CloudWaterType::INSERT; +} + +std::pair CloudSyncer::GetLocalWater(const std::string &tableName, UploadParam &uploadParam) +{ + std::pair res = { E_OK, 0u }; + if (IsNeedGetLocalWater(uploadParam.taskId)) { + res.first = storageProxy_->GetLocalWaterMarkByMode(tableName, res.second, uploadParam.mode); + } + uploadParam.localMark = res.second; + return res; +} + +int CloudSyncer::HandleBatchUpload(UploadParam &uploadParam, InnerProcessInfo &info, + CloudSyncData &uploadData, ContinueToken &continueStmtToken) +{ + int ret = E_OK; + uint32_t batchIndex = GetCurrentTableUploadBatchIndex(); + bool isLocked = false; + while (!CloudSyncUtils::CheckCloudSyncDataEmpty(uploadData)) { + ret = PreProcessBatchUpload(uploadParam, info, uploadData); + if (ret != E_OK) { + break; + } + if (IsNeedLock(uploadParam) && !isLocked) { + ret = LockCloudIfNeed(uploadParam.taskId); + if (ret != E_OK) { + break; + } + isLocked = true; + } + info.upLoadInfo.batchIndex = ++batchIndex; + ret = DoBatchUpload(uploadData, uploadParam, info); + if (ret != E_OK) { + NotifyUploadFailed(ret, info); + break; + } + uploadData = CloudSyncData(uploadData.tableName, uploadParam.mode); + if (continueStmtToken == nullptr) { + break; + } + SetUploadDataFlag(uploadParam.taskId, uploadData); + RecordWaterMark(uploadParam.taskId, uploadParam.localMark); + ret = storageProxy_->GetCloudDataNext(continueStmtToken, uploadData); + if ((ret != E_OK) && (ret != -E_UNFINISHED)) { + LOGE("[CloudSyncer] Failed to get cloud data next when doing upload, %d.", ret); + break; } + ChkIgnoredProcess(info, uploadData, uploadParam); } - return true; + if (isLocked && IsNeedLock(uploadParam)) { + UnlockIfNeed(); + } + return ret; } int CloudSyncer::DoUploadInner(const std::string &tableName, UploadParam &uploadParam) { InnerProcessInfo info = GetInnerProcessInfo(tableName, uploadParam); - static std::vector waterTypes = { - CloudWaterType::DELETE, CloudWaterType::UPDATE, CloudWaterType::INSERT - }; + static std::vector waterTypes = DBCommon::GetWaterTypeVec(); for (const auto &waterType: waterTypes) { uploadParam.mode = waterType; int errCode = DoUploadByMode(tableName, uploadParam, info); @@ -931,11 +908,98 @@ int CloudSyncer::UploadVersionRecordIfNeed(const UploadParam &uploadParam) WaterMark waterMark; CloudSyncUtils::GetWaterMarkAndUpdateTime(batchData.extend, waterMark); errCode = isInsert ? BatchInsert(info, uploadData, processInfo) : BatchUpdate(info, uploadData, processInfo); - if (errCode != E_OK) { - return errCode; - } batchData.record = copyRecord; CloudSyncUtils::ModifyCloudDataTime(batchData.extend[0]); - return storageProxy_->FillCloudLogAndAsset(isInsert ? OpType::INSERT : OpType::UPDATE, uploadData); + auto ret = storageProxy_->FillCloudLogAndAsset(isInsert ? OpType::INSERT : OpType::UPDATE, uploadData); + return errCode != E_OK ? errCode : ret; +} + +int CloudSyncer::TagUploadAssets(CloudSyncData &uploadData) +{ + if (!IsDataContainAssets()) { + return E_OK; + } + std::vector assetFields; + { + std::lock_guard autoLock(dataLock_); + assetFields = currentContext_.assetFields[currentContext_.tableName]; + } + + for (size_t i = 0; i < uploadData.insData.extend.size(); i++) { + for (const Field &assetField : assetFields) { + (void)TagAssetsInSingleCol(assetField, uploadData.insData.record[i], true); + } + } + for (size_t i = 0; i < uploadData.updData.extend.size(); i++) { + for (const Field &assetField : assetFields) { + (void)TagAssetsInSingleCol(assetField, uploadData.updData.record[i], false); + } + } + return E_OK; +} + +bool CloudSyncer::IsLockInDownload() +{ + std::lock_guard autoLock(dataLock_); + if (cloudTaskInfos_.find(currentContext_.currentTaskId) == cloudTaskInfos_.end()) { + return false; + } + auto currentLockAction = static_cast(cloudTaskInfos_[currentContext_.currentTaskId].lockAction); + return (currentLockAction & static_cast(LockAction::DOWNLOAD)) != 0; +} + +CloudSyncEvent CloudSyncer::SetCurrentTaskFailedInMachine(int errCode) +{ + std::lock_guard autoLock(dataLock_); + cloudTaskInfos_[currentContext_.currentTaskId].errCode = errCode; + return CloudSyncEvent::ERROR_EVENT; +} + +void CloudSyncer::InitCloudSyncStateMachine() +{ + CloudSyncStateMachine::Initialize(); + cloudSyncStateMachine_.RegisterFunc(CloudSyncState::DO_DOWNLOAD, [this]() { + return SyncMachineDoDownload(); + }); + cloudSyncStateMachine_.RegisterFunc(CloudSyncState::DO_UPLOAD, [this]() { + return SyncMachineDoUpload(); + }); + cloudSyncStateMachine_.RegisterFunc(CloudSyncState::DO_FINISHED, [this]() { + return SyncMachineDoFinished(); + }); + cloudSyncStateMachine_.RegisterFunc(CloudSyncState::DO_REPEAT_CHECK, [this]() { + return SyncMachineDoRepeatCheck(); + }); +} + +CloudSyncEvent CloudSyncer::SyncMachineDoRepeatCheck() +{ + auto config = storageProxy_->GetCloudSyncConfig(); + { + std::lock_guard autoLock(dataLock_); + if (config.maxRetryConflictTimes < 0) { // unlimited repeat counts + return CloudSyncEvent::REPEAT_DOWNLOAD_EVENT; + } + currentContext_.repeatCount++; + if (currentContext_.repeatCount > config.maxRetryConflictTimes) { + LOGD("[CloudSyncer] Repeat too much times current %d limit %" PRId32, currentContext_.repeatCount, + config.maxRetryConflictTimes); + SetCurrentTaskFailedWithoutLock(-E_CLOUD_VERSION_CONFLICT); + return CloudSyncEvent::ERROR_EVENT; + } + LOGD("[CloudSyncer] Repeat taskId %" PRIu64 " download current %d", currentContext_.currentTaskId, + currentContext_.repeatCount); + } + return CloudSyncEvent::REPEAT_DOWNLOAD_EVENT; +} + +void CloudSyncer::MarkDownloadFinishIfNeed(const std::string &downloadTable) +{ + // table exist reference should download every times + if (IsLockInDownload() || storageProxy_->IsTableExistReference(downloadTable)) { + return; + } + std::lock_guard autoLock(dataLock_); + currentContext_.isDownloadFinished[currentContext_.currentUserIndex][downloadTable] = true; } } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/icloud_syncer.h b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/icloud_syncer.h index 95f14dd7..5228b3a2 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/icloud_syncer.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/icloud_syncer.h @@ -43,6 +43,7 @@ public: std::vector users; LockAction lockAction = LockAction::INSERT; bool merge = false; + std::string storeId; }; struct InnerProcessInfo { diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/process_notifier.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/process_notifier.cpp index 3648f1b7..dad693a1 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/process_notifier.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/process_notifier.cpp @@ -30,20 +30,29 @@ ProcessNotifier::~ProcessNotifier() } void ProcessNotifier::Init(const std::vector &tableName, - const std::vector &devices) + const std::vector &devices, const std::vector &users) { std::lock_guard autoLock(processMutex_); - syncProcess_.errCode = OK; - syncProcess_.process = ProcessStatus::PROCESSING; - for (const auto &table: tableName) { - TableProcessInfo tableInfo = { - .process = ProcessStatus::PREPARED - }; - syncProcess_.tableProcess[table] = tableInfo; + InitSyncProcess(tableName, syncProcess_); + for (const auto &user : users) { + SyncProcess syncProcess; + InitSyncProcess(tableName, syncProcess); + multiSyncProcess_[user] = syncProcess; } devices_ = devices; } +void ProcessNotifier::InitSyncProcess(const std::vector &tableName, SyncProcess &syncProcess) +{ + syncProcess.errCode = OK; + syncProcess.process = ProcessStatus::PROCESSING; + for (const auto &table: tableName) { + TableProcessInfo tableInfo; + tableInfo.process = ProcessStatus::PREPARED; + syncProcess.tableProcess[table] = tableInfo; + } +} + void ProcessNotifier::UpdateProcess(const ICloudSyncer::InnerProcessInfo &process) { if (process.tableName.empty()) { @@ -136,6 +145,16 @@ uint32_t ProcessNotifier::GetUploadBatchIndex(const std::string &tableName) cons return syncProcess_.tableProcess.at(tableName).upLoadInfo.batchIndex; } +void ProcessNotifier::ResetUploadBatchIndex(const std::string &tableName) +{ + std::lock_guard autoLock(processMutex_); + if (syncProcess_.tableProcess.find(tableName) == syncProcess_.tableProcess.end()) { + LOGW("[ProcessNotifier] The specified table was not found when reset UploadBatchIndex"); + return; + } + syncProcess_.tableProcess[tableName].upLoadInfo.batchIndex = 0; +} + uint32_t ProcessNotifier::GetLastUploadSuccessCount(const std::string &tableName) const { std::lock_guard autoLock(processMutex_); @@ -151,8 +170,15 @@ void ProcessNotifier::GetDownloadInfoByTableName(ICloudSyncer::InnerProcessInfo return; } std::lock_guard autoLock(processMutex_); - if (syncProcess_.tableProcess.find(process.tableName) == syncProcess_.tableProcess.end()) { - process.downLoadInfo = syncProcess_.tableProcess[process.tableName].downLoadInfo; + SyncProcess syncProcess; + if (user_.empty()) { + syncProcess = syncProcess_; + } else { + syncProcess = multiSyncProcess_[user_]; + } + + if (syncProcess.tableProcess.find(process.tableName) == syncProcess.tableProcess.end()) { + process.downLoadInfo = syncProcess.tableProcess[process.tableName].downLoadInfo; } } @@ -160,4 +186,17 @@ void ProcessNotifier::SetUser(const std::string &user) { user_ = user; } + +void ProcessNotifier::SetAllTableFinish() +{ + std::lock_guard autoLock(processMutex_); + for (auto &item : syncProcess_.tableProcess) { + item.second.process = ProcessStatus::FINISHED; + } + for (auto &syncProcess : multiSyncProcess_) { + for (auto &item : syncProcess.second.tableProcess) { + item.second.process = ProcessStatus::FINISHED; + } + } +} } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/process_notifier.h b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/process_notifier.h index 190dca12..8416c378 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/process_notifier.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/process_notifier.h @@ -22,7 +22,8 @@ public: explicit ProcessNotifier(ICloudSyncer *syncer); ~ProcessNotifier(); - void Init(const std::vector &tableName, const std::vector &devices); + void Init(const std::vector &tableName, const std::vector &devices, + const std::vector &users); void UpdateProcess(const ICloudSyncer::InnerProcessInfo &process); @@ -33,11 +34,15 @@ public: uint32_t GetUploadBatchIndex(const std::string &tableName) const; + void ResetUploadBatchIndex(const std::string &tableName); + uint32_t GetLastUploadSuccessCount(const std::string &tableName) const; void GetDownloadInfoByTableName(ICloudSyncer::InnerProcessInfo &process); void SetUser(const std::string &user); + + void SetAllTableFinish(); protected: mutable std::mutex processMutex_; SyncProcess syncProcess_; @@ -45,6 +50,8 @@ protected: std::vector devices_; ICloudSyncer *syncer_; std::string user_; +private: + void InitSyncProcess(const std::vector &tableName, SyncProcess &syncProcess); }; } #endif // PROCESS_NOTIFIER_H diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device/ability_sync.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/device/ability_sync.cpp index 3a9eb303..a540dae8 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device/ability_sync.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device/ability_sync.cpp @@ -530,7 +530,7 @@ bool AbilitySync::SecLabelCheck(const AbilitySyncRequestPacket *packet) const int32_t remoteSecLabel = TransformSecLabelIfNeed(packet->GetSecLabel(), option.securityLabel); LOGI("[AbilitySync][RequestRecv] remote label:%d local l:%d, f:%d, errCode:%d", remoteSecLabel, option.securityLabel, option.securityFlag, errCode); - if (remoteSecLabel == NOT_SURPPORT_SEC_CLASSIFICATION && errCode == -E_NOT_SUPPORT) { + if (remoteSecLabel == NOT_SUPPORT_SEC_CLASSIFICATION && errCode == -E_NOT_SUPPORT) { return true; } uint32_t remoteSoftwareVersion = packet->GetSoftwareVersion(); @@ -542,7 +542,7 @@ bool AbilitySync::SecLabelCheck(const AbilitySyncRequestPacket *packet) const LOGE("[AbilitySync][RequestRecv] remote security label not set!"); return false; } - if (remoteSecLabel == NOT_SURPPORT_SEC_CLASSIFICATION || remoteSecLabel == SecurityLabel::NOT_SET) { + if (remoteSecLabel == NOT_SUPPORT_SEC_CLASSIFICATION || remoteSecLabel == SecurityLabel::NOT_SET) { return true; } if (errCode == -E_NOT_SUPPORT || (errCode == E_OK && option.securityLabel == SecurityLabel::NOT_SET)) { @@ -599,7 +599,7 @@ void AbilitySync::GetPacketSecOption(const ISyncTaskContext *context, SecurityOp (static_cast(storageInterface_))->GetSecurityOption(option); if (errCode == -E_NOT_SUPPORT) { LOGE("[AbilitySync][SyncStart] GetSecOpt not surpport sec classification"); - option.securityLabel = NOT_SURPPORT_SEC_CLASSIFICATION; + option.securityLabel = NOT_SUPPORT_SEC_CLASSIFICATION; } else if (errCode != E_OK) { LOGE("[AbilitySync][SyncStart] GetSecOpt errCode:%d", errCode); option.securityLabel = FAILED_GET_SEC_CLASSIFICATION; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device/ability_sync.h b/kv_store/frameworks/libs/distributeddb/syncer/src/device/ability_sync.h index 21ecfa2b..0e9535ad 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device/ability_sync.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device/ability_sync.h @@ -267,7 +267,6 @@ private: std::shared_ptr metadata_; std::string deviceId_; bool syncFinished_; - static const int FAILED_GET_SEC_CLASSIFICATION = 0x55; }; } // namespace DistributedDB #endif // ABILITY_SYNC_H diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device/generic_syncer.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/device/generic_syncer.cpp index 2613782b..e95aabea 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device/generic_syncer.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device/generic_syncer.cpp @@ -112,7 +112,6 @@ int GenericSyncer::Initialize(ISyncInterface *syncInterface, bool isNeedActive) } if (!RuntimeContext::GetInstance()->IsCommunicatorAggregatorValid()) { - LOGW("[Syncer] Communicator component not ready!"); return -E_NOT_INIT; } @@ -798,6 +797,9 @@ std::string GenericSyncer::GetSyncDevicesStr(const std::vector &dev syncDevices += DBCommon::StringMasking(dev); syncDevices += ","; } + if (syncDevices.empty()) { + return ""; + } return syncDevices.substr(0, syncDevices.size() - 1); } @@ -1192,9 +1194,9 @@ void GenericSyncer::ResetTimeSyncMarkByTimeChange(std::shared_ptr &met void GenericSyncer::ResetSyncStatus() { - std::shared_ptr metadata = nullptr; + std::shared_ptr metadata = nullptr; { - std::lock_guard lock(syncerLock_); + std::lock_guard lock(syncerLock_); if (metadata_ == nullptr) { return; } diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device/meta_data.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/device/meta_data.cpp index 39c3a0cc..693e2bf7 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device/meta_data.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device/meta_data.cpp @@ -273,6 +273,9 @@ void Metadata::PutMetadataToMap(const DeviceID &deviceId, const MetaDataValue &v void Metadata::GetMetadataFromMap(const DeviceID &deviceId, MetaDataValue &outValue) { + if (metadataMap_.find(deviceId) == metadataMap_.end() && RuntimeContext::GetInstance()->IsTimeChanged()) { + metadataMap_[deviceId].syncMark = static_cast(SyncMark::SYNC_MARK_TIME_CHANGE); + } outValue = metadataMap_[deviceId]; } @@ -705,7 +708,7 @@ int Metadata::ClearAllMetaDataValue(uint32_t innerClearAction) } } if (errCode == E_OK) { - LOGI("[Metadata][ClearAllMetaDataValue] success clear action %" PRIu32, innerClearAction); + LOGD("[Metadata][ClearAllMetaDataValue] success clear action %" PRIu32, innerClearAction); } return errCode; } diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device/multiver/multi_ver_sync_state_machine.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/device/multiver/multi_ver_sync_state_machine.cpp index 34cb9a22..51c8b7fa 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device/multiver/multi_ver_sync_state_machine.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device/multiver/multi_ver_sync_state_machine.cpp @@ -425,10 +425,10 @@ int MultiVerSyncStateMachine::ValueSlicePktRecvCallback(MultiVerSyncTaskContext void MultiVerSyncStateMachine::Finish() { MultiVerCommitNode commit; - std::vector commits; int commitsSize = context_->GetCommitsSize(); if (commitsSize > 0) { context_->GetCommit(commitsSize - 1, commit); + std::vector commits; context_->GetCommits(commits); LOGD("MultiVerSyncStateMachine::Finish merge src=%s", STR_MASK(context_->GetDeviceId())); PerformanceAnalysis *performance = PerformanceAnalysis::GetInstance(); @@ -451,8 +451,6 @@ void MultiVerSyncStateMachine::Finish() int MultiVerSyncStateMachine::OneCommitSyncFinish() { MultiVerCommitNode commit; - std::vector entries; - std::string deviceName; TimeOffset outOffset = 0; int errCode = E_OK; int commitIndex = context_->GetCommitIndex(); @@ -461,7 +459,8 @@ int MultiVerSyncStateMachine::OneCommitSyncFinish() commitIndex); if (commitIndex > 0) { context_->GetCommit(commitIndex - 1, commit); - deviceName = context_->GetDeviceId(); + std::string deviceName = context_->GetDeviceId(); + std::vector entries; context_->GetEntries(entries); LOGD("MultiVerSyncStateMachine::OneCommitSyncFinish src=%s, entries size = %lu", STR_MASK(context_->GetDeviceId()), entries.size()); @@ -553,7 +552,7 @@ void MultiVerSyncStateMachine::SyncResponseBegin(uint32_t sessionId) int errCode = RuntimeContext::GetInstance()->SetTimer( RESPONSE_TIME_OUT, timeOutCallback, [this]() { - int ret = RuntimeContext::GetInstance()->ScheduleTask([this](){ RefObject::DecObjRef(context_); }); + int ret = RuntimeContext::GetInstance()->ScheduleTask([this]() { RefObject::DecObjRef(context_); }); if (ret != E_OK) { LOGE("[MultiVerSyncStateMachine][SyncResponseEnd] timer finalizer ScheduleTask, errCode %d", ret); } diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device/multiver/value_slice_sync.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/device/multiver/value_slice_sync.cpp index ad39413f..73b97325 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device/multiver/value_slice_sync.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device/multiver/value_slice_sync.cpp @@ -204,12 +204,12 @@ int ValueSliceSync::SyncStart(MultiVerSyncTaskContext *context) } // move to next entry MultiVerKvEntry *entry = nullptr; - std::vector valueHashes; entriesIndex++; if (entriesIndex < entriesSize) { LOGD("ValueSliceSync::SyncStart begin entriesIndex = %d, entriesSize = %d", entriesIndex, entriesSize); context->SetEntriesIndex(entriesIndex); context->GetEntry(entriesIndex, entry); + std::vector valueHashes; errCode = entry->GetValueHash(valueHashes); if (errCode != E_OK) { LOGE("ValueSliceSync::entry->GetValueHash %d", errCode); diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device/remote_executor.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/device/remote_executor.cpp index beabf605..b3f4ddd6 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device/remote_executor.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device/remote_executor.cpp @@ -63,7 +63,7 @@ int RemoteExecutor::Initialize(ISyncInterface *syncInterface, ICommunicator *com return E_OK; } -int RemoteExecutor::RemoteQuery(const std::string device, const RemoteCondition &condition, +int RemoteExecutor::RemoteQuery(const std::string &device, const RemoteCondition &condition, uint64_t timeout, uint64_t connectionId, std::shared_ptr &result) { if (closed_) { @@ -233,12 +233,13 @@ int RemoteExecutor::CheckPermissions(const std::string &device, Message *inMsg) storage->DecRefCount(); return errCode; } - const auto *requestPacket = inMsg->GetObject(); - if (requestPacket == nullptr) { + const auto *packet = inMsg->GetObject(); + if (packet == nullptr) { LOGE("[RemoteExecutor] get packet object failed"); storage->DecRefCount(); return -E_INVALID_ARGS; } + const auto *requestPacket = static_cast(packet); errCode = CheckRemoteRecvData(device, storage, requestPacket->GetSecLabel(), requestPacket->GetVersion()); storage->DecRefCount(); return errCode; @@ -258,13 +259,13 @@ int RemoteExecutor::SendRemoteExecutorData(const std::string &device, const Mess } RelationalDBSyncInterface *storage = static_cast(syncInterface); - const RemoteExecutorRequestPacket *requestPacket = inMsg->GetObject(); - if (requestPacket == nullptr) { + const auto *packet = inMsg->GetObject(); + if (packet == nullptr) { LOGE("[RemoteExecutor] get packet object failed"); storage->DecRefCount(); return -E_INVALID_ARGS; } - + const RemoteExecutorRequestPacket *requestPacket = static_cast(packet); int errCode = ResponseRemoteQueryRequest(storage, requestPacket->GetPreparedStmt(), device, inMsg->GetSessionId()); storage->DecRefCount(); return errCode; @@ -272,10 +273,11 @@ int RemoteExecutor::SendRemoteExecutorData(const std::string &device, const Mess int RemoteExecutor::ReceiveRemoteExecutorAck(const std::string &targetDev, Message *inMsg) { - auto *packet = inMsg->GetObject(); - if (packet == nullptr) { + const auto *ack = inMsg->GetObject(); + if (ack == nullptr) { return -E_INVALID_ARGS; } + const auto *packet = static_cast(ack); int errCode = packet->GetAckCode(); uint32_t sessionId = inMsg->GetSessionId(); uint32_t sequenceId = inMsg->GetSequenceId(); @@ -492,7 +494,8 @@ int RemoteExecutor::RequestStart(uint32_t sessionId) ReleaseMessageAndPacket(message, packet); return errCode; } - errCode = message->SetExternalObject(packet); + auto exObj = static_cast(packet); + errCode = message->SetExternalObject(exObj); if (errCode != E_OK) { ReleaseMessageAndPacket(message, packet); LOGE("[RemoteExecutor][RequestStart] set external object failed errCode=%d", errCode); @@ -578,8 +581,8 @@ int RemoteExecutor::ResponseStart(RemoteExecutorAckPacket *packet, uint32_t sess return -E_OUT_OF_MEMORY; } packet->SetVersion(RemoteExecutorAckPacket::RESPONSE_PACKET_VERSION_CURRENT); - - int errCode = message->SetExternalObject(packet); + auto exObj = static_cast(packet); + int errCode = message->SetExternalObject(exObj); if (errCode != E_OK) { ReleaseMessageAndPacket(message, packet); storage->DecRefCount(); @@ -765,7 +768,7 @@ int RemoteExecutor::FillRequestPacket(RemoteExecutorRequestPacket *packet, uint3 packet->SetSql(task.condition.sql); packet->SetBindArgs(task.condition.bindArgs); packet->SetNeedResponse(); - packet->SetSecLabel(errCode == -E_NOT_SUPPORT ? NOT_SURPPORT_SEC_CLASSIFICATION : localOption.securityLabel); + packet->SetSecLabel(errCode == -E_NOT_SUPPORT ? NOT_SUPPORT_SEC_CLASSIFICATION : localOption.securityLabel); target = task.target; return E_OK; } @@ -943,7 +946,7 @@ int RemoteExecutor::ResponseRemoteQueryRequest(RelationalDBSyncInterface *storag SecurityOption option; errCode = storage->GetSecurityOption(option); if (errCode == -E_NOT_SUPPORT) { - option.securityLabel = NOT_SURPPORT_SEC_CLASSIFICATION; + option.securityLabel = NOT_SUPPORT_SEC_CLASSIFICATION; errCode = E_OK; } if (errCode != E_OK) { @@ -988,7 +991,7 @@ int RemoteExecutor::CheckSecurityOption(ISyncInterface *storage, ICommunicator * if (errCode != E_OK && errCode != -E_NOT_SUPPORT) { return -E_SECURITY_OPTION_CHECK_ERROR; } - if (remoteOption.securityLabel == NOT_SURPPORT_SEC_CLASSIFICATION || errCode == -E_NOT_SUPPORT) { + if (remoteOption.securityLabel == NOT_SUPPORT_SEC_CLASSIFICATION || errCode == -E_NOT_SUPPORT) { return E_OK; } if (!CheckRemoteSecurityOption(device, remoteOption, localOption)) { @@ -1006,7 +1009,7 @@ int RemoteExecutor::CheckRemoteRecvData(const std::string &device, SyncGenericIn int errCode = storage->GetSecurityOption(localOption); LOGI("[RemoteExecutor] remote label:%d local l:%d, f:%d, errCode:%d, remote ver %" PRIu32, remoteSecLabel, localOption.securityLabel, localOption.securityFlag, errCode, remoteVersion); - if (remoteSecLabel == NOT_SURPPORT_SEC_CLASSIFICATION && errCode == -E_NOT_SUPPORT) { + if (remoteSecLabel == NOT_SUPPORT_SEC_CLASSIFICATION && errCode == -E_NOT_SUPPORT) { return E_OK; } if (errCode != -E_NOT_SUPPORT && localOption.securityLabel == SecurityLabel::NOT_SET) { @@ -1017,14 +1020,13 @@ int RemoteExecutor::CheckRemoteRecvData(const std::string &device, SyncGenericIn LOGE("[RemoteExecutor] remote security label not set!"); return -E_SECURITY_OPTION_CHECK_ERROR; } - if (errCode == -E_NOT_SUPPORT) { return E_OK; } if (errCode != E_OK) { return -E_SECURITY_OPTION_CHECK_ERROR; } - if (remoteSecLabel == UNKNOWN_SECURITY_LABEL || remoteSecLabel == NOT_SURPPORT_SEC_CLASSIFICATION) { + if (remoteSecLabel == UNKNOWN_SECURITY_LABEL || remoteSecLabel == NOT_SUPPORT_SEC_CLASSIFICATION) { return E_OK; } if (RuntimeContext::GetInstance()->CheckDeviceSecurityAbility(device, localOption)) { diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device/remote_executor.h b/kv_store/frameworks/libs/distributeddb/syncer/src/device/remote_executor.h index 4aa97492..62544a17 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device/remote_executor.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device/remote_executor.h @@ -58,7 +58,7 @@ public: int Initialize(ISyncInterface *syncInterface, ICommunicator *communicator); - int RemoteQuery(const std::string device, const RemoteCondition &condition, + int RemoteQuery(const std::string &device, const RemoteCondition &condition, uint64_t timeout, uint64_t connectionId, std::shared_ptr &result); // receive request and ack, and process in another thread diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device/remote_executor_packet.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/device/remote_executor_packet.cpp index 3681a790..7ff3e9f8 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device/remote_executor_packet.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device/remote_executor_packet.cpp @@ -293,7 +293,7 @@ int RemoteExecutorAckPacket::DeSerialization(Parcel &parcel) (void) parcel.ReadInt(secLabel_); (void) parcel.ReadInt(secFlag_); } else { - secLabel_ = NOT_SURPPORT_SEC_CLASSIFICATION; + secLabel_ = NOT_SUPPORT_SEC_CLASSIFICATION; } if (parcel.IsError()) { LOGE("[RemoteExecutorAckPacket] DeSerialization failed"); diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_data_packet.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_data_packet.cpp index b795a7d4..f66e41b1 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_data_packet.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_data_packet.cpp @@ -194,6 +194,8 @@ uint32_t DataRequestPacket::CalculateLen(uint32_t messageId) const totalLen += Parcel::GetUInt64Len(); // schemaVersion totalLen += Parcel::GetInt64Len(); // systemTimeOffset totalLen += Parcel::GetInt64Len(); // senderTimeOffset + totalLen += Parcel::GetIntLen(); // security label + totalLen += Parcel::GetIntLen(); // security flag } if (totalLen > INT32_MAX) { return 0; @@ -341,6 +343,16 @@ int64_t DataRequestPacket::GetSenderTimeOffset() const return senderTimeOffset_; } +void DataRequestPacket::SetSecurityOption(const SecurityOption &option) +{ + securityOption_ = option; +} + +SecurityOption DataRequestPacket::GetSecurityOption() const +{ + return securityOption_; +} + void DataAckPacket::SetData(uint64_t data) { data_ = data; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_data_packet.h b/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_data_packet.h index 56bd3114..9b3ba510 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_data_packet.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_data_packet.h @@ -120,6 +120,9 @@ public: void SetSenderTimeOffset(int64_t senderTimeOffset); int64_t GetSenderTimeOffset() const; + + void SetSecurityOption(const SecurityOption &option); + SecurityOption GetSecurityOption() const; protected: std::vector data_; WaterMark endWaterMark_ = 0; @@ -141,6 +144,7 @@ protected: uint64_t schemaVersion_ = 0; // sender schema version, add in 109 int64_t systemTimeOffset_ = 0; // sender device time offset with receiver, add in 109 int64_t senderTimeOffset_ = 0; // sender local time offset, add in 109 + SecurityOption securityOption_; static const uint32_t IS_LAST_SEQUENCE = 0x1; // bit 0 used for isLastSequence, 1: is last, 0: not last static const uint32_t IS_UPDATE_WATER = 0x2; // bit 1 used for update watermark, 0: update, 1: not update static const uint32_t IS_COMPRESS_DATA = 0x4; // bit 3 used for compress data, 0: raw data, 1: compress data diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_data_sync.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_data_sync.cpp index f72ad9ac..bd4e90ec 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_data_sync.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_data_sync.cpp @@ -270,7 +270,7 @@ int SingleVerDataSync::GetDataWithPerformanceRecord(SingleVerSyncTaskContext *co performance->StepTimeRecordEnd(PT_TEST_RECORDS::RECORD_READ_DATA); } if (!outData.empty()) { - RecordClientId(context); + SingleVerDataSyncUtils::RecordClientId(*context, *storage_, metadata_); } return errCode; } @@ -406,21 +406,27 @@ int SingleVerDataSync::SaveData(const SingleVerSyncTaskContext *context, const s if (inData.empty()) { return E_OK; } - RecordClientId(context); + SingleVerDataSyncUtils::RecordClientId(*context, *storage_, metadata_); PerformanceAnalysis *performance = PerformanceAnalysis::GetInstance(); if (performance != nullptr) { performance->StepTimeRecordStart(PT_TEST_RECORDS::RECORD_SAVE_DATA); } - - const std::string localHashName = DBCommon::TransferHashString(GetLocalDeviceName()); + const auto localDeviceName = GetLocalDeviceName(); + const std::string localHashName = DBCommon::TransferHashString(localDeviceName); SingleVerDataSyncUtils::TransSendDataItemToLocal(context, localHashName, inData); + std::vector copyData = inData; + int errCode = storage_->InterceptData(copyData, GetDeviceId(), localDeviceName, false); + if (errCode != E_OK) { + LOGE("[DataSync][SaveData] intercept data failed, errCode=%d", errCode); + return errCode; + } // query only support prefix key and don't have query in packet in 104 version - int errCode = storage_->PutSyncDataWithQuery(query, inData, context->GetDeviceId()); + errCode = storage_->PutSyncDataWithQuery(query, copyData, context->GetDeviceId()); if (performance != nullptr) { performance->StepTimeRecordEnd(PT_TEST_RECORDS::RECORD_SAVE_DATA); } if (errCode != E_OK) { - LOGE("[DataSync][SaveData] save sync data failed,errCode=%d", errCode); + LOGE("[DataSync][SaveData] save sync data failed, errCode=%d", errCode); } return errCode; } @@ -654,7 +660,7 @@ void SingleVerDataSync::UpdateSendInfo(SyncTimeRange dataTimeRange, SingleVerSyn void SingleVerDataSync::FillDataRequestPacket(DataRequestPacket *packet, SingleVerSyncTaskContext *context, SyncEntry &syncData, int sendCode, int mode) { - SetDataRequestCommonInfo(*context, *packet); + SingleVerDataSyncUtils::SetDataRequestCommonInfo(*context, *storage_, *packet, metadata_); SyncType curType = (context->IsQuerySync()) ? SyncType::QUERY_SYNC_TYPE : SyncType::MANUAL_FULL_SYNC_TYPE; uint32_t version = std::min(context->GetRemoteSoftwareVersion(), SOFTWARE_VERSION_CURRENT); WaterMark localMark = 0; @@ -687,7 +693,8 @@ void SingleVerDataSync::FillDataRequestPacket(DataRequestPacket *packet, SingleV packet->SetQuery(context->GetQuery()); packet->SetQueryId(context->GetQuerySyncId()); CompressAlgorithm curAlgo = context->ChooseCompressAlgo(); - if (needCompressOnSync && curAlgo != CompressAlgorithm::NONE) { + // empty compress data should not mark compress + if (!syncData.compressedEntries.empty() && needCompressOnSync && curAlgo != CompressAlgorithm::NONE) { packet->SetCompressDataMark(); packet->SetCompressAlgo(curAlgo); } @@ -803,7 +810,7 @@ int SingleVerDataSync::PullRequestStart(SingleVerSyncTaskContext *context) uint32_t version = std::min(context->GetRemoteSoftwareVersion(), SOFTWARE_VERSION_CURRENT); WaterMark endMark = context->GetEndMark(); SyncTimeRange dataTime = {localMark, deleteMark, localMark, deleteMark}; - SetDataRequestCommonInfo(*context, *packet); + SingleVerDataSyncUtils::SetDataRequestCommonInfo(*context, *storage_, *packet, metadata_); packet->SetBasicInfo(E_OK, version, context->GetMode()); packet->SetExtraConditions(RuntimeContext::GetInstance()->GetPermissionCheckParam(storage_->GetDbProperties())); packet->SetWaterMark(localMark, peerMark, deleteMark); @@ -950,7 +957,7 @@ int SingleVerDataSync::DataRequestRecvPre(SingleVerSyncTaskContext *context, con return -E_WAIT_NEXT_MESSAGE; } // only deal with pull response packet errCode - if (sendCode != E_OK && sendCode != SEND_FINISHED && + if (sendCode != E_OK && sendCode != SEND_FINISHED && sendCode != -E_UNFINISHED && message->GetSessionId() == context->GetRequestSessionId()) { LOGE("[DataSync][DataRequestRecvPre] remote pullResponse getData sendCode=%d", sendCode); return sendCode; @@ -969,7 +976,7 @@ int SingleVerDataSync::DataRequestRecvPre(SingleVerSyncTaskContext *context, con (void)SendDataAck(context, message, errCode, 0); return errCode; } - errCode = SingleVerDataSyncUtils::SchemaVersionMatchCheck(deviceId_, *packet, *context, metadata_); + errCode = SingleVerDataSyncUtils::SchemaVersionMatchCheck(*context, *packet, metadata_); if (errCode != E_OK) { (void)SendDataAck(context, message, errCode, 0); } @@ -1030,7 +1037,7 @@ int SingleVerDataSync::DataRequestRecv(SingleVerSyncTaskContext *context, const return errCode; } -int SingleVerDataSync::SendDataPacket(SyncType syncType, const DataRequestPacket *packet, +int SingleVerDataSync::SendDataPacket(SyncType syncType, DataRequestPacket *packet, SingleVerSyncTaskContext *context) { Message *message = new (std::nothrow) Message(SingleVerDataSyncUtils::GetMessageId(syncType)); @@ -1321,6 +1328,11 @@ int SingleVerDataSync::RunPermissionCheck(SingleVerSyncTaskContext *context, con const std::vector &data = packet->GetData(); WaterMark maxSendDataTime = SingleVerDataSyncUtils::GetMaxSendDataTime(data); uint32_t version = std::min(context->GetRemoteSoftwareVersion(), SOFTWARE_VERSION_CURRENT); + auto securityOption = packet->GetSecurityOption(); + if (context->GetRemoteSeccurityOption().securityLabel == SecurityLabel::NOT_SET && + securityOption.securityLabel != SecurityLabel::NOT_SET) { + context->SetRemoteSeccurityOption(packet->GetSecurityOption()); + } if (version > SOFTWARE_VERSION_RELEASE_2_0 && (mode != SyncModeType::PULL) && !context->GetReceivcPermitCheck()) { bool permitReceive = SingleVerDataSyncUtils::CheckPermitReceiveData(context, communicateHandle_, storage_); @@ -1394,6 +1406,10 @@ int32_t SingleVerDataSync::ReSend(SingleVerSyncTaskContext *context, DataSyncReS } FillRequestReSendPacket(context, packet, reSendInfo, syncData, errCode); errCode = SendReSendPacket(packet, context, reSendInfo.sessionId, reSendInfo.sequenceId); + if (curType == SyncType::QUERY_SYNC_TYPE && (context->GetQuery().HasLimit() || context->GetQuery().HasOrderBy())) { + LOGI("[DataSync][ReSend] query contain limit/offset/orderby, no need to update watermark."); + return errCode; + } if (errCode == E_OK && SyncOperation::TransferSyncMode(context->GetMode()) != SyncModeType::PULL) { // resend.end may not update in localwatermark while E_TIMEOUT occurred in send message last time. SyncTimeRange dataTime {reSendInfo.start, reSendInfo.deleteDataStart, reSendInfo.end, reSendInfo.deleteDataEnd}; @@ -1411,7 +1427,7 @@ int32_t SingleVerDataSync::ReSend(SingleVerSyncTaskContext *context, DataSyncReS return errCode; } -int SingleVerDataSync::SendReSendPacket(const DataRequestPacket *packet, SingleVerSyncTaskContext *context, +int SingleVerDataSync::SendReSendPacket(DataRequestPacket *packet, SingleVerSyncTaskContext *context, uint32_t sessionId, uint32_t sequenceId) { SyncType syncType = (context->IsQuerySync()) ? SyncType::QUERY_SYNC_TYPE : SyncType::MANUAL_FULL_SYNC_TYPE; @@ -1686,7 +1702,7 @@ void SingleVerDataSync::UpdateMtuSize() void SingleVerDataSync::FillRequestReSendPacket(const SingleVerSyncTaskContext *context, DataRequestPacket *packet, DataSyncReSendInfo reSendInfo, SyncEntry &syncData, int sendCode) { - SetDataRequestCommonInfo(*context, *packet); + SingleVerDataSyncUtils::SetDataRequestCommonInfo(*context, *storage_, *packet, metadata_); SyncType curType = (context->IsQuerySync()) ? SyncType::QUERY_SYNC_TYPE : SyncType::MANUAL_FULL_SYNC_TYPE; WaterMark peerMark = 0; GetPeerWaterMark(curType, context->GetQuerySyncId(), context->GetDeviceId(), @@ -1718,7 +1734,7 @@ void SingleVerDataSync::FillRequestReSendPacket(const SingleVerSyncTaskContext * std::vector reserved {reSendInfo.packetId}; packet->SetReserved(reserved); } - if (reSendMode == SyncModeType::PULL) { + if (reSendMode == SyncModeType::PULL || reSendMode == SyncModeType::QUERY_PULL) { // resend pull packet dont set compress type return; } @@ -1752,7 +1768,7 @@ int SingleVerDataSync::InterceptData(SyncEntry &syncEntry) // GetLocalDeviceName get local device ID. // GetDeviceId get remote device ID. // If intercept data fail, entries will be released. - return storage_->InterceptData(syncEntry.entries, GetLocalDeviceName(), GetDeviceId()); + return storage_->InterceptData(syncEntry.entries, GetLocalDeviceName(), GetDeviceId(), true); } int SingleVerDataSync::ControlCmdStart(SingleVerSyncTaskContext *context) @@ -1870,7 +1886,7 @@ int SingleVerDataSync::ControlCmdStartCheck(SingleVerSyncTaskContext *context) return E_OK; } -int SingleVerDataSync::SendControlPacket(const ControlRequestPacket *packet, SingleVerSyncTaskContext *context) +int SingleVerDataSync::SendControlPacket(ControlRequestPacket *packet, SingleVerSyncTaskContext *context) { Message *message = new (std::nothrow) Message(CONTROL_SYNC_MESSAGE); if (message == nullptr) { @@ -2116,36 +2132,4 @@ void SingleVerDataSync::RemoveSubscribeIfNeed(const std::string &queryId, storage_->RemoveSubscribe(queryId); } } - -void SingleVerDataSync::RecordClientId(const SingleVerSyncTaskContext *context) -{ - StoreInfo info = { - storage_->GetDbProperties().GetStringProp(DBProperties::USER_ID, ""), - storage_->GetDbProperties().GetStringProp(DBProperties::APP_ID, ""), - storage_->GetDbProperties().GetStringProp(DBProperties::STORE_ID, "") - }; - std::string clientId; - int errCode = E_OK; - if (RuntimeContext::GetInstance()->TranslateDeviceId(context->GetDeviceId(), info, clientId) == E_OK) { - errCode = metadata_->SaveClientId(context->GetDeviceId(), clientId); - if (errCode != E_OK) { - LOGW("[DataSync] record clientId failed %d", errCode); - } - } -} - -void SingleVerDataSync::SetDataRequestCommonInfo(const SingleVerSyncTaskContext &context, DataRequestPacket &packet) -{ - packet.SetSenderTimeOffset(metadata_->GetLocalTimeOffset()); - packet.SetSystemTimeOffset(metadata_->GetSystemTimeOffset(deviceId_)); - if (context.GetRemoteSoftwareVersion() < SOFTWARE_VERSION_RELEASE_9_0) { - return; - } - auto [err, localSchemaVer] = metadata_->GetLocalSchemaVersion(); - if (err != E_OK) { - LOGW("[DataSync] get local schema version failed:%d", err); - return; - } - packet.SetSchemaVersion(localSchemaVer); -} } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_data_sync.h b/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_data_sync.h index 0be2eab8..c8b7d775 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_data_sync.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_data_sync.h @@ -183,7 +183,7 @@ protected: int DealRemoveDeviceDataByAck(SingleVerSyncTaskContext *context, WaterMark ackWaterMark, const std::vector &reserved); - int SendDataPacket(SyncType syncType, const DataRequestPacket *packet, SingleVerSyncTaskContext *context); + int SendDataPacket(SyncType syncType, DataRequestPacket *packet, SingleVerSyncTaskContext *context); void UpdateQueryPeerWaterMark(SyncType syncType, const std::string &queryId, const SyncTimeRange &dataTime, const SingleVerSyncTaskContext *context, UpdateWaterMark isUpdateWaterMark); @@ -208,7 +208,7 @@ protected: void SendResetWatchDogPacket(SingleVerSyncTaskContext *context, uint32_t packetLen); - int SendReSendPacket(const DataRequestPacket *packet, SingleVerSyncTaskContext *context, + int SendReSendPacket(DataRequestPacket *packet, SingleVerSyncTaskContext *context, uint32_t sessionId, uint32_t sequenceId); int SendPullResponseDataPkt(int ackCode, SyncEntry &syncOutData, SingleVerSyncTaskContext *context); @@ -238,7 +238,7 @@ protected: int ControlCmdStartCheck(SingleVerSyncTaskContext *context); - int SendControlPacket(const ControlRequestPacket *packet, SingleVerSyncTaskContext *context); + int SendControlPacket(ControlRequestPacket *packet, SingleVerSyncTaskContext *context); int ControlCmdRequestRecvPre(SingleVerSyncTaskContext *context, const Message *message); int SubscribeRequestRecvPre(SingleVerSyncTaskContext *context, const SubscribeRequest *packet, @@ -251,10 +251,6 @@ protected: void RemoveSubscribeIfNeed(const std::string &queryId, const std::shared_ptr &subscribeManager); - void RecordClientId(const SingleVerSyncTaskContext *context); - - void SetDataRequestCommonInfo(const SingleVerSyncTaskContext &context, DataRequestPacket &packet); - uint32_t mtuSize_; SyncGenericInterface* storage_; ICommunicator* communicateHandle_; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_data_sync_utils.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_data_sync_utils.cpp index 071c9ab0..b61f0026 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_data_sync_utils.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_data_sync_utils.cpp @@ -120,7 +120,7 @@ bool SingleVerDataSyncUtils::IsPermitRemoteDeviceRecvData(const std::string &dev return false; } SecurityOption localSecOption; - if (remoteSecOption.securityLabel == NOT_SURPPORT_SEC_CLASSIFICATION) { + if (remoteSecOption.securityLabel == NOT_SUPPORT_SEC_CLASSIFICATION) { return true; } int errCode = storage->GetSecurityOption(localSecOption); @@ -214,34 +214,53 @@ bool SingleVerDataSyncUtils::CheckPermitReceiveData(const SingleVerSyncTaskConte const ICommunicator *communicator, const SyncGenericInterface *storage) { if (storage == nullptr) { - LOGE("[DataSync] storage is nullptr when check receive data"); + LOGE("[SingleVerDataSyncUtils] storage is nullptr when check receive data"); return false; } // check memory db here because remote maybe low version // it will send option with not set rather than not support when remote is memory db bool memory = storage->GetDbProperties().GetBoolProp(KvDBProperties::MEMORY_MODE, false); if (memory) { - LOGI("[DataSync] skip check receive data because local is memory db"); + LOGI("[SingleVerDataSyncUtils] skip check receive data because local is memory db"); return true; } SecurityOption remoteSecOption = context->GetRemoteSeccurityOption(); std::string localDeviceId; - if (communicator == nullptr || remoteSecOption.securityLabel == NOT_SURPPORT_SEC_CLASSIFICATION) { + if (communicator == nullptr || remoteSecOption.securityLabel == NOT_SUPPORT_SEC_CLASSIFICATION) { return true; } communicator->GetLocalIdentity(localDeviceId); SecurityOption localOption; - (void)storage->GetSecurityOption(localOption); + int errCode = storage->GetSecurityOption(localOption); + if (errCode == -E_NOT_SUPPORT) { + LOGD("[SingleVerDataSyncUtils] local not support get security label"); + return true; + } + if (errCode == E_OK && localOption.securityLabel == SecurityLabel::NOT_SET) { + LOGE("[SingleVerDataSyncUtils] local label is not set!"); + return false; + } if (remoteSecOption.securityLabel == SecurityLabel::S0 && localOption.securityLabel == SecurityLabel::S1) { remoteSecOption.securityLabel = SecurityLabel::S1; - LOGI("[DataSync] Transform Remote SecLabel From S0 To S1 When Receive Data"); + LOGI("[SingleVerDataSyncUtils] Transform Remote SecLabel From S0 To S1 When Receive Data"); + } + if (remoteSecOption.securityLabel == FAILED_GET_SEC_CLASSIFICATION) { + LOGE("[SingleVerDataSyncUtils] remote label get failed!"); + return false; + } + if (remoteSecOption.securityLabel != SecurityLabel::NOT_SET && + remoteSecOption.securityLabel != localOption.securityLabel) { + LOGE("[SingleVerDataSyncUtils] label is not equal remote %d local %d", remoteSecOption.securityLabel, + localOption.securityLabel); + return false; } bool isPermitSync = SingleVerDataSyncUtils::IsPermitLocalDeviceRecvData(localDeviceId, remoteSecOption); if (isPermitSync) { return isPermitSync; } - LOGE("[DataSync][PermitReceiveData] check failed: permitReceive=%d, localDev=%s, seclabel=%d, secflag=%d", - isPermitSync, STR_MASK(localDeviceId), remoteSecOption.securityLabel, remoteSecOption.securityFlag); + LOGE("[SingleVerDataSyncUtils][PermitReceiveData] check failed: permitReceive=%d, localDev=%s, seclabel=%d," + " secflag=%d", isPermitSync, STR_MASK(localDeviceId), remoteSecOption.securityLabel, + remoteSecOption.securityFlag); return isPermitSync; } @@ -495,16 +514,60 @@ std::pair SingleVerDataSyncUtils::GetTimeOffsetFromReque return res; } -int SingleVerDataSyncUtils::SchemaVersionMatchCheck(const std::string &deviceId, const DataRequestPacket &packet, - SingleVerSyncTaskContext &context, std::shared_ptr &metadata) +void SingleVerDataSyncUtils::RecordClientId(const SingleVerSyncTaskContext &context, + const SyncGenericInterface &storage, std::shared_ptr &metadata) +{ + StoreInfo info = { + storage.GetDbProperties().GetStringProp(DBProperties::USER_ID, ""), + storage.GetDbProperties().GetStringProp(DBProperties::APP_ID, ""), + storage.GetDbProperties().GetStringProp(DBProperties::STORE_ID, "") + }; + std::string clientId; + int errCode = E_OK; + if (RuntimeContext::GetInstance()->TranslateDeviceId(context.GetDeviceId(), info, clientId) == E_OK) { + errCode = metadata->SaveClientId(context.GetDeviceId(), clientId); + if (errCode != E_OK) { + LOGW("[DataSync] record clientId failed %d", errCode); + } + } +} + +void SingleVerDataSyncUtils::SetDataRequestCommonInfo(const SingleVerSyncTaskContext &context, + const SyncGenericInterface &storage, DataRequestPacket &packet, std::shared_ptr &metadata) +{ + packet.SetSenderTimeOffset(metadata->GetLocalTimeOffset()); + packet.SetSystemTimeOffset(metadata->GetSystemTimeOffset(context.GetDeviceId())); + if (context.GetRemoteSoftwareVersion() < SOFTWARE_VERSION_RELEASE_9_0) { + return; + } + auto [err, localSchemaVer] = metadata->GetLocalSchemaVersion(); + if (err != E_OK) { + LOGW("[DataSync] get local schema version failed:%d", err); + return; + } + packet.SetSchemaVersion(localSchemaVer); + SecurityOption localOption; + err = storage.GetSecurityOption(localOption); + if (err == -E_NOT_SUPPORT) { + LOGW("[DataSync] local not support sec classification"); + localOption.securityLabel = NOT_SUPPORT_SEC_CLASSIFICATION; + } else if (err != E_OK) { + LOGE("[DataSync] get local security option errCode:%d", err); + localOption.securityLabel = FAILED_GET_SEC_CLASSIFICATION; + } + packet.SetSecurityOption(localOption); +} + +int SingleVerDataSyncUtils::SchemaVersionMatchCheck(const SingleVerSyncTaskContext &context, + const DataRequestPacket &packet, std::shared_ptr &metadata) { if (context.GetRemoteSoftwareVersion() < SOFTWARE_VERSION_RELEASE_9_0) { return E_OK; } - auto remoteSchemaVersion = metadata->GetRemoteSchemaVersion(deviceId); + auto remoteSchemaVersion = metadata->GetRemoteSchemaVersion(context.GetDeviceId()); if (remoteSchemaVersion != packet.GetSchemaVersion()) { LOGE("[DataSync] remote schema version misMatch, need ability sync again, packet %" PRIu64 " cache %" PRIu64, - packet.GetSchemaVersion(), remoteSchemaVersion); + packet.GetSchemaVersion(), remoteSchemaVersion); return -E_NEED_ABILITY_SYNC; } return E_OK; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_data_sync_utils.h b/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_data_sync_utils.h index bdfde107..ad7c03ea 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_data_sync_utils.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_data_sync_utils.h @@ -94,8 +94,14 @@ public: static std::pair GetTimeOffsetFromRequestMsg(const Message *message); - static int SchemaVersionMatchCheck(const std::string &deviceId, const DataRequestPacket &packet, - SingleVerSyncTaskContext &context, std::shared_ptr &metadata); + static void RecordClientId(const SingleVerSyncTaskContext &context, const SyncGenericInterface &storage, + std::shared_ptr &metadata);; + + static void SetDataRequestCommonInfo(const SingleVerSyncTaskContext &context, + const SyncGenericInterface &storage, DataRequestPacket &packet, std::shared_ptr &metadata); + + static int SchemaVersionMatchCheck(const SingleVerSyncTaskContext &context, const DataRequestPacket &packet, + std::shared_ptr &metadata); private: static int RunPermissionCheckInner(const SingleVerSyncTaskContext *context, const SyncGenericInterface* storage, const std::string &label, const DataRequestPacket *packet, int mode); diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_relational_sync_task_context.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_relational_sync_task_context.cpp index 1be90f1b..607d2999 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_relational_sync_task_context.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_relational_sync_task_context.cpp @@ -51,9 +51,9 @@ void SingleVerRelationalSyncTaskContext::Clear() SingleVerSyncTaskContext::Clear(); } -void SingleVerRelationalSyncTaskContext::CopyTargetData(const ISyncTarget *target, const TaskParam &TaskParam) +void SingleVerRelationalSyncTaskContext::CopyTargetData(const ISyncTarget *target, const TaskParam &taskParam) { - SingleVerSyncTaskContext::CopyTargetData(target, TaskParam); + SingleVerSyncTaskContext::CopyTargetData(target, taskParam); std::string hashTableName; std::string queryId; { @@ -72,7 +72,8 @@ void SingleVerRelationalSyncTaskContext::CopyTargetData(const ISyncTarget *targe } } -void SingleVerRelationalSyncTaskContext::SetRelationalSyncStrategy(RelationalSyncStrategy &strategy, bool isSchemaSync) +void SingleVerRelationalSyncTaskContext::SetRelationalSyncStrategy(const RelationalSyncStrategy &strategy, + bool isSchemaSync) { std::lock_guard autoLock(syncStrategyMutex_); relationalSyncStrategy_ = strategy; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_relational_sync_task_context.h b/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_relational_sync_task_context.h index 77b60c75..b22d4837 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_relational_sync_task_context.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_relational_sync_task_context.h @@ -31,7 +31,7 @@ public: std::string GetQuerySyncId() const override; std::string GetDeleteSyncId() const override; - void SetRelationalSyncStrategy(RelationalSyncStrategy &strategy, bool isSchemaSync); + void SetRelationalSyncStrategy(const RelationalSyncStrategy &strategy, bool isSchemaSync); std::pair GetSchemaSyncStatus(QuerySyncObject &querySyncObject) const override; void SchemaChange() override; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_serialize_manager.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_serialize_manager.cpp index bf2f9fb5..baf07292 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_serialize_manager.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_serialize_manager.cpp @@ -454,7 +454,6 @@ int SingleVerSerializeManager::DataPacketSyncerPartDeSerialization(Parcel &parce int32_t sendCode; int32_t mode; uint32_t sessionId; - uint32_t flag = 0; std::vector reserved; uint64_t totPacketLen = packLen; @@ -466,6 +465,7 @@ int SingleVerSerializeManager::DataPacketSyncerPartDeSerialization(Parcel &parce totPacketLen += parcel.ReadUInt32(sessionId); totPacketLen += parcel.ReadVector(reserved); if (version > SOFTWARE_VERSION_RELEASE_2_0) { + uint32_t flag = 0u; totPacketLen += parcel.ReadUInt32(flag); packet->SetFlag(flag); } @@ -926,6 +926,13 @@ int SingleVerSerializeManager::DataPacketInnerDeSerialization(DataRequestPacket packet->SetSchemaVersion(schemaVersion); packet->SetSystemTimeOffset(systemTimeOffset); packet->SetSenderTimeOffset(senderTimeOffset); + if (!parcel.IsContinueRead()) { + return errCode; + } + SecurityOption option; + parcel.ReadInt(option.securityLabel); + parcel.ReadInt(option.securityFlag); + packet->SetSecurityOption(option); } return errCode; } @@ -951,6 +958,13 @@ int SingleVerSerializeManager::DataPacketInnerSerialization(const DataRequestPac LOGE("[SingleVerSerializeManager] Serialize schema version or time offset failed"); return -E_PARSE_FAIL; } + auto option = packet->GetSecurityOption(); + parcel.WriteInt(option.securityLabel); + parcel.WriteInt(option.securityFlag); + if (parcel.IsError()) { + LOGE("[SingleVerSerializeManager] Serialize security option failed"); + return -E_PARSE_FAIL; + } } return E_OK; } diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_sync_state_machine.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_sync_state_machine.cpp index 59f642a4..1daa1d1b 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_sync_state_machine.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_sync_state_machine.cpp @@ -154,7 +154,7 @@ int SingleVerSyncStateMachine::Initialize(ISyncTaskContext *context, ISyncInterf currentState_ = IDLE; context_ = static_cast(context); - syncInterface_ = static_cast(syncInterface); + syncInterface_ = static_cast(syncInterface); InitStateSwitchTables(); InitStateMapping(); @@ -713,7 +713,6 @@ void SingleVerSyncStateMachine::NeedAbilitySyncHandle() currentRemoteVersionId_ = context_->GetRemoteSoftwareVersionId(); } abilitySync_->SetAbilitySyncFinishedStatus(false, *context_); - dataSync_->ClearSyncStatus(); } int SingleVerSyncStateMachine::HandleDataAckRecv(const Message *inMsg) diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_sync_state_machine.h b/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_sync_state_machine.h index 5816fa9e..f026d976 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_sync_state_machine.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_sync_state_machine.h @@ -226,7 +226,7 @@ private: static bool isStateSwitchTableInited_; static std::vector stateSwitchTables_; SingleVerSyncTaskContext *context_; - SingleVerKvDBSyncInterface *syncInterface_; + SyncGenericInterface *syncInterface_; std::shared_ptr timeSync_; std::unique_ptr abilitySync_; std::shared_ptr dataSync_; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_sync_task_context.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_sync_task_context.cpp index ae6e6491..162ce6f3 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_sync_task_context.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_sync_task_context.cpp @@ -431,6 +431,9 @@ std::string SingleVerSyncTaskContext::GetRemoteCompressAlgoStr() const currentAlgoStr += algoMap[algo] + ","; } } + if (currentAlgoStr.empty()) { + return ""; + } return currentAlgoStr.substr(0, currentAlgoStr.length() - 1); } diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device/sync_engine.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/device/sync_engine.cpp index 36f22ef1..2cdb7333 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device/sync_engine.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device/sync_engine.cpp @@ -911,7 +911,7 @@ ICommunicator *SyncEngine::AllocCommunicator(const std::string &identifier, int errCode = communicator->RegOnConnectCallback( std::bind(&DeviceManager::OnDeviceConnectCallback, deviceManager_, - std::placeholders::_1, std::placeholders::_2), nullptr); + std::placeholders::_1, std::placeholders::_2), nullptr); if (errCode != E_OK) { LOGE("[SyncEngine][RegConnCB] register failed in SetEqualIdentifier! err %d", errCode); communicator->RegOnMessageCallback(nullptr, nullptr); diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device/sync_task_context.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/device/sync_task_context.cpp index 79acea9e..f5b55840 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device/sync_task_context.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device/sync_task_context.cpp @@ -313,7 +313,7 @@ int SyncTaskContext::StartTimer() TimerAction timeOutCallback = std::bind(&SyncTaskContext::TimeOut, this, std::placeholders::_1); int errCode = RuntimeContext::GetInstance()->SetTimer(timeout_, timeOutCallback, [this]() { - int ret = RuntimeContext::GetInstance()->ScheduleTask([this](){ RefObject::DecObjRef(this); }); + int ret = RuntimeContext::GetInstance()->ScheduleTask([this]() { RefObject::DecObjRef(this); }); if (ret != E_OK) { LOGE("[SyncTaskContext] timer finalizer ScheduleTask, errCode %d", ret); } diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device/time_sync.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/device/time_sync.cpp index 772fb5c4..13bdb2df 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device/time_sync.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device/time_sync.cpp @@ -219,7 +219,7 @@ void TimeSync::Finalize() } runtimeContext->RemoveTimer(timerId, true); std::unique_lock lock(timeDriverLock_); - timeDriverCond_.wait(lock, [this](){ return this->timeDriverLockCount_ == 0; }); + timeDriverCond_.wait(lock, [this]() { return this->timeDriverLockCount_ == 0; }); LOGD("[TimeSync] Finalized!"); } diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/sync_types.h b/kv_store/frameworks/libs/distributeddb/syncer/src/sync_types.h index 26323c90..77ea0c14 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/sync_types.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/sync_types.h @@ -77,7 +77,8 @@ struct InternalSyncParma { }; constexpr int32_t UNKNOWN_SECURITY_LABEL = -1; -constexpr int NOT_SURPPORT_SEC_CLASSIFICATION = 0xff; +constexpr int NOT_SUPPORT_SEC_CLASSIFICATION = 0xff; +constexpr int FAILED_GET_SEC_CLASSIFICATION = 0x55; constexpr uint8_t QUERY_SYNC_MODE_BASE = SyncModeType::QUERY_PUSH; constexpr int AUTO_RETRY_TIMES = 3; constexpr int MANUAL_RETRY_TIMES = 1; diff --git a/kv_store/frameworks/libs/distributeddb/test/BUILD.gn b/kv_store/frameworks/libs/distributeddb/test/BUILD.gn index e598245e..3ead7040 100644 --- a/kv_store/frameworks/libs/distributeddb/test/BUILD.gn +++ b/kv_store/frameworks/libs/distributeddb/test/BUILD.gn @@ -16,6 +16,37 @@ import("../distributeddb.gni") module_output_path = "kv_store/distributeddb" ############################################################################### +config("gaussdb_rd_config") { + visibility = [ ":*" ] + include_dirs = [ + "../gaussdb_rd/src/common/include", + "../gaussdb_rd/src/executor/include", + "../gaussdb_rd/src/executor/document", + "../gaussdb_rd/src/oh_adapter/include", + "../gaussdb_rd/src/oh_adapter/src", + "../gaussdb_rd/src/interface/include", + ] + + defines = [ + "SQLITE_ENABLE_SNAPSHOT", + "SQLITE_HAS_CODEC", + "SQLITE_ENABLE_JSON1", + "USING_HILOG_LOGGER", + "USE_SQLITE_SYMBOLS", + "SQLITE_ENABLE_DROPTABLE_CALLBACK", + ] +} + +config("gaussdb_rd_public_config") { + visibility = [ "*:*" ] + include_dirs = [ + "../gaussdb_rd/include", + "../gaussdb_rd/include/grd_base", + "../gaussdb_rd/include/grd_document", + "../gaussdb_rd/include/grd_kv", + ] +} + config("module_private_config") { visibility = [ ":*" ] @@ -120,6 +151,14 @@ ohos_source_set("src_file") { configs = [ ":module_private_config" ] + branch_protector_ret = "pac_ret" + sanitize = { + ubsan = true + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + } deps = [ "//third_party/googletest:gtest_main", "//third_party/sqlite:sqlite", @@ -133,6 +172,10 @@ ohos_source_set("src_file") { "//third_party/jsoncpp:jsoncpp", "//third_party/openssl:libcrypto_shared", ] + configs += [ ":gaussdb_rd_config" ] + public_configs = [ ":gaussdb_rd_public_config" ] + configs += [ "//third_party/cJSON:cJSON_config" ] + deps += [ "//third_party/cJSON:cjson" ] external_deps = [ "c_utils:utils", "ffrt:libffrt", @@ -660,6 +703,12 @@ distributeddb_unittest("DistributedDBCloudSyncerLockTest") { ] } +distributeddb_unittest("DistributedDBSingleVerMultiSubUserTest") { + sources = [ + "unittest/common/syncer/distributeddb_single_ver_multi_sub_user_test.cpp", + ] +} + distributeddb_unittest("DistributedDBCloudSyncerUploadTest") { sources = [ "unittest/common/syncer/cloud/distributeddb_cloud_syncer_upload_test.cpp", @@ -868,6 +917,7 @@ group("unittest") { ":DistributedDBSchemalTest", ":DistributedDBSingleVerDLPTest", ":DistributedDBSingleVerMsgScheduleTest", + ":DistributedDBSingleVerMultiSubUserTest", ":DistributedDBSingleVerMultiUserTest", ":DistributedDBSingleVerP2PComplexSyncTest", ":DistributedDBSingleVerP2PPermissionSyncTest", diff --git a/kv_store/frameworks/libs/distributeddb/test/fuzztest/cloudsync_fuzzer/cloudsync_fuzzer.cpp b/kv_store/frameworks/libs/distributeddb/test/fuzztest/cloudsync_fuzzer/cloudsync_fuzzer.cpp index 2130308f..2b224344 100644 --- a/kv_store/frameworks/libs/distributeddb/test/fuzztest/cloudsync_fuzzer/cloudsync_fuzzer.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/fuzztest/cloudsync_fuzzer/cloudsync_fuzzer.cpp @@ -16,14 +16,15 @@ #include "cloudsync_fuzzer.h" #include "cloud/cloud_db_types.h" #include "cloud/cloud_db_constant.h" -#include "time_helper.h" #include "distributeddb_data_generate_unit_test.h" #include "distributeddb_tools_test.h" -#include "log_print.h" #include "fuzzer_data.h" +#include "kv_store_nb_delegate.h" +#include "log_print.h" #include "relational_store_delegate.h" #include "relational_store_manager.h" #include "runtime_config.h" +#include "time_helper.h" #include "virtual_asset_loader.h" #include "virtual_cloud_data_translate.h" #include "virtual_cloud_db.h" @@ -36,6 +37,7 @@ static const char *g_deviceCloud = "cloud_dev"; static const char *g_storeId = "STORE_ID"; static const char *g_dbSuffix = ".db"; static const char *g_table = "worker1"; +KvStoreDelegateManager g_mgr(DistributedDBUnitTest::APP_ID, DistributedDBUnitTest::USER_ID); static const char *g_createLocalTableSql = "CREATE TABLE IF NOT EXISTS worker1(" \ "name TEXT PRIMARY KEY," \ @@ -158,6 +160,9 @@ public: void InitDbAsset(const uint8_t* data, size_t size) { + if (data == nullptr || size == 0) { + return; + } sqlite3_stmt *stmt = nullptr; int errCode = SQLiteUtils::GetStatement(db_, g_insertLocalAssetSql, stmt); if (errCode != E_OK) { @@ -245,7 +250,12 @@ public: mgr_ = std::make_shared("APP_ID", "USER_ID"); RelationalStoreDelegate::Option option; mgr_->OpenStore(storePath_, "STORE_ID", option, delegate_); + config_.dataDir = testDir_; + g_mgr.SetKvStoreConfig(config_); + GetKvStore(kvDelegatePtrS1_, DistributedDBUnitTest::STORE_ID_1); + GetKvStore(kvDelegatePtrS2_, DistributedDBUnitTest::STORE_ID_2); virtualCloudDb_ = std::make_shared(); + virtualCloudDb1_ = std::make_shared(); virtualAssetLoader_ = std::make_shared(); delegate_->SetCloudDB(virtualCloudDb_); delegate_->SetIAssetLoader(virtualAssetLoader_); @@ -263,12 +273,106 @@ public: LOGI("sqlite close with errCode %d", errCode); } virtualCloudDb_ = nullptr; + CloseKvStore(kvDelegatePtrS1_, DistributedDBUnitTest::STORE_ID_1); + CloseKvStore(kvDelegatePtrS2_, DistributedDBUnitTest::STORE_ID_2); + virtualCloudDb1_ = nullptr; virtualAssetLoader_ = nullptr; if (DistributedDBToolsTest::RemoveTestDbFiles(testDir_) != 0) { LOGE("rm test db files error."); } } + void KvBlockSync(KvStoreNbDelegate *delegate, DBStatus expectDBStatus, + SyncMode mode = SyncMode::SYNC_MODE_CLOUD_MERGE, int expectSyncResult = OK) + { + if (delegate == nullptr) { + return; + } + std::mutex dataMutex; + std::condition_variable cv; + bool finish = false; + SyncProcess last; + auto callback = [expectDBStatus, &last, &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; + last = item.second; + } + cv.notify_one(); + } + } + }; + CloudSyncOption option; + option.mode = mode; + option.users.push_back(DistributedDBUnitTest::USER_ID); + option.devices.push_back("cloud"); + delegate->Sync(option, callback); + if (expectSyncResult == OK) { + std::unique_lock uniqueLock(dataMutex); + cv.wait(uniqueLock, [&finish]() { + return finish; + }); + } + lastProcess_ = last; + } + + static DataBaseSchema GetDataBaseSchema() + { + DataBaseSchema schema; + TableSchema tableSchema; + tableSchema.name = CloudDbConstant::CLOUD_KV_TABLE_NAME; + Field field; + field.colName = CloudDbConstant::CLOUD_KV_FIELD_KEY; + field.type = TYPE_INDEX; + field.primary = true; + tableSchema.fields.push_back(field); + field.colName = CloudDbConstant::CLOUD_KV_FIELD_DEVICE; + field.primary = false; + tableSchema.fields.push_back(field); + field.colName = CloudDbConstant::CLOUD_KV_FIELD_ORI_DEVICE; + tableSchema.fields.push_back(field); + field.colName = CloudDbConstant::CLOUD_KV_FIELD_VALUE; + tableSchema.fields.push_back(field); + field.colName = CloudDbConstant::CLOUD_KV_FIELD_DEVICE_CREATE_TIME; + field.type = TYPE_INDEX; + tableSchema.fields.push_back(field); + schema.tables.push_back(tableSchema); + return schema; + } + + void GetKvStore(KvStoreNbDelegate *&delegate, const std::string &storeId, int securityLabel = NOT_SET) + { + KvStoreNbDelegate::Option option; + DBStatus openRet = OK; + option.secOption.securityLabel = securityLabel; + g_mgr.GetKvStore(storeId, option, [&openRet, &delegate](DBStatus status, KvStoreNbDelegate *openDelegate) { + openRet = status; + delegate = openDelegate; + }); + if (delegate == nullptr) { + return; + } + std::map> cloudDbs; + cloudDbs[DistributedDBUnitTest::USER_ID] = virtualCloudDb1_; + delegate->SetCloudDB(cloudDbs); + std::map schemas; + schemas[DistributedDBUnitTest::USER_ID] = GetDataBaseSchema(); + delegate->SetCloudDbSchema(schemas); + } + + static void CloseKvStore(KvStoreNbDelegate *&delegate, const std::string &storeId) + { + if (delegate != nullptr) { + g_mgr.CloseKvStore(delegate); + delegate = nullptr; + DBStatus status = g_mgr.DeleteKvStore(storeId); + LOGD("delete kv store status %d store %s", status, storeId.c_str()); + } + } + void BlockSync(SyncMode mode = SYNC_MODE_CLOUD_MERGE) { Query query = Query::Select().FromTable({ g_table }); @@ -294,6 +398,17 @@ public: BlockSync(); } + void KvNormalSync() + { + Key key = {'k'}; + Value expectValue = {'v'}; + kvDelegatePtrS1_->Put(key, expectValue); + KvBlockSync(kvDelegatePtrS1_, OK); + KvBlockSync(kvDelegatePtrS2_, OK); + Value actualValue; + kvDelegatePtrS2_->Get(key, actualValue); + } + void RandomModeSync(const uint8_t* data, size_t size) { if (size == 0) { @@ -359,9 +474,14 @@ private: std::string storePath_; sqlite3 *db_ = nullptr; RelationalStoreDelegate *delegate_ = nullptr; + KvStoreNbDelegate* kvDelegatePtrS1_ = nullptr; + KvStoreNbDelegate* kvDelegatePtrS2_ = nullptr; std::shared_ptr virtualCloudDb_; + std::shared_ptr virtualCloudDb1_ = nullptr; std::shared_ptr virtualAssetLoader_; std::shared_ptr mgr_; + KvStoreConfig config_; + SyncProcess lastProcess_; Assets localAssets_; }; CloudSyncTest *g_cloudSyncTest = nullptr; @@ -392,6 +512,7 @@ void CombineTest(const uint8_t* data, size_t size) return; } g_cloudSyncTest->NormalSync(); + g_cloudSyncTest->KvNormalSync(); g_cloudSyncTest->RandomModeSync(data, size); g_cloudSyncTest->DataChangeSync(data, size); g_cloudSyncTest->AssetChangeSync(data, size); diff --git a/kv_store/frameworks/libs/distributeddb/test/fuzztest/kvstoreresultset_fuzzer/kvstoreresultset_fuzzer.h b/kv_store/frameworks/libs/distributeddb/test/fuzztest/kvstoreresultset_fuzzer/kvstoreresultset_fuzzer.h index 95fa0d3d..05a8f768 100644 --- a/kv_store/frameworks/libs/distributeddb/test/fuzztest/kvstoreresultset_fuzzer/kvstoreresultset_fuzzer.h +++ b/kv_store/frameworks/libs/distributeddb/test/fuzztest/kvstoreresultset_fuzzer/kvstoreresultset_fuzzer.h @@ -20,7 +20,7 @@ #include -uint32_t U32_AT(const uint8_t * const &ptr) +static inline uint32_t U32_AT(const uint8_t * const &ptr) { // 24 - 16 - 8 - 0, the 3th one no need to shift left return (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3]; diff --git a/kv_store/frameworks/libs/distributeddb/test/fuzztest/query_fuzzer/query_fuzzer.h b/kv_store/frameworks/libs/distributeddb/test/fuzztest/query_fuzzer/query_fuzzer.h index a0a25e67..78db522c 100644 --- a/kv_store/frameworks/libs/distributeddb/test/fuzztest/query_fuzzer/query_fuzzer.h +++ b/kv_store/frameworks/libs/distributeddb/test/fuzztest/query_fuzzer/query_fuzzer.h @@ -20,13 +20,7 @@ #include -uint16_t U16_AT(const uint8_t * const &ptr) -{ - // 8 - 0 - return (ptr[0] << 8) | ptr[1]; -} - -uint32_t U32_AT(const uint8_t * const &ptr) +static inline uint32_t U32_AT(const uint8_t * const &ptr) { // 24 - 16 - 8 - 0, the 3th one no need to shift left return (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3]; diff --git a/kv_store/frameworks/libs/distributeddb/test/fuzztest/storage_fuzzer/storage_fuzzer.cpp b/kv_store/frameworks/libs/distributeddb/test/fuzztest/storage_fuzzer/storage_fuzzer.cpp index 01ff079b..eaa58874 100644 --- a/kv_store/frameworks/libs/distributeddb/test/fuzztest/storage_fuzzer/storage_fuzzer.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/fuzztest/storage_fuzzer/storage_fuzzer.cpp @@ -15,6 +15,7 @@ #include "storage_fuzzer.h" +#include "cloud/cloud_db_types.h" #include "db_errno.h" #include "distributeddb_data_generate_unit_test.h" #include "relational_sync_able_storage.h" @@ -22,7 +23,6 @@ #include "sqlite_relational_store.h" #include "log_table_manager_factory.h" -#include "cloud_db_types.h" #include "distributeddb_tools_test.h" #include "log_print.h" #include "fuzzer_data.h" diff --git a/kv_store/frameworks/libs/distributeddb/test/moduletest/src/distributeddb_nb_batch_crud_test.cpp b/kv_store/frameworks/libs/distributeddb/test/moduletest/src/distributeddb_nb_batch_crud_test.cpp index f102f824..42c54c92 100644 --- a/kv_store/frameworks/libs/distributeddb/test/moduletest/src/distributeddb_nb_batch_crud_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/moduletest/src/distributeddb_nb_batch_crud_test.cpp @@ -378,7 +378,7 @@ HWTEST_F(DistributeddbNbBatchCrudTest, SimpleData008, TestSize.Level1) { vector entriesBatch, entryResults; vector allKeys; - GenerateRecords(BATCH_RECORDS + 1, DEFAULT_START, allKeys, entriesBatch); + GenerateFixedRecords(entriesBatch, allKeys, BATCH_RECORDS + 1, FOUR_M_LONG_STRING, ONE_M_LONG_STRING); /** * @tc.steps: step1. PutBatch 129 items to DB and GetEntries(). @@ -1582,7 +1582,7 @@ HWTEST_F(DistributeddbNbBatchCrudTest, Transaction012, TestSize.Level1) HWTEST_F(DistributeddbNbBatchCrudTest, Transaction013, TestSize.Level1) { std::vector entries, entriesGot; - EntrySize entrySize = {KEY_SIX_BYTE, VALUE_ONE_HUNDRED_BYTE}; + EntrySize entrySize = {KEY_SIX_BYTE, FOUR_M_LONG_STRING - KEY_SIX_BYTE}; GenerateAppointPrefixAndSizeRecords(entries, entrySize, BATCH_RECORDS); /** * @tc.steps: step1. start transaction @@ -1628,7 +1628,7 @@ HWTEST_F(DistributeddbNbBatchCrudTest, Transaction013, TestSize.Level1) HWTEST_F(DistributeddbNbBatchCrudTest, Transaction014, TestSize.Level1) { std::vector entries1, entries2, entries3, entries4, entriesGot; - EntrySize entrySize = {KEY_SIX_BYTE, VALUE_ONE_HUNDRED_BYTE}; + EntrySize entrySize = {KEY_SIX_BYTE, FOUR_M_LONG_STRING - KEY_SIX_BYTE}; GenerateAppointPrefixAndSizeRecords(entries1, entrySize, ONE_HUNDRED_RECORDS, {'a'}, {'m'}); GenerateAppointPrefixAndSizeRecords(entries2, entrySize, RECORDS_SMALL_CNT, {'b'}, {'n'}); GenerateAppointPrefixAndSizeRecords(entries3, entrySize, THIRTYTWO_RECORDS, {'c'}, {'o'}); diff --git a/kv_store/frameworks/libs/distributeddb/test/moduletest/src/distributeddb_nb_local_batch_crud_test.cpp b/kv_store/frameworks/libs/distributeddb/test/moduletest/src/distributeddb_nb_local_batch_crud_test.cpp index 1eefce26..8ad5b634 100644 --- a/kv_store/frameworks/libs/distributeddb/test/moduletest/src/distributeddb_nb_local_batch_crud_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/moduletest/src/distributeddb_nb_local_batch_crud_test.cpp @@ -304,8 +304,8 @@ HWTEST_F(DistributeddbNbLocalBatchCrudTest, SimpleData006, TestSize.Level1) * @tc.steps: step1. call PutLocalBatch interface to insert 128 records to DB, and check the data from DB. * @tc.expected: step1. PutLocalBatch succeed and can find 129 records in DB. */ - vector entries1, entries2, gotValues; - vector allKeys1, allKeys2; + vector entries1, entries2, entries3, gotValues; + vector allKeys1, allKeys2, allKeys3; GenerateFixedRecords(entries1, allKeys1, BATCH_RECORDS, KEY_SIX_BYTE, VALUE_ONE_HUNDRED_BYTE); EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries1), OK); @@ -316,7 +316,7 @@ HWTEST_F(DistributeddbNbLocalBatchCrudTest, SimpleData006, TestSize.Level1) * @tc.steps: step2. call PutLocalBatch interface to insert 129 records to DB, and check the data from DB. * @tc.expected: step2. PutLocalBatch failed and can only find 129 records in DB. */ - GenerateFixedRecords(entries2, allKeys2, BATCH_RECORDS + 1, KEY_EIGHT_BYTE, VALUE_ONE_HUNDRED_BYTE); + GenerateFixedRecords(entries2, allKeys2, BATCH_RECORDS + 1, KEY_EIGHT_BYTE, FOUR_M_LONG_STRING - KEY_EIGHT_BYTE); EXPECT_EQ(g_nbLocalBatchDelegate->PutLocalBatch(entries2), INVALID_ARGS); EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), OK); EXPECT_EQ(entries1.size() + 1, gotValues.size()); @@ -325,8 +325,9 @@ HWTEST_F(DistributeddbNbLocalBatchCrudTest, SimpleData006, TestSize.Level1) * @tc.steps: step3. call DeleteLocalBatch interface to Delete 129 records from DB which is already in DB. * @tc.expected: step3. DeleteLocalBatch failed and can still find the 129 records which was find upstairs in db. */ - allKeys1.push_back(KEY_1); - EXPECT_EQ(g_nbLocalBatchDelegate->DeleteLocalBatch(allKeys1), INVALID_ARGS); + GenerateFixedRecords(entries3, allKeys3, BATCH_RECORDS, FOUR_M_LONG_STRING, VALUE_ONE_HUNDRED_BYTE); + allKeys3.push_back(KEY_1); + EXPECT_EQ(g_nbLocalBatchDelegate->DeleteLocalBatch(allKeys3), INVALID_ARGS); EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), OK); EXPECT_EQ(entries1.size() + 1, gotValues.size()); } @@ -346,7 +347,7 @@ HWTEST_F(DistributeddbNbLocalBatchCrudTest, SimpleData007, TestSize.Level3) * @tc.expected: step1. PutLocalBatch succeed. */ vector entries; - EntrySize entrySize = {KEY_ONE_K_BYTE, FOUR_M_LONG_STRING}; + EntrySize entrySize = {KEY_ONE_K_BYTE, FOUR_M_LONG_STRING - KEY_ONE_K_BYTE}; GenerateAppointPrefixAndSizeRecords(entries, entrySize, BATCH_RECORDS); std::condition_variable batchCondition; @@ -396,7 +397,7 @@ HWTEST_F(DistributeddbNbLocalBatchCrudTest, SimpleData008, TestSize.Level3) * @tc.expected: step1. PutLocalBatch succeed. */ vector entries; - EntrySize entrySize = {KEY_ONE_K_BYTE, FOUR_M_LONG_STRING}; + EntrySize entrySize = {KEY_ONE_K_BYTE, FOUR_M_LONG_STRING - KEY_ONE_K_BYTE}; GenerateAppointPrefixAndSizeRecords(entries, entrySize, BATCH_RECORDS); std::condition_variable batchCondition; @@ -595,7 +596,7 @@ HWTEST_F(DistributeddbNbLocalBatchCrudTest, Exception001, TestSize.Level1) * @tc.expected: step2. PutBatch succeed but PutLocalBatch will return OVER_MAX_LIMITS. */ vector entries1, entries2, gotValues; - EntrySize entrySize = {KEY_SIX_BYTE, ONE_K_LONG_STRING}; + EntrySize entrySize = {KEY_SIX_BYTE, FOUR_M_LONG_STRING - KEY_SIX_BYTE}; GenerateAppointPrefixAndSizeRecords(entries1, entrySize, BATCH_RECORDS); entries2.push_back(ENTRY_1); entries2.push_back(ENTRY_2); diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_data_compression_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_data_compression_test.cpp index e3754c65..1d48c7a6 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_data_compression_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_data_compression_test.cpp @@ -90,7 +90,7 @@ HWTEST_F(DistributedDBDataCompressionTest, DataCompression1, TestSize.Level1) * @tc.expected: step1. Compress successfully. Compressed data length is less than srcLen. */ #ifndef OMIT_ZLIB - const int origLen = sizeof(g_srcStr); + const int origLen = static_cast(sizeof(g_srcStr)); vector srcData(g_srcStr, g_srcStr + sizeof(g_srcStr)); vector compressedData; @@ -122,7 +122,7 @@ HWTEST_F(DistributedDBDataCompressionTest, DataCompression2, TestSize.Level1) * @tc.expected: step1. Compress successfully. Compressed data length is less than srcLen. */ #ifndef OMIT_ZLIB - const int origLen = sizeof(g_srcStr); + const int origLen = static_cast(sizeof(g_srcStr)); vector srcData(g_srcStr, g_srcStr + sizeof(g_srcStr)); vector compressedData; diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_data_generate_unit_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_data_generate_unit_test.cpp index 74c440cf..d0bce30f 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_data_generate_unit_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_data_generate_unit_test.cpp @@ -69,7 +69,7 @@ void GenerateRecords(int recordNum, std::vector &entries, std::vector(cntStr.length()); if (keySize <= len) { break; } diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_data_generate_unit_test.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_data_generate_unit_test.h index 42c82fcf..a4013052 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_data_generate_unit_test.h +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_data_generate_unit_test.h @@ -41,6 +41,9 @@ const std::string STORE_ID_8 = "distributed_db_test8"; constexpr int32_t INSTANCE_ID_1 = 1; constexpr int32_t INSTANCE_ID_2 = 2; +const std::string SUB_USER_1 = "subUser1"; +const std::string SUB_USER_2 = "subUser2"; + const int NUM_LENGTH = 10; const int LETTER_LENGTH = 52; const uint8_t KEY_NUM[NUM_LENGTH] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_json_precheck_unit_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_json_precheck_unit_test.cpp index ffae09ca..2182da8b 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_json_precheck_unit_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_json_precheck_unit_test.cpp @@ -102,7 +102,7 @@ HWTEST_F(DistributedDBJsonPrecheckUnitTest, ParseValidString001, TestSize.Level1 * @tc.expected: step1. return value = 12. */ int errCode = E_OK; - int stepOne = JsonObject::CalculateNestDepth(JSON_STRING1, errCode); + int stepOne = static_cast(JsonObject::CalculateNestDepth(JSON_STRING1, errCode)); EXPECT_TRUE(errCode == E_OK); EXPECT_TRUE(stepOne == STRING1_DEPTH); @@ -129,7 +129,7 @@ HWTEST_F(DistributedDBJsonPrecheckUnitTest, ParseValidString002, TestSize.Level1 * @tc.expected: step1. return value = 6. */ int errCode = E_OK; - int stepOne = JsonObject::CalculateNestDepth(JSON_STRING3, errCode); + int stepOne = static_cast(JsonObject::CalculateNestDepth(JSON_STRING3, errCode)); EXPECT_TRUE(errCode == E_OK); EXPECT_TRUE(stepOne == STRING3_DEPTH); @@ -192,7 +192,7 @@ HWTEST_F(DistributedDBJsonPrecheckUnitTest, ParseInvalidString003, TestSize.Leve * @tc.expected: step1. return value > 10. */ int errCode = E_OK; - int stepOne = JsonObject::CalculateNestDepth(JSON_STRING5, errCode); + int stepOne = static_cast(JsonObject::CalculateNestDepth(JSON_STRING5, errCode)); EXPECT_TRUE(errCode == E_OK); EXPECT_TRUE(stepOne > MAX_DEPTH_FOR_TEST); diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/evloop_timer_unit_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/evloop_timer_unit_test.cpp index c78a86b9..549298da 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/evloop_timer_unit_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/evloop_timer_unit_test.cpp @@ -416,7 +416,9 @@ HWTEST_F(DistributedDBEventLoopTimerTest, EventLoopTimerTest007, TestSize.Level2 } lastTime = TimerTester::GetCurrentTime(); int ret = timer->SetTimeout(counter * TIME_PIECE_1000); - EXPECT_EQ(ret, E_OK); + if (ret != -E_OBJ_IS_KILLED) { + EXPECT_EQ(ret, E_OK); + } return E_OK; }, nullptr); EXPECT_EQ(errCode, E_OK); diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/system_time.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/system_time.cpp index 01b4830d..6341af7b 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/system_time.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/system_time.cpp @@ -40,7 +40,7 @@ int GetCurrentSysTimeInMicrosecond(uint64_t &outTime) } outTime = static_cast(rawTime.tv_sec) * MULTIPLES_BETWEEN_SECONDS_AND_MICROSECONDS + static_cast(rawTime.tv_usec); - outTime = outTime + g_timeOffset.load(); + outTime = outTime + static_cast(g_timeOffset.load()); return 0; } #endif // DB_DEBUG_ENV diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_common.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_common.h index ecd04684..1aeeaf71 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_common.h +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_common.h @@ -101,7 +101,7 @@ public: DistributedDB::HostToNet(info.length); DistributedDB::HostToNet(info.version); for (uint8_t i = 0; i < BUFF_LEN; i++) { - info.userId[i] = localDbProperty_.userId[i]; + info.userId[i] = static_cast(localDbProperty_.userId[i]); } auto errCode = memcpy_s(data, totalLen, &info, sizeof(ExtendHeadInfo)); if (errCode != EOK) { diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_test.cpp index 512128b5..a1f514a6 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_test.cpp @@ -22,6 +22,7 @@ #include "distributeddb_tools_unit_test.h" #include "endian_convert.h" #include "log_print.h" +#include "runtime_config.h" #include "thread_pool_test_stub.h" #include "virtual_communicator_aggregator.h" @@ -937,6 +938,7 @@ HWTEST_F(DistributedDBCommunicatorTest, CommunicationOptimization001, TestSize.L * @tc.steps: step5. both notify * @tc.expected: step5. both has callback; */ + RuntimeConfig::NotifyDBInfos({ deviceB }, { dbInfo }); adapterA->NotifyDBInfos({ deviceB }, { dbInfo }); adapterB->NotifyDBInfos({ deviceA }, { dbInfo }); std::this_thread::sleep_for(std::chrono::seconds(1)); diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_reference_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_reference_test.cpp index b988832e..c0a36439 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_reference_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_reference_test.cpp @@ -15,7 +15,7 @@ #include -#include "cloud_db_types.h" +#include "cloud/cloud_db_types.h" #include "db_common.h" #include "db_constant.h" #include "distributeddb_data_generate_unit_test.h" 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 8f1b2657..54418f09 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 @@ -62,17 +62,21 @@ public: triggerTableData_.insert_or_assign(tableEntry.first, tableEntry.second); } triggeredCount_++; - std::unique_lock lock(g_mutex); + { + std::unique_lock lock(g_mutex); + g_alreadyNotify = true; + } g_cv.notify_one(); - g_alreadyNotify = true; } void ClientObserverFunc2(ClientChangedData &clientChangedData) { triggeredCount2_++; - std::unique_lock lock(g_mutex); + { + std::unique_lock lock(g_mutex); + g_alreadyNotify = true; + } g_cv.notify_one(); - g_alreadyNotify = true; } void CheckTriggerTableData(size_t dataSize, const std::string &tableName, ChangeProperties &properties, @@ -84,6 +88,20 @@ public: EXPECT_EQ(triggeredCount_, triggerCount); } + void WaitAndResetNotify() + { + std::unique_lock lock(g_mutex); + WaitAndResetNotifyWithLock(lock); + } + + void WaitAndResetNotifyWithLock(std::unique_lock &lock) + { + g_cv.wait(lock, []() { + return g_alreadyNotify; + }); + g_alreadyNotify = false; + } + std::set triggerTableNames_; std::map triggerTableData_; int triggeredCount_ = 0; @@ -589,11 +607,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest002, */ std::string sql = "insert into " + tableName + " VALUES(1, 'zhangsan'), (2, 'lisi'), (3, 'wangwu');"; EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); - std::unique_lock lock(g_mutex); - g_cv.wait(lock, []() { - return g_alreadyNotify; - }); - g_alreadyNotify = false; + WaitAndResetNotify(); std::atomic count = 0; // 0 is observer triggered counts CheckTriggerObserverTest002(tableName, count); @@ -603,10 +617,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest002, */ sql = "update " + tableName + " set name = 'lisi1' where id = 2;"; EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); - g_cv.wait(lock, []() { - return g_alreadyNotify; - }); - g_alreadyNotify = false; + WaitAndResetNotify(); CheckTriggerObserverTest002(tableName, count); /** @@ -615,10 +626,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest002, */ sql = "delete from " + tableName + " where id = 3;"; EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); - g_cv.wait(lock, []() { - return g_alreadyNotify; - }); - g_alreadyNotify = false; + WaitAndResetNotify(); CheckTriggerObserverTest002(tableName, count); /** @@ -631,10 +639,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest002, EXPECT_EQ(RegisterClientObserver(db, clientObserver2), OK); sql = "update " + tableName + " set name = 'lisi2' where id = 2;"; EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); - g_cv.wait(lock, []() { - return g_alreadyNotify; - }); - g_alreadyNotify = false; + WaitAndResetNotify(); EXPECT_EQ(triggeredCount_, 0); EXPECT_EQ(triggeredCount2_, 1); @@ -726,8 +731,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest004, return triggeredCount_ == dataCounts; }); EXPECT_EQ(isEqual, true); - - g_alreadyNotify = false; + WaitAndResetNotifyWithLock(lock); ASSERT_EQ(triggerTableData_.size(), 1u); EXPECT_EQ(triggerTableData_.begin()->first, tableName); EXPECT_EQ(triggeredCount_, dataCounts); @@ -743,7 +747,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest004, return triggeredCount_ == 1; }); EXPECT_EQ(isEqual, true); - g_alreadyNotify = false; + WaitAndResetNotifyWithLock(lock); EXPECT_EQ(triggeredCount_, 1); // 1 is trigger times, first delete then insert EXPECT_EQ(UnRegisterClientObserver(db), OK); EXPECT_EQ(sqlite3_close_v2(db), E_OK); @@ -788,11 +792,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest005, } sql = "commit;"; EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); - std::unique_lock lock(g_mutex); - g_cv.wait(lock, []() { - return g_alreadyNotify; - }); - g_alreadyNotify = false; + WaitAndResetNotify(); ASSERT_EQ(triggerTableData_.size(), 1u); EXPECT_EQ(triggerTableData_.begin()->first, tableName); EXPECT_EQ(triggeredCount_, 1); @@ -821,10 +821,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest005, triggeredCount_ = 0; sql = "insert or replace into " + tableName + " VALUES(1000, 'lisi');"; EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); - g_cv.wait(lock, []() { - return g_alreadyNotify; - }); - g_alreadyNotify = false; + WaitAndResetNotify(); EXPECT_EQ(triggeredCount_, 1); // 1 is trigger times, first delete then insert EXPECT_EQ(UnRegisterClientObserver(db), OK); EXPECT_EQ(sqlite3_close_v2(db), E_OK); @@ -863,11 +860,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest006, */ std::string sql = "insert into " + tableName1 + " VALUES(1, 'zhangsan'), (2, 'lisi'), (3, 'wangwu');"; EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); - std::unique_lock lock(g_mutex); - g_cv.wait(lock, []() { - return g_alreadyNotify; - }); - g_alreadyNotify = false; + WaitAndResetNotify(); ASSERT_EQ(triggerTableData_.size(), 1u); // 1 is table size EXPECT_EQ(triggerTableData_.begin()->first, tableName1); EXPECT_EQ(triggeredCount_, 1); // 1 is trigger count @@ -891,10 +884,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest006, EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK); sql = "insert into " + tableName1 + " VALUES(7, 'zhangjiu');"; EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); - g_cv.wait(lock, []() { - return g_alreadyNotify; - }); - g_alreadyNotify = false; + WaitAndResetNotify(); ASSERT_EQ(triggerTableData_.size(), 1u); // 1 is table size EXPECT_EQ(triggerTableData_.begin()->first, tableName1); EXPECT_EQ(triggeredCount_, 1); // 1 is trigger count @@ -1197,6 +1187,46 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, FfrtTest002, TestSize.Le ADAPTER_WAIT(h3); } +/** + * @tc.name: FfrtTest003 + * @tc.desc: Test ffrt concurrency + * @tc.type: FUNC + * @tc.require: + * @tc.author: + */ +HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, FfrtTest003, TestSize.Level0) +{ + size_t count = 0; + size_t num = 3000; + std::vector waitVec; + + /** + * @tc.steps:step1. submit increase task + * @tc.expected: step1. return ok. + */ + for (size_t j = 0; j < num; j++) { + TaskHandle h1 = ConcurrentAdapter::ScheduleTaskH([this, &count, num]() { + for (size_t i = 0; i < num; i++) { + count++; + } + }, nullptr, nullptr); + waitVec.push_back(h1); + } + for (const auto &item : waitVec) { + ADAPTER_WAIT(item); + } + + /** + * @tc.steps:step2. check count + * @tc.expected: step2. return ok. + */ +#ifdef USE_FFRT + EXPECT_NE(count, num * num); +#else + EXPECT_EQ(count, num * num); +#endif +} + /** * @tc.name: AbnormalDelegateTest001 * @tc.desc: Test delegate interface after delegate is closed @@ -1589,13 +1619,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, RegisterStoreObserverTes int dataCounts = 10; // 10 is count of insert options. int begin = 0; PrepareDataForStoreObserver(db, tableName, begin, dataCounts); - { - std::unique_lock lock(g_mutex); - g_cv.wait(lock, []() { - return g_alreadyNotify; - }); - g_alreadyNotify = false; - } + WaitAndResetNotify(); EXPECT_EQ(g_changedData[0].tableName, "primary_test"); CheckChangedData(0); EXPECT_EQ(g_changedData[1].tableName, "no_primary_test"); @@ -1646,13 +1670,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, RegisterStoreObserverTes int dataCounts = 10; // 10 is count of insert options. int begin = 0; PrepareDataForStoreObserver(db, tableName, begin, dataCounts); - { - std::unique_lock lock(g_mutex); - g_cv.wait(lock, []() { - return g_alreadyNotify; - }); - g_alreadyNotify = false; - } + WaitAndResetNotify(); EXPECT_EQ(g_changedData[0].tableName, "primary_test"); CheckChangedData(0); EXPECT_EQ(g_changedData[1].tableName, "no_primary_test"); diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_relational_remove_device_data_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_relational_remove_device_data_test.cpp index 94d38066..ab14085e 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_relational_remove_device_data_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_relational_remove_device_data_test.cpp @@ -294,8 +294,8 @@ namespace { void CheckCloudTotalCount(const std::vector &tableNames, std::vector expectCounts) { VBucket extend; - extend[CloudDbConstant::CURSOR_FIELD] = std::to_string(0); for (size_t i = 0; i < tableNames.size(); ++i) { + extend[CloudDbConstant::CURSOR_FIELD] = std::to_string(0); int64_t realCount = 0; std::vector data; g_virtualCloudDb->Query(tableNames[i], extend, data); @@ -693,6 +693,18 @@ static void InitGetCloudSyncTaskCountTest001(sqlite3 *&db) InsertUserTableRecord(db, 0, localCount, paddingSize, false); InsertCloudTableRecord(0, cloudCount, paddingSize, false); } + +static CloudSyncOption GetSyncOption() +{ + CloudSyncOption option; + option.devices = {DEVICE_CLOUD}; + std::vector pk = {"test"}; + option.query = Query::Select().From(g_tableName1).In("name", pk); + option.priorityTask = true; + option.waitTime = g_syncWaitTime; + return option; +} + /* * @tc.name: GetCloudSyncTaskCountTest001 * @tc.desc: Test FLAG_ONLY mode of RemoveDeviceData concurrently with Sync @@ -741,7 +753,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, GetCloudSyn } cv2.notify_one(); }; - ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_MERGE, query, callback2, g_syncWaitTime), DBStatus::OK); + ASSERT_EQ(g_delegate->Sync(GetSyncOption(), callback2), DBStatus::OK); /** * @tc.steps: step3. Call Get Cloud Sync Task Count * @tc.expected: OK. @@ -1034,5 +1046,45 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudD CheckLocalLogCount(db, { g_tableName1 }, { deleteCount }); CloseDb(); } + +/* + * @tc.name: CleanCloudDataTest011 + * @tc.desc: Test if the version in the log table has been cleared after RemoveDeviceData. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liaoyonghuang + */ +HWTEST_F(DistributedDBCloudInterfacesRelationalRemoveDeviceDataTest, CleanCloudDataTest011, TestSize.Level0) +{ + /** + * @tc.steps: step1. make data: 10 records on local + */ + int64_t paddingSize = 10; + int localCount = 10; + InsertUserTableRecord(db, 0, localCount, paddingSize, false); + std::string device; + /** + * @tc.steps: step2. call Sync with cloud merge strategy, and after that, local will has 10 records. + */ + CloudDBSyncUtilsTest::callSync(g_tables, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, g_delegate); + LOGW("check 10-10"); + CheckCloudTotalCount(g_tables, {10, 10}); // 10 is cloud data num in table2 + /** + * @tc.steps: step3. remove device data + * @tc.expected: OK. + */ + ASSERT_EQ(g_delegate->RemoveDeviceData(device, DistributedDB::FLAG_AND_DATA), DBStatus::OK); + /** + * @tc.steps: step4. Check if the version in the log table has been cleared. + * @tc.expected: OK. + */ + for (auto tableName : g_tables) { + std::string sql = "select count(*) from " + DBCommon::GetLogTableName(tableName) + + " where ((flag & 0x08 != 0) or cloud_gid is null or cloud_gid == '') and version != '';"; + EXPECT_EQ(sqlite3_exec(db, sql.c_str(), QueryCountCallback, + reinterpret_cast(0), nullptr), SQLITE_OK); + } + CloseDb(); +} } #endif // RELATIONAL_STORE \ 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 44b32381..9518d625 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 @@ -22,6 +22,7 @@ #include "db_constant.h" #include "distributeddb_data_generate_unit_test.h" #include "distributeddb_tools_unit_test.h" +#include "relational_store_client.h" #include "relational_store_manager.h" #include "runtime_config.h" #include "time_helper.h" @@ -1385,6 +1386,9 @@ namespace { sqlite3_stmt *stmt = nullptr; ASSERT_EQ(SQLiteUtils::GetStatement(db_, sql, stmt), E_OK); ASSERT_EQ(SQLiteUtils::StepWithRetry(stmt), SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)); + int ret = E_OK; + SQLiteUtils::ResetStatement(stmt, true, ret); + ASSERT_EQ(ret, E_OK); } /** @@ -1428,6 +1432,9 @@ namespace { sqlite3_stmt *stmt = nullptr; ASSERT_EQ(SQLiteUtils::GetStatement(db_, sql, stmt), E_OK); ASSERT_EQ(SQLiteUtils::StepWithRetry(stmt), SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)); + int ret = E_OK; + SQLiteUtils::ResetStatement(stmt, true, ret); + ASSERT_EQ(ret, E_OK); /** * @tc.steps:step3. re-SetCloudDbSchema and set sharedtable @@ -1798,4 +1805,52 @@ namespace { EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, reinterpret_cast(cloudCount), nullptr), SQLITE_OK); } + + /** + * @tc.name: SharedTableSync013 + * @tc.desc: Test the sharing_resource after data deleted + * @tc.type: FUNC + * @tc.require: + * @tc.author: bty + */ + HWTEST_F(DistributedDBCloudInterfacesSetCloudSchemaTest, SharedTableSync013, TestSize.Level0) + { + /** + * @tc.steps:step1. init cloud data and sync + * @tc.expected: step1. return OK + */ + InitCloudEnv(); + forkInsertFunc_ = InsertSharingUri; + const std::vector tables = { g_tableName2, g_sharedTableName1 }; + int cloudCount = 10; + InsertCloudTableRecord(0, cloudCount, false); + InsertCloudTableRecord(0, cloudCount); + Query query = Query::Select().FromTable(tables); + BlockSync(query, g_delegate, DBStatus::OK); + forkInsertFunc_ = nullptr; + + /** + * @tc.steps:step2. logic delete cloud data and sync, check sharing_resource + * @tc.expected: step2. return OK + */ + bool logicDelete = true; + auto data = static_cast(&logicDelete); + EXPECT_EQ(g_delegate->Pragma(LOGIC_DELETE_SYNC_DATA, data), OK); + DeleteCloudTableRecord(0, cloudCount, false); + DeleteCloudTableRecord(cloudCount, cloudCount); + BlockSync(query, g_delegate, DBStatus::OK); + std::string sql = "SELECT COUNT(*) FROM " + DBCommon::GetLogTableName(g_tableName2) + + " where sharing_resource!=''"; + EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, + reinterpret_cast(cloudCount), nullptr), SQLITE_OK); + + /** + * @tc.steps:step3. drop logic data, check sharing_resource + * @tc.expected: step3. return OK + */ + EXPECT_EQ(DropLogicDeletedData(db_, g_tableName2, 0u), OK); + sql = "SELECT COUNT(*) FROM " + DBCommon::GetLogTableName(g_tableName2) + " where sharing_resource=''"; + EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, + reinterpret_cast(cloudCount), nullptr), SQLITE_OK); + } } // namespace \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_data_operation_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_data_operation_test.cpp index 67504742..f6d10ef0 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_data_operation_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_data_operation_test.cpp @@ -2381,7 +2381,7 @@ HWTEST_F(DistributedDBInterfacesDataOperationTest, WriteTimeSort005, TestSize.Le EXPECT_EQ(g_kvNbDelegatePtrForQuery->GetEntries( Query::Select().InKeys(keys).OrderByWriteTime(true).Limit(limitNum, 0), resultSet2), OK); ASSERT_NE(resultSet2, nullptr); - int expectedSize = (keys.size() >= limitNum) ? limitNum : keys.size(); + int expectedSize = (keys.size() >= limitNum) ? static_cast(limitNum) : static_cast(keys.size()); ASSERT_EQ(resultSet2->GetCount(), static_cast(expectedSize)); CheckResultSize(resultSet2, expectedKeys, expectedSize); g_kvNbDelegatePtrForQuery->CloseResultSet(resultSet2); diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_data_value_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_data_value_test.cpp index 1f017c95..aead282f 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_data_value_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_data_value_test.cpp @@ -167,7 +167,7 @@ HWTEST_F(DistributedDBInterfacesDataValueTest, DataValueCheck002, TestSize.Level DataValue dataValue; for (uint32_t i = 0; i < g_checkFuncList.size(); i++) { uint32_t index = static_cast((lastWriteIndex + i + 1) % - static_cast(g_checkFuncList.size())); + static_cast(g_checkFuncList.size())); g_checkFuncList[index](dataValue); } } diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_local_batch_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_local_batch_test.cpp index b4643a59..2e646938 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_local_batch_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_local_batch_test.cpp @@ -440,187 +440,6 @@ HWTEST_F(DistributedDBInterfacesNBDelegateLocalBatchTest, SingleVerPutLocalBatch g_kvNbDelegatePtr = nullptr; } -/** - * @tc.name: SingleVerPutLocalBatch005 - * @tc.desc: Check for legal parameters that the sum size of all entries is smaller than 512M. - * @tc.type: FUNC - * @tc.require: - * @tc.author: mazhao - */ -HWTEST_F(DistributedDBInterfacesNBDelegateLocalBatchTest, SingleVerPutLocalBatch005, TestSize.Level1) -{ - /** - * @tc.steps: step1. - * Create and construct two sets of vector , each set of two data contains records: - */ - Key legalKey; - DistributedDBToolsUnitTest::GetRandomKeyValue(legalKey, DBConstant::MAX_KEY_SIZE); // 1K - Value legalValue; - DistributedDBToolsUnitTest::GetRandomKeyValue(legalValue, DBConstant::MAX_VALUE_SIZE); // 4M - Value emptyValue; // 0k - vector entrysKeyLegal; // size is 512M - 1kB - for (int i = 0; i < 524287; i++) { // 524287 * legalKey is equal to 512M - 1KB. - entrysKeyLegal.push_back({legalKey, emptyValue}); - } - - vector entrysMixLegal; // size is 511M + 511KB < 512M - for (int i = 0; i < 127; i++) { // 127 * (legalValue + legalKey) is equal to 508M + 127KB < 512M. - entrysMixLegal.push_back({legalKey, legalValue}); - } - - const KvStoreNbDelegate::Option option = {true, false}; - g_mgr.SetKvStoreConfig(g_config); - g_mgr.GetKvStore("SingleVerPutLocalBatch005", option, g_kvNbDelegateCallback); - ASSERT_TRUE(g_kvNbDelegatePtr != nullptr); - EXPECT_TRUE(g_kvDelegateStatus == OK); - /** - * @tc.steps: step2. PutBatch operates on two sets of data. - * @tc.expected: step2. two operations return OK. - */ - EXPECT_EQ(g_kvNbDelegatePtr->PutLocalBatch(entrysKeyLegal), OK); - EXPECT_EQ(g_kvNbDelegatePtr->PutLocalBatch(entrysMixLegal), OK); - - EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK); - EXPECT_EQ(g_mgr.DeleteKvStore("SingleVerPutLocalBatch005"), OK); - g_kvNbDelegatePtr = nullptr; -} - -/** - * @tc.name: SingleVerPutLocalBatch006 - * @tc.desc: Check for legal parameters that the sum size of all entries is equal to 512M. - * @tc.type: FUNC - * @tc.require: - * @tc.author: mazhao - */ -HWTEST_F(DistributedDBInterfacesNBDelegateLocalBatchTest, SingleVerPutLocalBatch006, TestSize.Level1) -{ - /** - * @tc.steps: step1. - * Create and construct two sets of vector , each set of two data contains records: - */ - Key legalKey; - DistributedDBToolsUnitTest::GetRandomKeyValue(legalKey, DBConstant::MAX_KEY_SIZE); // 1K - Value legalValue; - DistributedDBToolsUnitTest::GetRandomKeyValue(legalValue, DBConstant::MAX_VALUE_SIZE); // 4M - Value emptyValue; // 0k - - vector entrysKeyLegal; // size is 512M - for (int i = 0; i < 524288; i++) { // 524288 * legalKey is equal to 512M. - entrysKeyLegal.push_back({legalKey, emptyValue}); - } - - vector entrysMixLegal; // size is 512M - for (int i = 0; i < 127; i++) { // 127 * (legalValue + legalKey) is equal to 508M + 127KB < 512M. - entrysMixLegal.push_back({legalKey, legalValue}); - } - for (int i = 0; i < 3969; i++) { // 3969 * legalKey is equal to 3969KB. - entrysMixLegal.push_back({legalKey, emptyValue}); - } - - const KvStoreNbDelegate::Option option = {true, false}; - g_mgr.SetKvStoreConfig(g_config); - g_mgr.GetKvStore("SingleVerPutLocalBatch006", option, g_kvNbDelegateCallback); - ASSERT_TRUE(g_kvNbDelegatePtr != nullptr); - EXPECT_TRUE(g_kvDelegateStatus == OK); - /** - * @tc.steps: step2. PutBatch operates on two sets of data. - * @tc.expected: step2. two operations return OK. - */ - EXPECT_EQ(g_kvNbDelegatePtr->PutLocalBatch(entrysKeyLegal), OK); - EXPECT_EQ(g_kvNbDelegatePtr->PutLocalBatch(entrysMixLegal), OK); - - EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK); - EXPECT_EQ(g_mgr.DeleteKvStore("SingleVerPutLocalBatch006"), OK); - g_kvNbDelegatePtr = nullptr; -} - -/** - * @tc.name: SingleVerPutLocalBatch007 - * @tc.desc: Check for illegal parameters that the sum size of all entries is larger to 512M. - * @tc.type: FUNC - * @tc.require: - * @tc.author: mazhao - */ -HWTEST_F(DistributedDBInterfacesNBDelegateLocalBatchTest, SingleVerPutLocalBatch007, TestSize.Level1) -{ - /** - * @tc.steps: step1. - * Create and construct two sets of vector , each set of two data contains records: - */ - Key legalKey; - DistributedDBToolsUnitTest::GetRandomKeyValue(legalKey, DBConstant::MAX_KEY_SIZE); // 1K - Value legalValue; - DistributedDBToolsUnitTest::GetRandomKeyValue(legalValue, DBConstant::MAX_VALUE_SIZE); // 4M - Value emptyValue; // 0k - - vector entrysKeyIllegal; // size is 512M + 1KB - for (int i = 0; i < 524289; i++) { // 524289 * legalKey is equal to 512M + 1KB. - entrysKeyIllegal.push_back({legalKey, emptyValue}); - } - - vector entrysMixIllegal; // size is 512M + 1KB - for (int i = 0; i < 127; i++) { // 127 * (legalValue + legalKey) is equal to 508M + 127KB < 512M. - entrysMixIllegal.push_back({legalKey, legalValue}); - } - for (int i = 0; i < 3970; i++) { // 3970 * legalKey is equal to 3970KB. - entrysMixIllegal.push_back({legalKey, emptyValue}); - } - - const KvStoreNbDelegate::Option option = {true, false}; - g_mgr.SetKvStoreConfig(g_config); - g_mgr.GetKvStore("SingleVerPutLocalBatch007", option, g_kvNbDelegateCallback); - ASSERT_TRUE(g_kvNbDelegatePtr != nullptr); - EXPECT_TRUE(g_kvDelegateStatus == OK); - /** - * @tc.steps: step2. PutBatch operates on two sets of data. - * @tc.expected: step2. two operations return INVALID_ARGS. - */ - EXPECT_EQ(g_kvNbDelegatePtr->PutLocalBatch(entrysKeyIllegal), INVALID_ARGS); - EXPECT_EQ(g_kvNbDelegatePtr->PutLocalBatch(entrysMixIllegal), INVALID_ARGS); - - EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK); - EXPECT_EQ(g_mgr.DeleteKvStore("SingleVerPutLocalBatch007"), OK); - g_kvNbDelegatePtr = nullptr; -} - -/** - * @tc.name: SingleVerPutLocalBatch008 - * @tc.desc: Check for illegal parameters that the sum size of all entries excced uint32_t limit. - * @tc.type: FUNC - * @tc.require: - * @tc.author: mazhao - */ -HWTEST_F(DistributedDBInterfacesNBDelegateLocalBatchTest, SingleVerPutLocalBatch008, TestSize.Level1) -{ - /** - * @tc.steps: step1. - * Create and construct two sets of vector , each set of two data contains records: - */ - Key legalKey; - DistributedDBToolsUnitTest::GetRandomKeyValue(legalKey, DBConstant::MAX_KEY_SIZE); // 1K - Value emptyValue; // 0k - - vector entrysIllegal; // size excced to the limit of uint32_t - for (int i = 0; i < 4194305; i++) { // 4194305 * legalKey is excced to the limit of uint32_t. - entrysIllegal.push_back({legalKey, emptyValue}); - } - - const KvStoreNbDelegate::Option option = {true, false}; - g_mgr.SetKvStoreConfig(g_config); - g_mgr.GetKvStore("SingleVerPutLocalBatch008", option, g_kvNbDelegateCallback); - ASSERT_TRUE(g_kvNbDelegatePtr != nullptr); - EXPECT_TRUE(g_kvDelegateStatus == OK); - /** - * @tc.steps: step2. PutBatch operates on two sets of data. - * @tc.expected: step2. two operations return INVALID_ARGS. - */ - EXPECT_EQ(g_kvNbDelegatePtr->PutLocalBatch(entrysIllegal), INVALID_ARGS); - - EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK); - EXPECT_EQ(g_mgr.DeleteKvStore("SingleVerPutLocalBatch008"), OK); - g_kvNbDelegatePtr = nullptr; -} - /** * @tc.name: SingleVerDeleteLocalBatch001 * @tc.desc: Check for illegal parameters. @@ -792,150 +611,6 @@ HWTEST_F(DistributedDBInterfacesNBDelegateLocalBatchTest, SingleVerDeleteLocalBa g_kvNbDelegatePtr = nullptr; } -/** - * @tc.name: SingleVerDeleteLocalBatch003 - * @tc.desc: Check for legal parameters that the sum size of all Keys is smaller than 512M. - * @tc.type: FUNC - * @tc.require: - * @tc.author: mazhao - */ -HWTEST_F(DistributedDBInterfacesNBDelegateLocalBatchTest, SingleVerDeleteLocalBatch003, TestSize.Level1) -{ - /** - * @tc.steps: step1. - * Create and construct one sets of vector : - */ - Key legalKey; - DistributedDBToolsUnitTest::GetRandomKeyValue(legalKey, DBConstant::MAX_KEY_SIZE); // 1K - vector keysLegal; // size is 512M - 1kB - for (int i = 0; i < 524287; i++) { // 524287 * legalKey is equal to 512M - 1KB. - keysLegal.push_back(legalKey); - } - - const KvStoreNbDelegate::Option option = {true, false}; - g_mgr.SetKvStoreConfig(g_config); - g_mgr.GetKvStore("SingleVerDeleteLocalBatch003", option, g_kvNbDelegateCallback); - ASSERT_TRUE(g_kvNbDelegatePtr != nullptr); - EXPECT_TRUE(g_kvDelegateStatus == OK); - /** - * @tc.steps: step2. DeleteBatch operates on sets of data. - * @tc.expected: step2. return OK. - */ - EXPECT_EQ(g_kvNbDelegatePtr->DeleteLocalBatch(keysLegal), OK); - - EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK); - EXPECT_EQ(g_mgr.DeleteKvStore("SingleVerDeleteLocalBatch003"), OK); - g_kvNbDelegatePtr = nullptr; -} - -/** - * @tc.name: SingleVerDeleteLocalBatch004 - * @tc.desc: Check for legal parameters that the sum size of all entries is equal to 512M. - * @tc.type: FUNC - * @tc.require: - * @tc.author: mazhao - */ -HWTEST_F(DistributedDBInterfacesNBDelegateLocalBatchTest, SingleVerDeleteLocalBatch004, TestSize.Level1) -{ - /** - * @tc.steps: step1. - * Create and construct one sets of vector : - */ - Key legalKey; - DistributedDBToolsUnitTest::GetRandomKeyValue(legalKey, DBConstant::MAX_KEY_SIZE); // 1K - vector keysLegal; // size is 512M - for (int i = 0; i < 524288; i++) { // 524288 * legalKey is equal to 512M. - keysLegal.push_back(legalKey); - } - - const KvStoreNbDelegate::Option option = {true, false}; - g_mgr.SetKvStoreConfig(g_config); - g_mgr.GetKvStore("SingleVerDeleteLocalBatch004", option, g_kvNbDelegateCallback); - ASSERT_TRUE(g_kvNbDelegatePtr != nullptr); - EXPECT_TRUE(g_kvDelegateStatus == OK); - /** - * @tc.steps: step2. DeleteBatch operates on sets of data. - * @tc.expected: step2. return OK. - */ - EXPECT_EQ(g_kvNbDelegatePtr->DeleteBatch(keysLegal), OK); - - EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK); - EXPECT_EQ(g_mgr.DeleteKvStore("SingleVerDeleteLocalBatch004"), OK); - g_kvNbDelegatePtr = nullptr; -} - -/** - * @tc.name: SingleVerDeleteLocalBatch005 - * @tc.desc: Check for illegal parameters that the sum size of all entries is larger to 512M. - * @tc.type: FUNC - * @tc.require: - * @tc.author: mazhao - */ -HWTEST_F(DistributedDBInterfacesNBDelegateLocalBatchTest, SingleVerDeleteLocalBatch005, TestSize.Level1) -{ - /** - * @tc.steps: step1. - * Create and construct one sets of vector : - */ - Key legalKey; - DistributedDBToolsUnitTest::GetRandomKeyValue(legalKey, DBConstant::MAX_KEY_SIZE); // 1K - vector keysIllLegal; // size is 512M + 1kB - for (int i = 0; i < 524289; i++) { // 524289 * legalKey is equal to 512M + 1KB. - keysIllLegal.push_back(legalKey); - } - - const KvStoreNbDelegate::Option option = {true, false}; - g_mgr.SetKvStoreConfig(g_config); - g_mgr.GetKvStore("SingleVerDeleteLocalBatch005", option, g_kvNbDelegateCallback); - ASSERT_TRUE(g_kvNbDelegatePtr != nullptr); - EXPECT_TRUE(g_kvDelegateStatus == OK); - /** - * @tc.steps: step2. DeleteLocalBatch operates on sets of data. - * @tc.expected: step2. return INVALID_ARGS. - */ - EXPECT_EQ(g_kvNbDelegatePtr->DeleteLocalBatch(keysIllLegal), INVALID_ARGS); - - EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK); - EXPECT_EQ(g_mgr.DeleteKvStore("SingleVerDeleteLocalBatch005"), OK); - g_kvNbDelegatePtr = nullptr; -} - -/** - * @tc.name: SingleVerDeleteLocalBatch006 - * @tc.desc: Check for illegal parameters that the sum size of all entries excced uint32_t limit. - * @tc.type: FUNC - * @tc.require: - * @tc.author: mazhao - */ -HWTEST_F(DistributedDBInterfacesNBDelegateLocalBatchTest, SingleVerDeleteLocalBatch006, TestSize.Level1) -{ - /** - * @tc.steps: step1. - * Create and construct one sets of vector : - */ - Key legalKey; - DistributedDBToolsUnitTest::GetRandomKeyValue(legalKey, DBConstant::MAX_KEY_SIZE); // 1K - vector keysIllLegal; // size excced to the limit of uint32_t - for (int i = 0; i < 4194305; i++) { // 4194305 * legalKey is excced to the limit of uint32_t. - keysIllLegal.push_back(legalKey); - } - - const KvStoreNbDelegate::Option option = {true, false}; - g_mgr.SetKvStoreConfig(g_config); - g_mgr.GetKvStore("SingleVerDeleteLocalBatch006", option, g_kvNbDelegateCallback); - ASSERT_TRUE(g_kvNbDelegatePtr != nullptr); - EXPECT_TRUE(g_kvDelegateStatus == OK); - /** - * @tc.steps: step2. DeleteLocalBatch operates on sets of data. - * @tc.expected: step2. return INVALID_ARGS. - */ - EXPECT_EQ(g_kvNbDelegatePtr->DeleteLocalBatch(keysIllLegal), INVALID_ARGS); - - EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK); - EXPECT_EQ(g_mgr.DeleteKvStore("SingleVerDeleteLocalBatch006"), OK); - g_kvNbDelegatePtr = nullptr; -} - /** * @tc.name: SingleVerPutLocalBatchObserver001 * @tc.desc: Test the observer function of PutLocalBatch() interface. diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_test.cpp index cb5594fd..2423057c 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_test.cpp @@ -1006,187 +1006,6 @@ static void CreatEntrys(int recordSize, vector &keys, vector &values } } -/** - * @tc.name: SingleVerPutBatch005 - * @tc.desc: Check for legal parameters that the sum size of all entries is smaller than 512M. - * @tc.type: FUNC - * @tc.require: - * @tc.author: mazhao - */ -HWTEST_F(DistributedDBInterfacesNBDelegateTest, SingleVerPutBatch005, TestSize.Level1) -{ - /** - * @tc.steps: step1. - * Create and construct two sets of vector , each set of two data contains records: - */ - Key legalKey; - DistributedDBToolsUnitTest::GetRandomKeyValue(legalKey, DBConstant::MAX_KEY_SIZE); // 1K - Value legalValue; - DistributedDBToolsUnitTest::GetRandomKeyValue(legalValue, DBConstant::MAX_VALUE_SIZE); // 4M - Value emptyValue; // 0k - vector entrysKeyLegal; // size is 512M - 1kB - for (int i = 0; i < 524287; i++) { // 524287 * legalKey is equal to 512M - 1KB. - entrysKeyLegal.push_back({legalKey, emptyValue}); - } - - vector entrysMixLegal; // size is 511M + 511KB < 512M - for (int i = 0; i < 127; i++) { // 127 * (legalValue + legalKey) is equal to 508M + 127KB < 512M. - entrysMixLegal.push_back({legalKey, legalValue}); - } - - const KvStoreNbDelegate::Option option = {true, false}; - g_mgr.SetKvStoreConfig(g_config); - g_mgr.GetKvStore("distributed_SingleVerPutBatch_005", option, g_kvNbDelegateCallback); - ASSERT_TRUE(g_kvNbDelegatePtr != nullptr); - EXPECT_TRUE(g_kvDelegateStatus == OK); - /** - * @tc.steps: step2. PutBatch operates on two sets of data. - * @tc.expected: step2. two operations return OK. - */ - EXPECT_EQ(g_kvNbDelegatePtr->PutBatch(entrysKeyLegal), OK); - EXPECT_EQ(g_kvNbDelegatePtr->PutBatch(entrysMixLegal), OK); - - EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK); - EXPECT_EQ(g_mgr.DeleteKvStore("distributed_SingleVerPutBatch_005"), OK); - g_kvNbDelegatePtr = nullptr; -} - -/** - * @tc.name: SingleVerPutBatch006 - * @tc.desc: Check for legal parameters that the sum size of all entries is equal to 512M. - * @tc.type: FUNC - * @tc.require: - * @tc.author: mazhao - */ -HWTEST_F(DistributedDBInterfacesNBDelegateTest, SingleVerPutBatch006, TestSize.Level1) -{ - /** - * @tc.steps: step1. - * Create and construct two sets of vector , each set of two data contains records: - */ - Key legalKey; - DistributedDBToolsUnitTest::GetRandomKeyValue(legalKey, DBConstant::MAX_KEY_SIZE); // 1K - Value legalValue; - DistributedDBToolsUnitTest::GetRandomKeyValue(legalValue, DBConstant::MAX_VALUE_SIZE); // 4M - Value emptyValue; // 0k - - vector entrysKeyLegal; // size is 512M - for (int i = 0; i < 524288; i++) { // 524288 * legalKey is equal to 512M. - entrysKeyLegal.push_back({legalKey, emptyValue}); - } - - vector entrysMixLegal; // size is 512M - for (int i = 0; i < 127; i++) { // 127 * (legalValue + legalKey) is equal to 508M + 127KB < 512M. - entrysMixLegal.push_back({legalKey, legalValue}); - } - for (int i = 0; i < 3969; i++) { // 3969 * legalKey is equal to 3969KB. - entrysMixLegal.push_back({legalKey, emptyValue}); - } - - const KvStoreNbDelegate::Option option = {true, false}; - g_mgr.SetKvStoreConfig(g_config); - g_mgr.GetKvStore("distributed_SingleVerPutBatch_006", option, g_kvNbDelegateCallback); - ASSERT_TRUE(g_kvNbDelegatePtr != nullptr); - EXPECT_TRUE(g_kvDelegateStatus == OK); - /** - * @tc.steps: step2. PutBatch operates on two sets of data. - * @tc.expected: step2. two operations return OK. - */ - EXPECT_EQ(g_kvNbDelegatePtr->PutBatch(entrysKeyLegal), OK); - EXPECT_EQ(g_kvNbDelegatePtr->PutBatch(entrysMixLegal), OK); - - EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK); - EXPECT_EQ(g_mgr.DeleteKvStore("distributed_SingleVerPutBatch_006"), OK); - g_kvNbDelegatePtr = nullptr; -} - -/** - * @tc.name: SingleVerPutBatch007 - * @tc.desc: Check for illegal parameters that the sum size of all entries is larger to 512M. - * @tc.type: FUNC - * @tc.require: - * @tc.author: mazhao - */ -HWTEST_F(DistributedDBInterfacesNBDelegateTest, SingleVerPutBatch007, TestSize.Level1) -{ - /** - * @tc.steps: step1. - * Create and construct two sets of vector , each set of two data contains records: - */ - Key legalKey; - DistributedDBToolsUnitTest::GetRandomKeyValue(legalKey, DBConstant::MAX_KEY_SIZE); // 1K - Value legalValue; - DistributedDBToolsUnitTest::GetRandomKeyValue(legalValue, DBConstant::MAX_VALUE_SIZE); // 4M - Value emptyValue; // 0k - - vector entrysKeyIllegal; // size is 512M + 1KB - for (int i = 0; i < 524289; i++) { // 524289 * legalKey is equal to 512M + 1KB. - entrysKeyIllegal.push_back({legalKey, emptyValue}); - } - - vector entrysMixIllegal; // size is 512M + 1KB - for (int i = 0; i < 127; i++) { // 127 * (legalValue + legalKey) is equal to 508M + 127KB < 512M. - entrysMixIllegal.push_back({legalKey, legalValue}); - } - for (int i = 0; i < 3970; i++) { // 3970 * legalKey is equal to 3970KB. - entrysMixIllegal.push_back({legalKey, emptyValue}); - } - - const KvStoreNbDelegate::Option option = {true, false}; - g_mgr.SetKvStoreConfig(g_config); - g_mgr.GetKvStore("distributed_SingleVerPutBatch_007", option, g_kvNbDelegateCallback); - ASSERT_TRUE(g_kvNbDelegatePtr != nullptr); - EXPECT_TRUE(g_kvDelegateStatus == OK); - /** - * @tc.steps: step2. PutBatch operates on two sets of data. - * @tc.expected: step2. two operations return INVALID_ARGS. - */ - EXPECT_EQ(g_kvNbDelegatePtr->PutBatch(entrysKeyIllegal), INVALID_ARGS); - EXPECT_EQ(g_kvNbDelegatePtr->PutBatch(entrysMixIllegal), INVALID_ARGS); - - EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK); - EXPECT_EQ(g_mgr.DeleteKvStore("distributed_SingleVerPutBatch_007"), OK); - g_kvNbDelegatePtr = nullptr; -} - -/** - * @tc.name: SingleVerPutBatch008 - * @tc.desc: Check for illegal parameters that the sum size of all entries excced uint32_t limit. - * @tc.type: FUNC - * @tc.require: - * @tc.author: mazhao - */ -HWTEST_F(DistributedDBInterfacesNBDelegateTest, SingleVerPutBatch008, TestSize.Level1) -{ - /** - * @tc.steps: step1. - * Create and construct two sets of vector , each set of two data contains records: - */ - Key legalKey; - DistributedDBToolsUnitTest::GetRandomKeyValue(legalKey, DBConstant::MAX_KEY_SIZE); // 1K - Value emptyValue; // 0k - - vector entrysIllegal; // size excced to the limit of uint32_t - for (int i = 0; i < 4194305; i++) { // 4194305 * legalKey is excced to the limit of uint32_t. - entrysIllegal.push_back({legalKey, emptyValue}); - } - - const KvStoreNbDelegate::Option option = {true, false}; - g_mgr.SetKvStoreConfig(g_config); - g_mgr.GetKvStore("SingleVerPutBatch008", option, g_kvNbDelegateCallback); - ASSERT_TRUE(g_kvNbDelegatePtr != nullptr); - EXPECT_TRUE(g_kvDelegateStatus == OK); - /** - * @tc.steps: step2. PutBatch operates on two sets of data. - * @tc.expected: step2. two operations return INVALID_ARGS. - */ - EXPECT_EQ(g_kvNbDelegatePtr->PutBatch(entrysIllegal), INVALID_ARGS); - - EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK); - EXPECT_EQ(g_mgr.DeleteKvStore("SingleVerPutBatch008"), OK); - g_kvNbDelegatePtr = nullptr; -} - /** * @tc.name: SingleVerDeleteBatch001 * @tc.desc: Check for illegal parameters. @@ -1361,150 +1180,6 @@ HWTEST_F(DistributedDBInterfacesNBDelegateTest, SingleVerDeleteBatch002, TestSiz g_kvNbDelegatePtr = nullptr; } -/** - * @tc.name: SingleVerDeleteBatch003 - * @tc.desc: Check for legal parameters that the sum size of all Keys is smaller than 512M. - * @tc.type: FUNC - * @tc.require: - * @tc.author: mazhao - */ -HWTEST_F(DistributedDBInterfacesNBDelegateTest, SingleVerDeleteBatch003, TestSize.Level1) -{ - /** - * @tc.steps: step1. - * Create and construct one sets of vector : - */ - Key legalKey; - DistributedDBToolsUnitTest::GetRandomKeyValue(legalKey, DBConstant::MAX_KEY_SIZE); // 1K - vector keysLegal; // size is 512M - 1kB - for (int i = 0; i < 524287; i++) { // 524287 * legalKey is equal to 512M - 1KB. - keysLegal.push_back(legalKey); - } - - const KvStoreNbDelegate::Option option = {true, false}; - g_mgr.SetKvStoreConfig(g_config); - g_mgr.GetKvStore("SingleVerDeleteBatch003", option, g_kvNbDelegateCallback); - ASSERT_TRUE(g_kvNbDelegatePtr != nullptr); - EXPECT_TRUE(g_kvDelegateStatus == OK); - /** - * @tc.steps: step2. DeleteBatch operates on sets of data. - * @tc.expected: step2. return OK. - */ - EXPECT_EQ(g_kvNbDelegatePtr->DeleteBatch(keysLegal), OK); - - EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK); - EXPECT_EQ(g_mgr.DeleteKvStore("SingleVerDeleteBatch003"), OK); - g_kvNbDelegatePtr = nullptr; -} - -/** - * @tc.name: SingleVerDeleteBatch004 - * @tc.desc: Check for legal parameters that the sum size of all entries is equal to 512M. - * @tc.type: FUNC - * @tc.require: - * @tc.author: mazhao - */ -HWTEST_F(DistributedDBInterfacesNBDelegateTest, SingleVerDeleteBatch004, TestSize.Level1) -{ - /** - * @tc.steps: step1. - * Create and construct one sets of vector : - */ - Key legalKey; - DistributedDBToolsUnitTest::GetRandomKeyValue(legalKey, DBConstant::MAX_KEY_SIZE); // 1K - vector keysLegal; // size is 512M - for (int i = 0; i < 524288; i++) { // 524288 * legalKey is equal to 512M. - keysLegal.push_back(legalKey); - } - - const KvStoreNbDelegate::Option option = {true, false}; - g_mgr.SetKvStoreConfig(g_config); - g_mgr.GetKvStore("SingleVerDeleteBatch004", option, g_kvNbDelegateCallback); - ASSERT_TRUE(g_kvNbDelegatePtr != nullptr); - EXPECT_TRUE(g_kvDelegateStatus == OK); - /** - * @tc.steps: step2. DeleteBatch operates on sets of data. - * @tc.expected: step2. return OK. - */ - EXPECT_EQ(g_kvNbDelegatePtr->DeleteBatch(keysLegal), OK); - - EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK); - EXPECT_EQ(g_mgr.DeleteKvStore("SingleVerDeleteBatch004"), OK); - g_kvNbDelegatePtr = nullptr; -} - -/** - * @tc.name: SingleVerDeleteBatch005 - * @tc.desc: Check for illegal parameters that the sum size of all entries is larger to 512M. - * @tc.type: FUNC - * @tc.require: - * @tc.author: mazhao - */ -HWTEST_F(DistributedDBInterfacesNBDelegateTest, SingleVerDeleteBatch005, TestSize.Level1) -{ - /** - * @tc.steps: step1. - * Create and construct one sets of vector : - */ - Key legalKey; - DistributedDBToolsUnitTest::GetRandomKeyValue(legalKey, DBConstant::MAX_KEY_SIZE); // 1K - vector keysIllLegal; // size is 512M + 1kB - for (int i = 0; i < 524289; i++) { // 524289 * legalKey is equal to 512M + 1KB. - keysIllLegal.push_back(legalKey); - } - - const KvStoreNbDelegate::Option option = {true, false}; - g_mgr.SetKvStoreConfig(g_config); - g_mgr.GetKvStore("SingleVerDeleteBatch005", option, g_kvNbDelegateCallback); - ASSERT_TRUE(g_kvNbDelegatePtr != nullptr); - EXPECT_TRUE(g_kvDelegateStatus == OK); - /** - * @tc.steps: step2. DeleteBatch operates on sets of data. - * @tc.expected: step2. return INVALID_ARGS. - */ - EXPECT_EQ(g_kvNbDelegatePtr->DeleteBatch(keysIllLegal), INVALID_ARGS); - - EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK); - EXPECT_EQ(g_mgr.DeleteKvStore("SingleVerDeleteBatch005"), OK); - g_kvNbDelegatePtr = nullptr; -} - -/** - * @tc.name: SingleVerDeleteBatch006 - * @tc.desc: Check for illegal parameters that the sum size of all entries excced uint32_t limit. - * @tc.type: FUNC - * @tc.require: - * @tc.author: mazhao - */ -HWTEST_F(DistributedDBInterfacesNBDelegateTest, SingleVerDeleteBatch006, TestSize.Level1) -{ - /** - * @tc.steps: step1. - * Create and construct one sets of vector : - */ - Key legalKey; - DistributedDBToolsUnitTest::GetRandomKeyValue(legalKey, DBConstant::MAX_KEY_SIZE); // 1K - vector keysIllLegal; // size excced to the limit of uint32_t - for (int i = 0; i < 4194305; i++) { // 4194305 * legalKey is excced to the limit of uint32_t. - keysIllLegal.push_back(legalKey); - } - - const KvStoreNbDelegate::Option option = {true, false}; - g_mgr.SetKvStoreConfig(g_config); - g_mgr.GetKvStore("SingleVerDeleteBatch006", option, g_kvNbDelegateCallback); - ASSERT_TRUE(g_kvNbDelegatePtr != nullptr); - EXPECT_TRUE(g_kvDelegateStatus == OK); - /** - * @tc.steps: step2. DeleteLocalBatch operates on sets of data. - * @tc.expected: step2. return INVALID_ARGS. - */ - EXPECT_EQ(g_kvNbDelegatePtr->DeleteBatch(keysIllLegal), INVALID_ARGS); - - EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK); - EXPECT_EQ(g_mgr.DeleteKvStore("SingleVerDeleteBatch006"), OK); - g_kvNbDelegatePtr = nullptr; -} - /** * @tc.name: SingleVerPutBatchObserver001 * @tc.desc: Test the observer function of PutBatch() interface. @@ -3168,20 +2843,20 @@ HWTEST_F(DistributedDBInterfacesNBDelegateTest, MigrateDeadLockTest001, TestSize } /** - * @tc.name: RdRangeQueryInSqlite001 + * @tc.name: InvalidQueryTest001 * @tc.desc: Test GetEntries with range query filter by sqlite * @tc.type: FUNC * @tc.require: AR.SR.IR20230714002092.017.001 * @tc.author: mazhao */ -HWTEST_F(DistributedDBInterfacesNBDelegateTest, RdRangeQueryInSqlite001, TestSize.Level1) +HWTEST_F(DistributedDBInterfacesNBDelegateTest, InvalidQueryTest001, TestSize.Level1) { /** * @tc.steps:step1. Get the nb delegate. * @tc.expected: step1. Get results OK and non-null delegate. */ KvStoreNbDelegate::Option option; - g_mgr.GetKvStore("RdRangeQueryInSqlite001", option, g_kvNbDelegateCallback); + g_mgr.GetKvStore("InvalidQueryTest001", option, g_kvNbDelegateCallback); std::vector entries; ASSERT_TRUE(g_kvNbDelegatePtr != nullptr); EXPECT_TRUE(g_kvDelegateStatus == OK); @@ -3195,4 +2870,44 @@ HWTEST_F(DistributedDBInterfacesNBDelegateTest, RdRangeQueryInSqlite001, TestSiz EXPECT_EQ(g_kvNbDelegatePtr->GetEntries(inValidQuery, resultSet), NOT_SUPPORT); EXPECT_EQ(g_kvNbDelegatePtr->GetEntries(inValidQuery, entries), NOT_SUPPORT); } + +/** + * @tc.name: OptionValidCheck001 + * @tc.desc: test validation of option mode + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangshijie + */ +HWTEST_F(DistributedDBInterfacesNBDelegateTest, OptionModeValidCheck001, TestSize.Level0) +{ + /** + * @tc.steps:step1. Get the nb delegate. + * @tc.expected: step1. Get results OK and non-null delegate. + */ + KvStoreNbDelegate::Option option = {true, false, false}; + KvStoreObserverUnitTest *observer = new KvStoreObserverUnitTest(); + ASSERT_TRUE(observer != nullptr); + option.observer = observer; + std::vector invalidModeVec = {0, 5, 6, 7, 9, 16}; + std::string storeId = "OptionModeValidCheck001"; + for (size_t i = 0; i < invalidModeVec.size(); i++) { + option.mode = invalidModeVec.at(i); + g_mgr.GetKvStore(storeId, option, g_kvNbDelegateCallback); + ASSERT_TRUE(g_kvNbDelegatePtr == nullptr); + EXPECT_EQ(g_kvDelegateStatus, INVALID_ARGS); + } + + std::vector validModeVec = {1, 2, 3, 4, 8}; + for (size_t i = 0; i < validModeVec.size(); i++) { + option.mode = validModeVec.at(i); + g_mgr.GetKvStore(storeId, option, g_kvNbDelegateCallback); + ASSERT_TRUE(g_kvNbDelegatePtr != nullptr); + EXPECT_EQ(g_kvDelegateStatus, OK); + EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK); + EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK); + g_kvNbDelegatePtr = nullptr; + } + + delete observer; +} } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_sync_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_sync_test.cpp index 75d556e7..229b7dfc 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_sync_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_sync_test.cpp @@ -1071,3 +1071,22 @@ HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RuntimeConfig001, TestSize.L EXPECT_EQ(RuntimeConfig::IsProcessSystemApiAdapterValid(), RuntimeContext::GetInstance()->IsProcessSystemApiAdapterValid()); } + +/** + * @tc.name: RelationalSyncRangeTest001 + * @tc.desc: Test with sync interface, range query is not support + * @tc.type: FUNC + * @tc.require: DTS2023112110763 + * @tc.author: mazhao + */ +HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RelationalSyncRangeTest001, TestSize.Level1) +{ + std::vector devices = {DEVICE_A}; + Query query = Query::Select("sync_data").Range({}, {}); + int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query, + [&devices](const std::map> &devicesMap) { + EXPECT_EQ(devicesMap.size(), devices.size()); + }, true); + + EXPECT_EQ(errCode, NOT_SUPPORT); +} diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp index 71cf01ee..4256c99c 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp @@ -356,7 +356,7 @@ void CreateDistributedTableOverLimitTest(TableSyncType tableSyncTpe) ASSERT_NE(db, nullptr); EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK); const int tableCount = DBConstant::MAX_DISTRIBUTED_TABLE_COUNT + 10; // 10: additional size for test abnormal scene - for (int i=0; iCreateDistributedTable("TEST_" + std::to_string(i), tableSyncTpe), OK); } else { 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 1cfd094d..60aab138 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 @@ -17,6 +17,8 @@ #include #include +#include "cloud_db_sync_utils_test.h" +#include "cloud/cloud_db_types.h" #include "db_common.h" #include "distributeddb_data_generate_unit_test.h" #include "distributeddb_tools_unit_test.h" @@ -27,8 +29,6 @@ #include "relational_virtual_device.h" #include "runtime_config.h" #include "virtual_relational_ver_sync_db_interface.h" -#include "cloud_db_types.h" -#include "cloud_db_sync_utils_test.h" using namespace testing::ext; using namespace DistributedDB; @@ -148,6 +148,7 @@ namespace { while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) { std::string extendVal; EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 0, extendVal), E_OK); + ASSERT_NE(num, 0u); EXPECT_EQ(extendVal, "Local" + std::to_string(index % num)); std::string cursorVal; EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 1, cursorVal), E_OK); diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_space_management_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_space_management_test.cpp index 1d79d1fa..d362c78d 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_space_management_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_space_management_test.cpp @@ -308,7 +308,7 @@ static void CreateFile(const std::string &fileUrl, uint64_t fileSize) static void DeleteFile(const std::string &fileUrl) { std::ifstream walFile(fileUrl); - if (walFile) { + if (walFile.good()) { int result = remove(fileUrl.c_str()); if (result < 0) { LOGE("failed to delete the file[%s]:%d", fileUrl.c_str(), errno); 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 304465a3..80dc496b 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 @@ -346,7 +346,7 @@ HWTEST_F(DistributedDBCloudAssetsOperationSyncTest, SyncWithAssetOperation002, T ForkDownloadAndRemoveAsset(OK, downLoadCount, removeCount); UpdateCloudTableRecord(0, actualCount, false); RelationalTestUtils::CloudBlockSync(query, delegate_); - EXPECT_EQ(downLoadCount, 3); // local asset was removed should download 3 times + EXPECT_EQ(downLoadCount, 1); // local asset was removed should download 1 times EXPECT_EQ(removeCount, 1); virtualAssetLoader_->ForkDownload(nullptr); virtualAssetLoader_->ForkRemoveLocalAssets(nullptr); @@ -418,7 +418,7 @@ HWTEST_F(DistributedDBCloudAssetsOperationSyncTest, SyncWithAssetOperation004, T ForkDownloadAndRemoveAsset(DB_ERROR, downLoadCount, removeCount); UpdateCloudTableRecord(0, actualCount, false); RelationalTestUtils::CloudBlockSync(query, delegate_, DBStatus::OK, DBStatus::REMOTE_ASSETS_FAIL); - EXPECT_EQ(downLoadCount, 15); // local asset was removed should download 5 * 3 = 15 times + EXPECT_EQ(downLoadCount, 5); // local asset was removed should download 5 times EXPECT_EQ(removeCount, 1); virtualAssetLoader_->ForkDownload(nullptr); virtualAssetLoader_->ForkRemoveLocalAssets(nullptr); @@ -530,6 +530,51 @@ HWTEST_F(DistributedDBCloudAssetsOperationSyncTest, UpsertData001, TestSize.Leve CheckAssetsCount({ 0 }); } +/** + * @tc.name: UpsertData002 + * @tc.desc: Test sync after Upsert. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liaoyonghuang + */ +HWTEST_F(DistributedDBCloudAssetsOperationSyncTest, UpsertData002, TestSize.Level0) +{ + /** + * @tc.steps:step1. Insert 5 records and sync. + * @tc.expected: step1. ok. + */ + const int actualCount = 5; + InsertUserTableRecord(tableName_, 0, actualCount, 10, false); // 10 is photo size + Query query = Query::Select().FromTable({ tableName_ }); + BlockSync(query, delegate_); + + /** + * @tc.steps:step2. UpsertData and sync. + * @tc.expected: step2. ok. + */ + vector records; + for (int i = 0; i < actualCount; i++) { + VBucket record; + record["id"] = std::to_string(i); + record["name"] = std::string("UpsertName"); + records.push_back(record); + } + EXPECT_EQ(delegate_->UpsertData(tableName_, records), OK); + BlockSync(query, delegate_); + + /** + * @tc.steps:step3. Check local data. + * @tc.expected: step3. All local data has been merged by the cloud. + */ + std::vector allData; + auto dbSchema = GetSchema(); + ASSERT_GT(dbSchema.tables.size(), 0u); + ASSERT_EQ(RelationalTestUtils::SelectData(db_, dbSchema.tables[0], allData), E_OK); + for (const auto &data : allData) { + ASSERT_EQ(std::get(data.at("name")), "local"); + } +} + /** * @tc.name: SyncWithAssetConflict001 * @tc.desc: Upload with asset no change diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_check_sync_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_check_sync_test.cpp index 41e07581..b79dba42 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_check_sync_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_check_sync_test.cpp @@ -20,6 +20,7 @@ #include "db_common.h" #include "distributeddb_data_generate_unit_test.h" #include "log_print.h" +#include "relational_store_client.h" #include "relational_store_delegate.h" #include "relational_store_instance.h" #include "relational_store_manager.h" @@ -55,6 +56,8 @@ const Asset g_cloudAsset = { .modifyTime = "123456", .createTime = "0", .size = "1024", .hash = "DEC" }; +std::vector g_actualDBStatus; + void CreateUserDBAndTable(sqlite3 *&db) { EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK); @@ -72,13 +75,14 @@ void PrepareOption(CloudSyncOption &option, const Query &query, bool isPriorityT option.compensatedSyncOnly = isCompensatedSyncOnly; } -void BlockSync(const Query &query, RelationalStoreDelegate *delegate) +void BlockSync(const Query &query, RelationalStoreDelegate *delegate, std::vector &actualDBStatus) { std::mutex dataMutex; std::condition_variable cv; bool finish = false; - auto callback = [&cv, &dataMutex, &finish](const std::map &process) { + auto callback = [&actualDBStatus, &cv, &dataMutex, &finish](const std::map &process) { for (const auto &item: process) { + actualDBStatus.push_back(item.second.errCode); if (item.second.process == DistributedDB::FINISHED) { { std::lock_guard autoLock(dataMutex); @@ -453,13 +457,13 @@ void DistributedDBCloudCheckSyncTest::InitLogicDeleteDataEnv(int64_t dataCount) InsertUserTableRecord(tableName_, dataCount); // sync Query query = Query::Select().FromTable({ tableName_ }); - BlockSync(query, delegate_); + BlockSync(query, delegate_, g_actualDBStatus); // delete cloud data for (int i = 0; i < dataCount; ++i) { DeleteCloudTableRecord(i); } // sync again - BlockSync(query, delegate_); + BlockSync(query, delegate_, g_actualDBStatus); } void DistributedDBCloudCheckSyncTest::CheckLocalCount(int64_t expectCount) @@ -504,8 +508,8 @@ HWTEST_F(DistributedDBCloudCheckSyncTest, CloudSyncTest001, TestSize.Level0) InsertUserTableRecord(tableName_, actualCount); // sync twice Query query = Query::Select().FromTable({ tableName_ }); - BlockSync(query, delegate_); - BlockSync(query, delegate_); + BlockSync(query, delegate_, g_actualDBStatus); + BlockSync(query, delegate_, g_actualDBStatus); // remove cloud data delegate_->RemoveDeviceData("CLOUD", ClearMode::FLAG_AND_DATA); // check local data @@ -532,13 +536,13 @@ HWTEST_F(DistributedDBCloudCheckSyncTest, CloudSyncTest002, TestSize.Level0) InsertUserTableRecord(tableName_, actualCount); // sync twice Query query = Query::Select().FromTable({ tableName_ }); - BlockSync(query, delegate_); + BlockSync(query, delegate_, g_actualDBStatus); // cloud delete id=0 and insert id=0 but its gid is 1 // local delete id=0 DeleteCloudTableRecord(0); // cloud gid is 0 InsertCloudTableRecord(0, actualCount, 0, false); // 0 is id DeleteUserTableRecord(0); // 0 is id - BlockSync(query, delegate_); + BlockSync(query, delegate_, g_actualDBStatus); bool deleteStatus = true; EXPECT_EQ(virtualCloudDb_->GetDataStatus("1", deleteStatus), OK); EXPECT_EQ(deleteStatus, false); @@ -561,7 +565,7 @@ HWTEST_F(DistributedDBCloudCheckSyncTest, CloudSyncTest003, TestSize.Level0) // delete local data DeleteUserTableRecord(0); Query query = Query::Select().FromTable({ tableName_ }); - BlockSync(query, delegate_); + BlockSync(query, delegate_, g_actualDBStatus); // check local data, cloud date will insert into local int dataCnt = -1; @@ -589,12 +593,12 @@ HWTEST_F(DistributedDBCloudCheckSyncTest, CloudSyncTest004, TestSize.Level0) Query query = Query::Select().FromTable({ tableName_ }); LOGW("Block Sync"); virtualCloudDb_->SetInsertFailed(1); - BlockSync(query, delegate_); + BlockSync(query, delegate_, g_actualDBStatus); // delete local data DeleteUserTableRecord(0); // 0 is id LOGW("Block Sync"); // sync again and this record with be synced to cloud - BlockSync(query, delegate_); + BlockSync(query, delegate_, g_actualDBStatus); bool deleteStatus = true; EXPECT_EQ(virtualCloudDb_->GetDataStatus("0", deleteStatus), OK); EXPECT_EQ(deleteStatus, true); @@ -638,7 +642,7 @@ HWTEST_F(DistributedDBCloudCheckSyncTest, CloudSyncObserverTest001, TestSize.Lev */ InsertCloudTableRecord(0, actualCount, actualCount, false); Query query = Query::Select().FromTable({ tableName_ }); - BlockSync(query, delegate_); + BlockSync(query, delegate_, g_actualDBStatus); /** * @tc.steps:step3. check observer. @@ -655,7 +659,7 @@ HWTEST_F(DistributedDBCloudCheckSyncTest, CloudSyncObserverTest001, TestSize.Lev observer2->ResetCloudSyncToZero(); int64_t begin = 11; InsertCloudTableRecord(begin, actualCount, actualCount, false); - BlockSync(query, delegate_); + BlockSync(query, delegate_, g_actualDBStatus); /** * @tc.steps:step5. check observer. @@ -1006,6 +1010,7 @@ HWTEST_F(DistributedDBCloudCheckSyncTest, CloudPrioritySyncTest007, TestSize.Lev Query priorytyQuery = Query::Select().From(tableName_).In("id", idValue); CloudSyncOption option; PrepareOption(option, priorytyQuery, true); + option.lockAction = static_cast(0xff); // lock all std::mutex callbackMutex; std::condition_variable callbackCv; size_t finishCount = 0u; @@ -1067,6 +1072,7 @@ HWTEST_F(DistributedDBCloudCheckSyncTest, CloudPrioritySyncTest008, TestSize.Lev std::vector idValue = {"0"}; Query priorytyQuery = Query::Select().From(tableName_).In("id", idValue); CloudSyncOption option; + option.lockAction = static_cast(0xff); // lock all PrepareOption(option, priorytyQuery, true); std::mutex callbackMutex; std::condition_variable callbackCv; @@ -1153,7 +1159,7 @@ HWTEST_F(DistributedDBCloudCheckSyncTest, CloudPrioritySyncTest010, TestSize.Lev * @tc.expected: step2. ok. */ Query query = Query::Select().FromTable({tableName_}); - BlockSync(query, delegate_); + BlockSync(query, delegate_, g_actualDBStatus); CheckCloudTableCount(tableName_, 10); // 10 is count of cloud records after sync DeleteCloudDBData(0, 3); // delete 0 1 2 record in cloud CheckCloudTableCount(tableName_, 7); // 7 is count of cloud records after delete @@ -1479,11 +1485,11 @@ HWTEST_F(DistributedDBCloudCheckSyncTest, LogicDeleteSyncTest003, TestSize.Level trackerSchema.trackerColNames = {}; EXPECT_EQ(delegate_->SetTrackerTable(trackerSchema), OK); InsertUserTableRecord(tableName_, actualCount); - BlockSync(Query::Select().FromTable({ tableName_ }), delegate_); + BlockSync(Query::Select().FromTable({ tableName_ }), delegate_, g_actualDBStatus); for (int i = 0; i < actualCount + actualCount; ++i) { DeleteCloudTableRecord(i); } - BlockSync(Query::Select().FromTable({ tableName_ }), delegate_); + BlockSync(Query::Select().FromTable({ tableName_ }), delegate_, g_actualDBStatus); EXPECT_EQ(observer->IsAllChangedDataEq(), true); EXPECT_EQ(delegate_->UnRegisterObserver(observer), OK); @@ -1539,6 +1545,53 @@ HWTEST_F(DistributedDBCloudCheckSyncTest, LogicDeleteSyncTest005, TestSize.Level EXPECT_EQ(delegate_->Pragma(AUTO_SYNC, data), DBStatus::NOT_SUPPORT); } +/** + * @tc.name: LogicDeleteSyncTest006 + * @tc.desc: sync with logic delete after lock table. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liaoyonghuang + */ +HWTEST_F(DistributedDBCloudCheckSyncTest, LogicDeleteSyncTest006, TestSize.Level0) +{ + /** + * @tc.steps:step1. set logic delete + * @tc.expected: step1. ok. + */ + bool logicDelete = true; + auto data = static_cast(&logicDelete); + delegate_->Pragma(LOGIC_DELETE_SYNC_DATA, data); + + /** + * @tc.steps:step2. insert user table record and sync. + * @tc.expected: step2. ok. + */ + int dataCount = 10; + InsertUserTableRecord(tableName_, dataCount); + Query query = Query::Select().FromTable({ tableName_ }); + BlockSync(query, delegate_, g_actualDBStatus); + + /** + * @tc.steps:step3. Lock log table, and delete data from cloud table. + * @tc.expected: step3. ok. + */ + std::vector> hashKey; + CloudDBSyncUtilsTest::GetHashKey(tableName_, " 1=1 ", db_, hashKey); + Lock(tableName_, hashKey, db_); + for (int i = 0; i < dataCount; ++i) { + DeleteCloudTableRecord(i); + } + /** + * @tc.steps:step4. sync. + * @tc.expected: step4. ok. + */ + std::vector actualDBStatus; + BlockSync(query, delegate_, actualDBStatus); + for (auto status : actualDBStatus) { + EXPECT_EQ(status, OK); + } +} + /** * @tc.name: LogicCreateRepeatedTableNameTest001 * @tc.desc: test create repeated table name with different cases @@ -1582,7 +1635,7 @@ HWTEST_F(DistributedDBCloudCheckSyncTest, SaveCursorTest001, TestSize.Level0) EXPECT_EQ(cursor, "0"); }); Query query = Query::Select().FromTable({ tableName_ }); - BlockSync(query, delegate_); + BlockSync(query, delegate_, g_actualDBStatus); CheckLocalCount(actualCount); } @@ -1621,7 +1674,7 @@ HWTEST_F(DistributedDBCloudCheckSyncTest, SaveCursorTest002, TestSize.Level0) auto cursor = std::get(extend[CloudDbConstant::CURSOR_FIELD]); EXPECT_EQ(cursor, "0"); }); - BlockSync(query, delegate_); + BlockSync(query, delegate_, g_actualDBStatus); CheckLocalCount(actualCount); } @@ -1660,10 +1713,147 @@ HWTEST_F(DistributedDBCloudCheckSyncTest, SaveCursorTest003, TestSize.Level0) auto cursor = std::get(extend[CloudDbConstant::CURSOR_FIELD]); EXPECT_EQ(cursor, "0"); }); - BlockSync(query, delegate_); + BlockSync(query, delegate_, g_actualDBStatus); CheckCloudTableCount(tableName_, actualCount); } +/** + * @tc.name: RangeQuerySyncTest001 + * @tc.desc: Test sync that has option parameter with range query. + * @tc.type: FUNC + * @tc.require: + * @tc.author: chenchaohao + */ +HWTEST_F(DistributedDBCloudCheckSyncTest, RangeQuerySyncTest001, TestSize.Level0) +{ + /** + * @tc.steps:step1. insert user table record. + * @tc.expected: step1. ok. + */ + CloudSyncOption option; + option.devices = { "CLOUD" }; + option.mode = SYNC_MODE_CLOUD_MERGE; + option.waitTime = g_syncWaitTime; + Query query = Query::Select().From(tableName_).Range({}, {}); + option.query = query; + + /** + * @tc.steps:step2. test normal sync with range query. + * @tc.expected: step2. not support. + */ + option.priorityTask = false; + ASSERT_EQ(delegate_->Sync(option, nullptr), NOT_SUPPORT); + + /** + * @tc.steps:step3. test Priority sync with range query. + * @tc.expected: step3. not support. + */ + option.priorityTask = true; + ASSERT_EQ(delegate_->Sync(option, nullptr), NOT_SUPPORT); +} + +/* + * @tc.name: RangeQuerySyncTest002 + * @tc.desc: Test sync that has not option parameter with range query. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DistributedDBCloudCheckSyncTest, RangeQuerySyncTest002, TestSize.Level1) +{ + Query query = Query::Select().FromTable({ tableName_ }).Range({}, {}); + ASSERT_EQ(delegate_->Sync({"CLOUD"}, SYNC_MODE_CLOUD_FORCE_PULL, query, nullptr, g_syncWaitTime), + DBStatus::NOT_SUPPORT); +} + +/* + * @tc.name: SameDataSync001 + * @tc.desc: Test query same data in one batch. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zqq + */ +HWTEST_F(DistributedDBCloudCheckSyncTest, SameDataSync001, TestSize.Level0) +{ + /** + * @tc.steps:step1. insert cloud records, cloud has two batch id:0-4 + * @tc.expected: step1. OK + */ + const int actualCount = 5; + InsertCloudTableRecord(0, actualCount, 0, false); + InsertCloudTableRecord(0, actualCount, 0, false); + /** + * @tc.steps:step2. call sync, local has one batch id:0-4 + * @tc.expected: step2. OK + */ + Query query = Query::Select().FromTable({ tableName_ }); + BlockSync(query, delegate_, g_actualDBStatus); + CheckLocalCount(actualCount); +} + +/* + * @tc.name: SameDataSync002 + * @tc.desc: Test sync when there are two data with the same primary key on the cloud. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liaoyonghuang + */ +HWTEST_F(DistributedDBCloudCheckSyncTest, SameDataSync002, TestSize.Level1) +{ + /** + * @tc.steps:step1. insert local 1 record and sync to cloud. + * @tc.expected: step1. OK + */ + const int actualCount = 1; + InsertUserTableRecord(tableName_, actualCount); + Query query = Query::Select().FromTable({ tableName_ }); + BlockSync(query, delegate_, g_actualDBStatus); + + /** + * @tc.steps:step2. insert 2 records with the same primary key. + * @tc.expected: step2. OK + */ + std::vector record; + std::vector extend; + Timestamp now = TimeHelper::GetSysCurrentTime(); + VBucket data; + std::vector photo(0, 'v'); + data.insert_or_assign("id", "0"); + data.insert_or_assign("name", "Cloud"); + data.insert_or_assign("height", 166.0); // 166.0 is random double value + data.insert_or_assign("married", false); + data.insert_or_assign("photo", photo); + data.insert_or_assign("age", static_cast(13L)); // 13 is random age + record.push_back(data); + data.insert_or_assign("age", static_cast(14L)); // 14 is random age + record.push_back(data); + VBucket log; + log.insert_or_assign(CloudDbConstant::CREATE_FIELD, static_cast( + now / CloudDbConstant::TEN_THOUSAND)); + log.insert_or_assign(CloudDbConstant::MODIFY_FIELD, static_cast( + now / CloudDbConstant::TEN_THOUSAND)); + log.insert_or_assign(CloudDbConstant::DELETE_FIELD, false); + log.insert_or_assign(CloudDbConstant::VERSION_FIELD, "1"); + extend.push_back(log); + log.insert_or_assign(CloudDbConstant::VERSION_FIELD, "2"); + extend.push_back(log); + ASSERT_EQ(virtualCloudDb_->BatchInsert(tableName_, std::move(record), extend), DBStatus::OK); + + /** + * @tc.steps:step3. sync from cloud and check record. + * @tc.expected: step3. The record with age of 14 has been updated locally. + */ + BlockSync(query, delegate_, g_actualDBStatus); + std::string sql = "SELECT age FROM " + tableName_ + " where id=0;"; + int64_t actualAge = 0; + int64_t expectAge = 14L; + RelationalTestUtils::ExecSql(db_, sql, nullptr, [&actualAge](sqlite3_stmt *stmt) { + actualAge = sqlite3_column_int(stmt, 0); + return E_OK; + }); + EXPECT_EQ(actualAge, expectAge); +} + /* * @tc.name: CreateDistributedTable001 * @tc.desc: Test create distributed table when table not empty. @@ -1697,7 +1887,7 @@ HWTEST_F(DistributedDBCloudCheckSyncTest, CreateDistributedTable001, TestSize.Le * @tc.expected: step2. OK */ Query query = Query::Select().FromTable({ table }); - BlockSync(query, delegate_); + BlockSync(query, delegate_, g_actualDBStatus); CheckCloudTableCount(table, actualCount); } @@ -1766,7 +1956,7 @@ HWTEST_F(DistributedDBCloudCheckSyncTest, ConsistentFlagTest001, TestSize.Level1 InsertUserTableRecord(tableName_, localCount); InsertCloudTableRecord(tableName_, 0, cloudCount, 0, false); Query query = Query::Select().FromTable({ tableName_ }); - BlockSync(query, delegate_); + BlockSync(query, delegate_, g_actualDBStatus); /** * @tc.steps:step2. check the 0x20 bit of flag after sync @@ -1790,7 +1980,7 @@ HWTEST_F(DistributedDBCloudCheckSyncTest, ConsistentFlagTest001, TestSize.Level1 * @tc.steps:step4. check the 0x20 bit of flag after sync * @tc.expected: step4. ok. */ - BlockSync(query, delegate_); + BlockSync(query, delegate_, g_actualDBStatus); EXPECT_EQ(sqlite3_exec(db_, querySql.c_str(), QueryCountCallback, reinterpret_cast(localCount), nullptr), SQLITE_OK); } @@ -1835,9 +2025,10 @@ void DistributedDBCloudCheckSyncTest::SyncDataStatusTest(bool isCompensatedSyncO int unSyncCount = 14; // 14 is the num of unSync data with status 0 CloudDBSyncUtilsTest::CheckCount(db_, querySql, unSyncCount); } else { - querySql = preSql + " where status=3 and data_key in (2,12) and cloud_gid ='';"; + // gid 12、13 are upload insert, lock to lock_change + querySql = preSql + " where status=3 and data_key in (2,12) and cloud_gid !='';"; CloudDBSyncUtilsTest::CheckCount(db_, querySql, syncCount); - querySql = preSql + " where status=3 and data_key in (3,13) and cloud_gid ='';"; + querySql = preSql + " where status=3 and data_key in (3,13) and cloud_gid !='';"; CloudDBSyncUtilsTest::CheckCount(db_, querySql, syncCount); querySql = preSql + " where status=0 and cloud_gid !='';"; int unSyncCount = 16; // 16 is the num of sync finish diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_interfaces_relational_sync_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_interfaces_relational_sync_test.cpp index 8f67e65f..8d9c6ed9 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_interfaces_relational_sync_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_interfaces_relational_sync_test.cpp @@ -541,8 +541,8 @@ namespace { void CheckCloudTotalCount(std::vector expectCounts) { VBucket extend; - extend[CloudDbConstant::CURSOR_FIELD] = std::to_string(0); for (size_t i = 0; i < g_tables.size(); ++i) { + extend[CloudDbConstant::CURSOR_FIELD] = std::to_string(0); int64_t realCount = 0; std::vector data; g_virtualCloudDb->Query(g_tables[i], extend, data); @@ -847,6 +847,7 @@ namespace { } std::vector data2; + extend[CloudDbConstant::CURSOR_FIELD] = std::to_string(0); g_virtualCloudDb->Query(g_tables[1], extend, data2); for (size_t j = 0; j < data2.size(); ++j) { Type entry; @@ -854,7 +855,7 @@ namespace { ASSERT_TRUE(isExisted); Assets assets = std::get(entry); Asset baseAsset = j >= (size_t)(localCount / g_arrayHalfSub) ? g_localAsset : g_cloudAsset; - int index = j; + int index = static_cast(j); for (const auto &asset: assets) { EXPECT_EQ(asset.version, baseAsset.version); EXPECT_EQ(asset.name, baseAsset.name + std::to_string(index++)); @@ -1068,7 +1069,7 @@ namespace { EXPECT_EQ(AssetOperationUtils::EraseBitMask(asset.status), static_cast(AssetStatus::DOWNLOADING)); LOGD("asset [name]:%s, [status]:%u, [flag]:%u", asset.name.c_str(), asset.status, asset.flag); - asset.status = (index++) % 6u; // 6 is AssetStatus type num, include invalid type + asset.status = (index++) % 5u + 1; // 5 is AssetStatus type num, include invalid type } } return status; diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_task_merge_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_task_merge_test.cpp index 44219b03..e67a78be 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_task_merge_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_task_merge_test.cpp @@ -303,5 +303,155 @@ HWTEST_F(DistributedDBCloudTaskMergeTest, CloudSyncMergeTaskTest001, TestSize.Le }); CheckCloudTableCount({ tableNameB_, tableNameC_, tableNameD_ }, actualCount); } + +/** + * @tc.name: CloudSyncMergeTaskTest002 + * @tc.desc: test merge sync task with different mode. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liaoyonghuang + */ +HWTEST_F(DistributedDBCloudTaskMergeTest, CloudSyncMergeTaskTest002, TestSize.Level1) +{ + /** + * @tc.steps:step1. insert user table record. + * @tc.expected: step1. ok. + */ + const int actualCount = 10; // 10 is count of records + InsertUserTableRecord(tableNameA_, actualCount); + Query normalQuery1 = Query::Select().FromTable({ tableNameA_ }); + CloudSyncOption option; + PrepareOption(option, normalQuery1, true); + /** + * @tc.steps:step2. set 2s block time for sync task 1st, and start sync task 2nd. + * @tc.expected: step2. ok. + */ + virtualCloudDb_->SetBlockTime(2000); // block 1st sync task 2s. + std::thread syncThread1([&]() { + ASSERT_EQ(delegate_->Sync(option, nullptr), OK); + }); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep 100ms + std::thread syncThread2([&]() { + ASSERT_EQ(delegate_->Sync(option, nullptr), OK); + }); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep 100ms + + /** + * @tc.steps:step3. start sync task 3rd. + * @tc.expected: task CLOUD_SYNC_TASK_MERGED because it was merged into Task 2. + */ + auto callback3 = [](const std::map &process) { + for (const auto &item: process) { + ASSERT_EQ(item.second.errCode, CLOUD_SYNC_TASK_MERGED); + } + }; + std::thread syncThread3([&]() { + ASSERT_EQ(delegate_->Sync(option, callback3), OK); + }); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep 100ms + + /** + * @tc.steps:step4. start sync task 4th. + * @tc.expected: task was not merged because the mode is not SYNC_MODE_CLOUD_MERGE. + */ + auto callback4 = [](const std::map &process) { + for (const auto &item: process) { + ASSERT_EQ(item.second.errCode, OK); + } + }; + std::thread syncThread4([&]() { + option.mode = SYNC_MODE_CLOUD_FORCE_PUSH; + ASSERT_EQ(delegate_->Sync(option, callback4), OK); + }); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep 100ms + + /** + * @tc.steps:step5. start sync task 5th. + * @tc.expected: task CLOUD_SYNC_TASK_MERGED because it was merged into Task 2. + */ + auto callback5 = [](const std::map &process) { + for (const auto &item: process) { + ASSERT_EQ(item.second.errCode, CLOUD_SYNC_TASK_MERGED); + } + }; + std::thread syncThread5([&]() { + option.mode = SYNC_MODE_CLOUD_MERGE; + ASSERT_EQ(delegate_->Sync(option, callback5), OK); + }); + + syncThread1.join(); + syncThread2.join(); + syncThread3.join(); + syncThread4.join(); + syncThread5.join(); +} + +/** + * @tc.name: CloudSyncMergeTaskTest003 + * @tc.desc: test merge sync task which merge is false. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liaoyonghuang + */ +HWTEST_F(DistributedDBCloudTaskMergeTest, CloudSyncMergeTaskTest003, TestSize.Level1) +{ + /** + * @tc.steps:step1. insert user table record. + * @tc.expected: step1. ok. + */ + const int actualCount = 10; // 10 is count of records + InsertUserTableRecord(tableNameA_, actualCount); + Query normalQuery1 = Query::Select().FromTable({ tableNameA_ }); + CloudSyncOption option; + PrepareOption(option, normalQuery1, true); + /** + * @tc.steps:step2. set 2s block time for sync task 1st, and start sync task 2nd. + * @tc.expected: step2. ok. + */ + virtualCloudDb_->SetBlockTime(2000); // block 1st sync task 2s. + std::thread syncThread1([&]() { + ASSERT_EQ(delegate_->Sync(option, nullptr), OK); + }); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep 100ms + std::thread syncThread2([&]() { + ASSERT_EQ(delegate_->Sync(option, nullptr), OK); + }); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep 100ms + /** + * @tc.steps:step3. start sync task 3rd. + * @tc.expected: task CLOUD_SYNC_TASK_MERGED because it was merged into Task 2. + */ + auto callback3 = [](const std::map &process) { + for (const auto &item: process) { + ASSERT_EQ(item.second.errCode, CLOUD_SYNC_TASK_MERGED); + EXPECT_EQ(item.second.tableProcess.size(), 1u); + for (const auto &table : item.second.tableProcess) { + EXPECT_EQ(table.second.process, ProcessStatus::FINISHED); + } + } + }; + std::thread syncThread3([&]() { + ASSERT_EQ(delegate_->Sync(option, callback3), OK); + }); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep 100ms + /** + * @tc.steps:step4. start sync task 4th. + * @tc.expected: task OK because it cannot be merged. + */ + auto callback4 = [](const std::map &process) { + for (const auto &item: process) { + ASSERT_EQ(item.second.errCode, OK); + } + }; + std::thread syncThread4([&]() { + option.merge = false; + ASSERT_EQ(delegate_->Sync(option, callback4), OK); + }); + + syncThread1.join(); + syncThread2.join(); + syncThread3.join(); + syncThread4.join(); +} } #endif \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_cloud_schema_mgr_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_cloud_schema_mgr_test.cpp index d0a0216a..15eef8f3 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_cloud_schema_mgr_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_cloud_schema_mgr_test.cpp @@ -670,4 +670,20 @@ HWTEST_F(DistributedDBCloudSchemaMgrTest, SchemaMgrTest014, TestSize.Level0) EXPECT_EQ(g_schemaMgr->ChkSchema(TABLE_NAME_1, localSchema), E_OK); EXPECT_EQ(g_schemaMgr->ChkSchema(TABLE_NAME_2, localSchema), E_OK); } + +/** + * @tc.name: FieldInfo001 + * @tc.desc: Test Relational field info. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBCloudSchemaMgrTest, FieldInfo001, TestSize.Level0) +{ + FieldInfo fieldInfo; + fieldInfo.SetDataType("long"); + EXPECT_EQ(fieldInfo.GetStorageType(), StorageType::STORAGE_TYPE_INTEGER); + fieldInfo.SetDataType("LONG"); + EXPECT_EQ(fieldInfo.GetStorageType(), StorageType::STORAGE_TYPE_INTEGER); +} } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_query_object_helper_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_query_object_helper_test.cpp index 1d2c9fce..8b987e9b 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_query_object_helper_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_query_object_helper_test.cpp @@ -15,7 +15,7 @@ #include -#include "cloud_db_types.h" +#include "cloud/cloud_db_types.h" #include "db_errno.h" #include "get_query_info.h" #include "log_print.h" diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_cloud_syncable_storage_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_cloud_syncable_storage_test.cpp index 4009f38a..69a7e8f9 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_cloud_syncable_storage_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_cloud_syncable_storage_test.cpp @@ -255,7 +255,7 @@ void ConstructMultiDownloadData(int64_t count, DownloadData &downloadData, std:: std::string name = "lisi" + std::to_string(i); vBucket["name"] = name; vBucket["age"] = (int64_t)i; - int64_t mTime = 12345679L + i; + int64_t mTime = static_cast(12345679L + i); vBucket[CloudDbConstant::MODIFY_FIELD] = mTime; vBucket[CloudDbConstant::CREATE_FIELD] = mTime; downloadData.data.push_back(vBucket); @@ -311,13 +311,13 @@ void fillCloudAssetTest(int64_t count, AssetStatus statusType, bool isDownloadSu vBucket[CloudDbConstant::GID_FIELD] = std::to_string(1); for (int i = 0; i < 4; i ++) { // 4 is AssetStatus Num Asset asset = g_localAsset; - asset.flag = i; + asset.flag = static_cast(i); asset.status = static_cast(statusType); asset.timestamp = g_startTime; Assets assets; for (int j = 0; j < 4; j++) { // 4 is AssetStatus Num Asset temp = g_localAsset; - temp.flag = j; + temp.flag = static_cast(j); temp.status = static_cast(statusType); temp.timestamp = g_startTime + j; assets.push_back(temp); @@ -1349,7 +1349,7 @@ HWTEST_F(DistributedDBRelationalCloudSyncableStorageTest, FillCloudVersion001, T /** * @tc.steps: step7. insert not contain version effect insert - * @tc.expected: OK. + * @tc.expected: E_OK. */ EXPECT_EQ(g_storageProxy->FillCloudLogAndAsset(OpType::INSERT_VERSION, syncData), E_OK); EXPECT_EQ(g_storageProxy->Commit(), E_OK); diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_remote_query_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_remote_query_test.cpp index bbfdc2c8..90aa72bf 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_remote_query_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_remote_query_test.cpp @@ -445,7 +445,7 @@ HWTEST_F(DistributedDBRelationalRemoteQueryTest, PreparedStmtSerialize, TestSize * @tc.expected: OK. */ PreparedStmt prepStmt1(PreparedStmt::QUERY, "SELECT * FROM test WHERE value=? or value=?", {"1", "2"}); - int len = prepStmt1.CalcLength(); + int len = static_cast(prepStmt1.CalcLength()); /** * @tc.steps: step2. Serialize the prepared stmt; @@ -558,7 +558,7 @@ HWTEST_F(DistributedDBRelationalRemoteQueryTest, LargeAmountOfData1, TestSize.Le do { RelationalRowDataSet rowDataSet {}; EXPECT_EQ(store->ExecuteQuery(prepStmt, 1024, rowDataSet, token), E_OK); // 1024 is min mtu. - totalCnt += rowDataSet.GetSize(); + totalCnt += static_cast(rowDataSet.GetSize()); EXPECT_EQ(allRowDataSet.Merge(std::move(rowDataSet)), E_OK); } while (token != nullptr); diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_single_ver_natural_store_testcase.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_single_ver_natural_store_testcase.cpp index e79f3b30..5d7e5381 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_single_ver_natural_store_testcase.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_single_ver_natural_store_testcase.cpp @@ -515,7 +515,8 @@ void DistributedDBStorageSingleVerNaturalStoreTestCase::PutSyncData003(SQLiteSin * @tc.expected: step2. The Get interface returns OK. The value of key1 is value1, * and the value of key2 is value2. */ - Value valueRead1, valueRead2; + Value valueRead1; + Value valueRead2; EXPECT_EQ(connection->Get(option, dataItem1.key, valueRead1), E_OK); EXPECT_EQ(connection->Get(option, dataItem2.key, valueRead2), E_OK); EXPECT_EQ(DistributedDBToolsUnitTest::IsValueEqual(valueRead1, dataItem1.value), true); @@ -864,8 +865,6 @@ void DistributedDBStorageSingleVerNaturalStoreTestCase::SyncDatabaseOperate006(S { IOption option; option.dataType = IOption::SYNC_DATA; - Key key1, key2, key3; - Value value1, value2, value3; /** * @tc.steps: step2/3/4. Set Ioption to synchronous data. @@ -874,12 +873,17 @@ void DistributedDBStorageSingleVerNaturalStoreTestCase::SyncDatabaseOperate006(S * Insert the data of key length=keyPrefix length - 1, value3. * @tc.expected: step2/3/4. Return E_NOT_FOUND. */ + Key key1; DistributedDBToolsUnitTest::GetRandomKeyValue(key1, 30); // 30 as random size - key3 = key2 = key1; + Key key2 = key1; key2.push_back('C'); + Key key3 = key1; key3.pop_back(); + Value value1; DistributedDBToolsUnitTest::GetRandomKeyValue(value1, 84); // 84 as random size + Value value2; DistributedDBToolsUnitTest::GetRandomKeyValue(value2, 101); // 101 as random size + Value value3; DistributedDBToolsUnitTest::GetRandomKeyValue(value3, 37); // 37 as random size EXPECT_EQ(connection->Put(option, key1, value1), E_OK); EXPECT_EQ(connection->Put(option, key2, value2), E_OK); @@ -1535,7 +1539,7 @@ int DistributedDBStorageSingleVerNaturalStoreTestCase::GetRawSyncData(const std: } stuSyncData.timestamp = static_cast(sqlite3_column_int64(statement, SYNC_RES_TIME_INDEX)); - stuSyncData.flag = sqlite3_column_int64(statement, SYNC_RES_FLAG_INDEX); + stuSyncData.flag = static_cast(sqlite3_column_int64(statement, SYNC_RES_FLAG_INDEX)); vecSyncData.push_back(stuSyncData); } diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/cloud_syncer_test.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/cloud_syncer_test.h index 0af06c2a..fb442737 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/cloud_syncer_test.h +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/cloud_syncer_test.h @@ -54,10 +54,11 @@ public: cloudTaskInfos_.insert(std::pair{taskId, CloudTaskInfo()}); cloudTaskInfos_[taskId].mode = mode; cloudTaskInfos_[taskId].taskId = taskId; - currentContext_.currentTaskId = taskId; currentContext_.tableName = "TestTable" + std::to_string(taskId); + cloudTaskInfos_[taskId].table.push_back(currentContext_.tableName); + currentContext_.currentTaskId = taskId; currentContext_.notifier = std::make_shared(this); - currentContext_.notifier->Init({currentContext_.tableName}, { "cloud" }); + currentContext_.notifier->Init({currentContext_.tableName}, { "cloud" }, cloudTaskInfos_[taskId].users); currentContext_.strategy = std::make_shared(); closed_ = false; cloudTaskInfos_[taskId].callback = [this, taskId](const std::map &process) { @@ -250,7 +251,7 @@ public: void SetCloudWaterMarks(const TableName &tableName, const std::string &mark) { currentContext_.tableName = tableName; - currentContext_.cloudWaterMarks[tableName] = mark; + currentContext_.cloudWaterMarks[currentContext_.currentUserIndex][tableName] = mark; } int CallDownloadAssets() @@ -331,6 +332,28 @@ public: { return resumeTaskInfos_[taskId].upload; } + + int CallHandleTagAssets(const Key &hashKey, const DataInfo &dataInfo, size_t idx, SyncParam ¶m, + VBucket &localAssetInfo) + { + return CloudSyncer::HandleTagAssets(hashKey, dataInfo, idx, param, localAssetInfo); + } + + std::map> GetDownloadFinishedStatus() + { + std::lock_guard autoLock(dataLock_); + return currentContext_.isDownloadFinished; + } + + int CallDoDownloadInNeed(bool needUpload, bool isFirstDownload) + { + CloudTaskInfo taskInfo; + { + std::lock_guard autoLock(dataLock_); + taskInfo = cloudTaskInfos_[currentContext_.currentTaskId]; + } + return DoDownloadInNeed(taskInfo, needUpload, isFirstDownload); + } CloudTaskInfo taskInfo_; private: std::map process_; diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_asset_compare_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_asset_compare_test.cpp index fbefe23d..f5e8d64e 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_asset_compare_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_asset_compare_test.cpp @@ -594,9 +594,9 @@ namespace { { auto assetList = g_cloudSyncer->TestTagAssetsInSingleRecord( DATA_BASELINE, DATA_ASSETS_SAME_NAME_PARTIALLY_CHANGED, true); - EXPECT_EQ(std::get(DATA_BASELINE[FIELD_CARS])[0].flag, static_cast(AssetOpType::NO_CHANGE)); - EXPECT_EQ(std::get(DATA_BASELINE[FIELD_CARS])[1].flag, static_cast(AssetOpType::UPDATE)); - EXPECT_EQ(std::get(DATA_BASELINE[FIELD_CARS])[2].flag, static_cast(AssetOpType::NO_CHANGE)); + EXPECT_EQ(std::get(DATA_BASELINE[FIELD_CARS])[0].status, AssetStatus::NORMAL); + EXPECT_EQ(std::get(DATA_BASELINE[FIELD_CARS])[1].status, AssetStatus::UPDATE); + EXPECT_EQ(std::get(DATA_BASELINE[FIELD_CARS])[2].status, AssetStatus::NORMAL); } /** @@ -610,10 +610,10 @@ namespace { { auto assetList = g_cloudSyncer->TestTagAssetsInSingleRecord( DATA_BASELINE, DATA_EMPTY, true); - EXPECT_EQ(std::get(DATA_BASELINE[FIELD_HOUSE]).flag, static_cast(AssetOpType::INSERT)); - EXPECT_EQ(std::get(DATA_BASELINE[FIELD_CARS])[0].flag, static_cast(AssetOpType::INSERT)); - EXPECT_EQ(std::get(DATA_BASELINE[FIELD_CARS])[1].flag, static_cast(AssetOpType::INSERT)); - EXPECT_EQ(std::get(DATA_BASELINE[FIELD_CARS])[2].flag, static_cast(AssetOpType::INSERT)); + EXPECT_EQ(std::get(DATA_BASELINE[FIELD_HOUSE]).status, AssetStatus::INSERT); + EXPECT_EQ(std::get(DATA_BASELINE[FIELD_CARS])[0].status, AssetStatus::INSERT); + EXPECT_EQ(std::get(DATA_BASELINE[FIELD_CARS])[1].status, AssetStatus::INSERT); + EXPECT_EQ(std::get(DATA_BASELINE[FIELD_CARS])[2].status, AssetStatus::INSERT); } /** @@ -627,9 +627,9 @@ namespace { { auto assetList = g_cloudSyncer->TestTagAssetsInSingleRecord( DATA_EMPTY, DATA_BASELINE, true); - EXPECT_EQ(std::get(DATA_EMPTY[FIELD_CARS])[0].flag, static_cast(AssetOpType::DELETE)); - EXPECT_EQ(std::get(DATA_EMPTY[FIELD_CARS])[1].flag, static_cast(AssetOpType::DELETE)); - EXPECT_EQ(std::get(DATA_EMPTY[FIELD_CARS])[2].flag, static_cast(AssetOpType::DELETE)); + EXPECT_EQ(std::get(DATA_EMPTY[FIELD_CARS])[0].status, AssetStatus::DELETE | AssetStatus::HIDDEN); + EXPECT_EQ(std::get(DATA_EMPTY[FIELD_CARS])[1].status, AssetStatus::DELETE | AssetStatus::HIDDEN); + EXPECT_EQ(std::get(DATA_EMPTY[FIELD_CARS])[2].status, AssetStatus::DELETE | AssetStatus::HIDDEN); } /** @@ -642,7 +642,7 @@ namespace { HWTEST_F(DistributedDBCloudAssetCompareTest, AssetCmpTest020, TestSize.Level0) { auto assetList = g_cloudSyncer->TestTagAssetsInSingleRecord( - DATA_ALL_NULL_ASSETS, DATA_BASELINE, true); + DATA_ALL_NULL_ASSETS, DATA_BASELINE, false); EXPECT_EQ(std::get(DATA_BASELINE[FIELD_HOUSE]).flag, static_cast(AssetOpType::DELETE)); EXPECT_EQ(std::get(DATA_ALL_NULL_ASSETS[FIELD_CARS])[0].flag, static_cast(AssetOpType::DELETE)); @@ -652,10 +652,10 @@ namespace { static_cast(AssetOpType::DELETE)); std::map expectedList; - TagAsset(AssetOpType::DELETE, AssetStatus::NORMAL, a1); - TagAsset(AssetOpType::DELETE, AssetStatus::NORMAL, a2); - TagAsset(AssetOpType::DELETE, AssetStatus::NORMAL, a3); - TagAsset(AssetOpType::DELETE, AssetStatus::NORMAL, a4); + TagAsset(AssetOpType::DELETE, AssetStatus::DOWNLOADING, a1); + TagAsset(AssetOpType::DELETE, AssetStatus::DOWNLOADING, a2); + TagAsset(AssetOpType::DELETE, AssetStatus::DOWNLOADING, a3); + TagAsset(AssetOpType::DELETE, AssetStatus::DOWNLOADING, a4); expectedList[FIELD_HOUSE] = { a1 }; expectedList[FIELD_CARS] = { a2, a3, a4 }; ASSERT_TRUE(CheckAssetDownloadList(FIELD_HOUSE, assetList, expectedList)); @@ -693,17 +693,21 @@ namespace { HWTEST_F(DistributedDBCloudAssetCompareTest, AssetCmpTest022, TestSize.Level0) { auto assetList = g_cloudSyncer->TestTagAssetsInSingleRecord( - DATA_BASELINE, DATA_ALL_NULL_ASSETS, true); + DATA_BASELINE, DATA_ALL_NULL_ASSETS, false); EXPECT_EQ(std::get(DATA_BASELINE[FIELD_HOUSE]).flag, static_cast(AssetOpType::INSERT)); EXPECT_EQ(std::get(DATA_BASELINE[FIELD_CARS])[0].flag, static_cast(AssetOpType::INSERT)); EXPECT_EQ(std::get(DATA_BASELINE[FIELD_CARS])[1].flag, static_cast(AssetOpType::INSERT)); EXPECT_EQ(std::get(DATA_BASELINE[FIELD_CARS])[2].flag, static_cast(AssetOpType::INSERT)); std::map expectedList; - TagAsset(AssetOpType::INSERT, AssetStatus::NORMAL, a1); - TagAsset(AssetOpType::INSERT, AssetStatus::NORMAL, a2); - TagAsset(AssetOpType::INSERT, AssetStatus::NORMAL, a3); - TagAsset(AssetOpType::INSERT, AssetStatus::NORMAL, a4); + TagAsset(AssetOpType::INSERT, + static_cast(AssetStatus::DOWNLOADING | AssetStatus::DOWNLOAD_WITH_NULL), a1); + TagAsset(AssetOpType::INSERT, + static_cast(AssetStatus::DOWNLOADING | AssetStatus::DOWNLOAD_WITH_NULL), a2); + TagAsset(AssetOpType::INSERT, + static_cast(AssetStatus::DOWNLOADING | AssetStatus::DOWNLOAD_WITH_NULL), a3); + TagAsset(AssetOpType::INSERT, + static_cast(AssetStatus::DOWNLOADING | AssetStatus::DOWNLOAD_WITH_NULL), a4); expectedList[FIELD_HOUSE] = { a1 }; expectedList[FIELD_CARS] = { a2, a3, a4 }; ASSERT_TRUE(CheckAssetDownloadList(FIELD_HOUSE, assetList, expectedList)); @@ -721,14 +725,14 @@ namespace { { auto assetList = g_cloudSyncer->TestTagAssetsInSingleRecord( DATA_ASSET_SAME_NAME_BUT_CHANGE, DATA_BASELINE, true); - EXPECT_EQ(std::get(DATA_ASSET_SAME_NAME_BUT_CHANGE[FIELD_HOUSE]).flag, - static_cast(AssetOpType::UPDATE)); - EXPECT_EQ(std::get(DATA_ASSET_SAME_NAME_BUT_CHANGE[FIELD_CARS])[0].flag, - static_cast(AssetOpType::NO_CHANGE)); - EXPECT_EQ(std::get(DATA_ASSET_SAME_NAME_BUT_CHANGE[FIELD_CARS])[1].flag, - static_cast(AssetOpType::NO_CHANGE)); - EXPECT_EQ(std::get(DATA_ASSET_SAME_NAME_BUT_CHANGE[FIELD_CARS])[2].flag, - static_cast(AssetOpType::NO_CHANGE)); + EXPECT_EQ(std::get(DATA_ASSET_SAME_NAME_BUT_CHANGE[FIELD_HOUSE]).status, + AssetStatus::UPDATE); + EXPECT_EQ(std::get(DATA_ASSET_SAME_NAME_BUT_CHANGE[FIELD_CARS])[0].status, + AssetStatus::NORMAL); + EXPECT_EQ(std::get(DATA_ASSET_SAME_NAME_BUT_CHANGE[FIELD_CARS])[1].status, + AssetStatus::NORMAL); + EXPECT_EQ(std::get(DATA_ASSET_SAME_NAME_BUT_CHANGE[FIELD_CARS])[2].status, + AssetStatus::NORMAL); } /** @@ -742,16 +746,16 @@ namespace { { auto assetList = g_cloudSyncer->TestTagAssetsInSingleRecord( DATA_ASSETS_DIFFERENT_CHANGED_FIELD, DATA_BASELINE, true); - EXPECT_EQ(std::get(DATA_ASSETS_DIFFERENT_CHANGED_FIELD[FIELD_HOUSE]).flag, - static_cast(AssetOpType::NO_CHANGE)); - EXPECT_EQ(std::get(DATA_ASSETS_DIFFERENT_CHANGED_FIELD[FIELD_CARS])[0].flag, - static_cast(AssetOpType::NO_CHANGE)); - EXPECT_EQ(std::get(DATA_ASSETS_DIFFERENT_CHANGED_FIELD[FIELD_CARS])[1].flag, - static_cast(AssetOpType::UPDATE)); - EXPECT_EQ(std::get(DATA_ASSETS_DIFFERENT_CHANGED_FIELD[FIELD_CARS])[2].flag, - static_cast(AssetOpType::INSERT)); - EXPECT_EQ(std::get(DATA_ASSETS_DIFFERENT_CHANGED_FIELD[FIELD_CARS])[3].flag, - static_cast(AssetOpType::DELETE)); + EXPECT_EQ(std::get(DATA_ASSETS_DIFFERENT_CHANGED_FIELD[FIELD_HOUSE]).status, + AssetStatus::NORMAL); + EXPECT_EQ(std::get(DATA_ASSETS_DIFFERENT_CHANGED_FIELD[FIELD_CARS])[0].status, + AssetStatus::NORMAL); + EXPECT_EQ(std::get(DATA_ASSETS_DIFFERENT_CHANGED_FIELD[FIELD_CARS])[1].status, + AssetStatus::UPDATE); + EXPECT_EQ(std::get(DATA_ASSETS_DIFFERENT_CHANGED_FIELD[FIELD_CARS])[2].status, + AssetStatus::INSERT); + EXPECT_EQ(std::get(DATA_ASSETS_DIFFERENT_CHANGED_FIELD[FIELD_CARS])[3].status, + AssetStatus::DELETE | AssetStatus::HIDDEN); } /** @@ -765,10 +769,10 @@ namespace { HWTEST_F(DistributedDBCloudAssetCompareTest, AssetCmpTest025, TestSize.Level0) { auto assetList = g_cloudSyncer->TestTagAssetsInSingleRecord(DATA_BASELINE, DATA_NULL_ASSETS, true); - EXPECT_EQ(std::get(DATA_BASELINE[FIELD_HOUSE]).flag, static_cast(AssetOpType::NO_CHANGE)); - EXPECT_EQ(std::get(DATA_BASELINE[FIELD_CARS])[0].flag, static_cast(AssetOpType::INSERT)); - EXPECT_EQ(std::get(DATA_BASELINE[FIELD_CARS])[1].flag, static_cast(AssetOpType::INSERT)); - EXPECT_EQ(std::get(DATA_BASELINE[FIELD_CARS])[2].flag, static_cast(AssetOpType::INSERT)); + EXPECT_EQ(std::get(DATA_BASELINE[FIELD_HOUSE]).status, AssetStatus::NORMAL); + EXPECT_EQ(std::get(DATA_BASELINE[FIELD_CARS])[0].status, AssetStatus::INSERT); + EXPECT_EQ(std::get(DATA_BASELINE[FIELD_CARS])[1].status, AssetStatus::INSERT); + EXPECT_EQ(std::get(DATA_BASELINE[FIELD_CARS])[2].status, AssetStatus::INSERT); } /** @@ -783,10 +787,10 @@ namespace { HWTEST_F(DistributedDBCloudAssetCompareTest, AssetCmpTest026, TestSize.Level0) { auto assetList = g_cloudSyncer->TestTagAssetsInSingleRecord(DATA_BASELINE, DATA_EMPTY_ASSETS, true); - EXPECT_EQ(std::get(DATA_BASELINE[FIELD_HOUSE]).flag, static_cast(AssetOpType::NO_CHANGE)); - EXPECT_EQ(std::get(DATA_BASELINE[FIELD_CARS])[0].flag, static_cast(AssetOpType::INSERT)); - EXPECT_EQ(std::get(DATA_BASELINE[FIELD_CARS])[1].flag, static_cast(AssetOpType::INSERT)); - EXPECT_EQ(std::get(DATA_BASELINE[FIELD_CARS])[2].flag, static_cast(AssetOpType::INSERT)); + EXPECT_EQ(std::get(DATA_BASELINE[FIELD_HOUSE]).status, AssetStatus::NORMAL); + EXPECT_EQ(std::get(DATA_BASELINE[FIELD_CARS])[0].status, AssetStatus::INSERT); + EXPECT_EQ(std::get(DATA_BASELINE[FIELD_CARS])[1].status, AssetStatus::INSERT); + EXPECT_EQ(std::get(DATA_BASELINE[FIELD_CARS])[2].status, AssetStatus::INSERT); } /** @@ -821,12 +825,12 @@ namespace { { auto assetList = g_cloudSyncer->TestTagAssetsInSingleRecord( DATA_ALL_NULL_ASSETS, DATA_BASELINE, true); - EXPECT_EQ(std::get(DATA_ALL_NULL_ASSETS[FIELD_CARS])[0].flag, - static_cast(AssetOpType::DELETE)); - EXPECT_EQ(std::get(DATA_ALL_NULL_ASSETS[FIELD_CARS])[1].flag, - static_cast(AssetOpType::DELETE)); - EXPECT_EQ(std::get(DATA_ALL_NULL_ASSETS[FIELD_CARS])[2].flag, - static_cast(AssetOpType::DELETE)); + EXPECT_EQ(std::get(DATA_ALL_NULL_ASSETS[FIELD_CARS])[0].status, + AssetStatus::DELETE | AssetStatus::HIDDEN); + EXPECT_EQ(std::get(DATA_ALL_NULL_ASSETS[FIELD_CARS])[1].status, + AssetStatus::DELETE | AssetStatus::HIDDEN); + EXPECT_EQ(std::get(DATA_ALL_NULL_ASSETS[FIELD_CARS])[2].status, + AssetStatus::DELETE | AssetStatus::HIDDEN); } /** @@ -1008,4 +1012,43 @@ namespace { AssetOperationUtils::CloudSyncAction::END_UPLOAD); EXPECT_EQ(res["field"][asset.name], AssetOperationUtils::AssetOpType::NOT_HANDLE); } + + /** + * @tc.name: SameAssetNotify001 + * @tc.desc: Test same asset notify in one batch + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ + HWTEST_F(DistributedDBCloudAssetCompareTest, SameAssetNotify001, TestSize.Level0) + { + /** + * @tc.steps: step1. prepare two data with same pk + */ + ICloudSyncer::SyncParam param; + param.downloadData.opType.push_back(OpType::INSERT); + param.downloadData.opType.push_back(OpType::UPDATE); + const std::string pkField = "pk_asset"; + param.changedData.field.push_back(pkField); + VBucket oneRow; + oneRow[pkField] = static_cast(1); // 1 is pk + param.downloadData.data.push_back(oneRow); + param.downloadData.data.push_back(oneRow); + ICloudSyncer::DataInfo dataInfo; + dataInfo.localInfo.logInfo.dataKey = 1; + param.isSinglePrimaryKey = true; + param.pkColNames.push_back(pkField); + /** + * @tc.steps: step2. handle tag assets + * @tc.expected: step2. all type should be INSERT + */ + VBucket localAsset; + Key hashKey; + for (size_t i = 0; i < param.downloadData.opType.size(); ++i) { + int errCode = g_cloudSyncer->CallHandleTagAssets(hashKey, dataInfo, i, param, localAsset); + ASSERT_EQ(errCode, E_OK); + auto strategy = std::get(param.assetsDownloadList[i]); + EXPECT_EQ(strategy, OpType::INSERT); + } + } } diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_db_proxy_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_db_proxy_test.cpp index 69a4acfa..3a2c893a 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_db_proxy_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_db_proxy_test.cpp @@ -17,8 +17,8 @@ #include #include "cloud/cloud_db_constant.h" #include "cloud/cloud_db_data_utils.h" -#include "cloud/cloud_db_types.h" #include "cloud/cloud_db_proxy.h" +#include "cloud/cloud_db_types.h" #include "cloud/cloud_sync_utils.h" #include "distributeddb_tools_unit_test.h" #include "kv_store_errno.h" @@ -459,6 +459,46 @@ HWTEST_F(DistributedDBCloudDBProxyTest, CloudDBProxyTest010, TestSize.Level0) EXPECT_EQ(proxy.Close(), E_OK); } +/** + * @tc.name: CloudDBProxyTest008 + * @tc.desc: Verify cloud db heartbeat with diff status. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBCloudDBProxyTest, CloudDBProxyTest011, TestSize.Level2) +{ + /** + * @tc.steps: step1. set cloud db to proxy + * @tc.expected: step1. E_OK + */ + CloudDBProxy proxy; + proxy.SetCloudDB(virtualCloudDb_); + virtualCloudDb_->SetHeartbeatBlockTime(100); // block 100 ms + std::mutex waitMutex; + std::condition_variable waitCv; + const int scheduleCount = 12; + int currentCount = 0; + for (int i = 0; i < scheduleCount; ++i) { + RuntimeContext::GetInstance()->ScheduleTask([&proxy, &waitMutex, &waitCv, ¤tCount]() { + proxy.HeartBeat(); + { + std::lock_guard autoLock(waitMutex); + currentCount++; + LOGI("[CloudDBProxyTest011] CurrentCount %d", currentCount); + } + waitCv.notify_all(); + }); + } + LOGI("[CloudDBProxyTest011] Begin wait all task finish"); + std::unique_lock uniqueLock(waitMutex); + waitCv.wait_for(uniqueLock, std::chrono::milliseconds(DBConstant::MAX_TIMEOUT), [¤tCount, scheduleCount]() { + return currentCount >= scheduleCount; + }); + LOGI("[CloudDBProxyTest011] End wait all task finish"); + EXPECT_EQ(currentCount, scheduleCount); +} + /** * @tc.name: CloudSyncQueue001 * @tc.desc: Verify sync task count decrease after sync finished. @@ -496,6 +536,46 @@ HWTEST_F(DistributedDBCloudDBProxyTest, CloudSyncQueue001, TestSize.Level2) RefObject::KillAndDecObjRef(cloudSyncer); } +/** + * @tc.name: CloudSyncQueue002 + * @tc.desc: Verify sync task abort after close. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBCloudDBProxyTest, CloudSyncQueue002, TestSize.Level2) +{ + /** + * @tc.steps: step1. set cloud db to proxy and sleep 2s when download + * @tc.expected: step1. E_OK + */ + auto iCloud = std::make_shared(); + ASSERT_NE(iCloud, nullptr); + EXPECT_CALL(*iCloud, Rollback).WillRepeatedly(testing::Return(E_OK)); + EXPECT_CALL(*iCloud, Commit).WillRepeatedly(testing::Return(E_OK)); + EXPECT_CALL(*iCloud, StartTransaction).WillRepeatedly(testing::Return(E_OK)); + auto cloudSyncer = new(std::nothrow) VirtualCloudSyncer(StorageProxy::GetCloudDb(iCloud.get())); + ASSERT_NE(cloudSyncer, nullptr); + cloudSyncer->SetCloudDB(virtualCloudDb_); + cloudSyncer->SetSyncAction(true, false); + std::atomic close = false; + cloudSyncer->SetDownloadFunc([cloudSyncer, &close]() { + std::this_thread::sleep_for(std::chrono::seconds(2)); // sleep 2s + cloudSyncer->PauseCurrentTask(); + EXPECT_TRUE(close); + return -E_TASK_PAUSED; + }); + /** + * @tc.steps: step2. call sync and wait sync finish + */ + EXPECT_EQ(cloudSyncer->Sync({ "cloud" }, SyncMode::SYNC_MODE_CLOUD_MERGE, { TABLE_NAME }, nullptr, 0), E_OK); + std::this_thread::sleep_for(std::chrono::seconds(1)); + close = true; + cloudSyncer->Close(); + RuntimeContext::GetInstance()->StopTaskPool(); + RefObject::KillAndDecObjRef(cloudSyncer); +} + /** * @tc.name: CloudSyncerTest001 * @tc.desc: Verify syncer notify by queue schedule. diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_kv_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_kv_test.cpp index aa057809..d7d264a5 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_kv_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_kv_test.cpp @@ -15,6 +15,7 @@ #include +#include "cloud/cloud_db_constant.h" #include "distributeddb_data_generate_unit_test.h" #include "distributeddb_tools_unit_test.h" #include "kv_virtual_device.h" @@ -33,6 +34,9 @@ namespace { static std::string HWM_HEAD = "naturalbase_cloud_meta_sync_data_"; string g_testDir; KvStoreDelegateManager g_mgr(APP_ID, USER_ID); +CloudSyncOption g_CloudSyncoption; +const std::string USER_ID_2 = "user2"; +const std::string USER_ID_3 = "user3"; class DistributedDBCloudKvTest : public testing::Test { public: static void SetUpTestCase(); @@ -41,19 +45,21 @@ public: void TearDown(); void InsertRecord(int num); void SetDeviceId(const Key &key, const std::string &deviceId); - void SetFlag(const Key &key, bool isCloudFlag); - int CheckFlag(const Key &key, bool isCloudFlag); + void SetFlag(const Key &key, LogInfoFlag flag); + int CheckFlag(const Key &key, LogInfoFlag flag); int CheckLogTable(const std::string &deviceId); int CheckWaterMark(const std::string &key); int ChangeUserId(const std::string &deviceId, const std::string &wantUserId); int ChangeHashKey(const std::string &deviceId); protected: - void GetKvStore(KvStoreNbDelegate *&delegate, const std::string &storeId, int securityLabel = NOT_SET); + DBStatus GetKvStore(KvStoreNbDelegate *&delegate, const std::string &storeId, KvStoreNbDelegate::Option option, + bool invalidSchema = false); void CloseKvStore(KvStoreNbDelegate *&delegate, const std::string &storeId); - void BlockSync(KvStoreNbDelegate *delegate, DBStatus expectDBStatus, - SyncMode mode = SyncMode::SYNC_MODE_CLOUD_MERGE, int expectSyncResult = OK); - static DataBaseSchema GetDataBaseSchema(); + void BlockSync(KvStoreNbDelegate *delegate, DBStatus expectDBStatus, CloudSyncOption option, + int expectSyncResult = OK); + static DataBaseSchema GetDataBaseSchema(bool invalidSchema); std::shared_ptr virtualCloudDb_ = nullptr; + std::shared_ptr virtualCloudDb2_ = nullptr; KvStoreConfig config_; KvStoreNbDelegate* kvDelegatePtrS1_ = nullptr; KvStoreNbDelegate* kvDelegatePtrS2_ = nullptr; @@ -68,6 +74,9 @@ void DistributedDBCloudKvTest::SetUpTestCase() if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) { LOGE("rm test db files error!"); } + g_CloudSyncoption.mode = SyncMode::SYNC_MODE_CLOUD_MERGE; + g_CloudSyncoption.users.push_back(USER_ID); + g_CloudSyncoption.devices.push_back("cloud"); string dir = g_testDir + "/single_ver"; DIR* dirTmp = opendir(dir.c_str()); @@ -93,13 +102,16 @@ void DistributedDBCloudKvTest::SetUp() * @tc.setup: create virtual device B and C, and get a KvStoreNbDelegate as deviceA */ virtualCloudDb_ = std::make_shared(); + virtualCloudDb2_ = std::make_shared(); g_mgr.SetKvStoreConfig(config_); - GetKvStore(kvDelegatePtrS1_, STORE_ID_1); + KvStoreNbDelegate::Option option1; + ASSERT_EQ(GetKvStore(kvDelegatePtrS1_, STORE_ID_1, option1), OK); // set aggregator after get store1, only store2 can sync with p2p communicatorAggregator_ = new (std::nothrow) VirtualCommunicatorAggregator(); ASSERT_TRUE(communicatorAggregator_ != nullptr); RuntimeContext::GetInstance()->SetCommunicatorAggregator(communicatorAggregator_); - GetKvStore(kvDelegatePtrS2_, STORE_ID_2); + KvStoreNbDelegate::Option option2; + ASSERT_EQ(GetKvStore(kvDelegatePtrS2_, STORE_ID_2, option2), OK); deviceB_ = new (std::nothrow) KvVirtualDevice("DEVICE_B"); ASSERT_TRUE(deviceB_ != nullptr); @@ -113,6 +125,7 @@ void DistributedDBCloudKvTest::TearDown() CloseKvStore(kvDelegatePtrS1_, STORE_ID_1); CloseKvStore(kvDelegatePtrS2_, STORE_ID_2); virtualCloudDb_ = nullptr; + virtualCloudDb2_ = nullptr; if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) { LOGE("rm test db files error!"); } @@ -124,35 +137,42 @@ void DistributedDBCloudKvTest::TearDown() RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr); communicatorAggregator_ = nullptr; + RuntimeContext::GetInstance()->SetProcessSystemApiAdapter(nullptr); } -void DistributedDBCloudKvTest::BlockSync(KvStoreNbDelegate *delegate, DBStatus expectDBStatus, - SyncMode mode, int expectSyncResult) +void DistributedDBCloudKvTest::BlockSync(KvStoreNbDelegate *delegate, DBStatus expectDBStatus, CloudSyncOption option, + int expectSyncResult) { + if (delegate == nullptr) { + return; + } std::mutex dataMutex; std::condition_variable cv; bool finish = false; SyncProcess last; - auto callback = - [expectDBStatus, &last, &cv, &dataMutex, &finish](const std::map &process) { + auto callback = [expectDBStatus, &last, &cv, &dataMutex, &finish, &option](const std::map &process) { + size_t notifyCnt = 0; for (const auto &item: process) { - if (item.second.process == DistributedDB::FINISHED) { - EXPECT_EQ(item.second.errCode, expectDBStatus); - { - std::lock_guard autoLock(dataMutex); + LOGD("user = %s, status = %d", item.first.c_str(), item.second.process); + if (item.second.process != DistributedDB::FINISHED) { + continue; + } + EXPECT_EQ(item.second.errCode, expectDBStatus); + { + std::lock_guard autoLock(dataMutex); + notifyCnt++; + if (notifyCnt == option.users.size()) { finish = true; last = item.second; + cv.notify_one(); } - cv.notify_one(); } } }; - CloudSyncOption option; - option.mode = mode; - option.users.push_back(USER_ID); - option.devices.push_back("cloud"); - EXPECT_EQ(delegate->Sync(option, callback), expectSyncResult); - if (expectSyncResult == OK) { + auto actualRet = delegate->Sync(option, callback); + EXPECT_EQ(actualRet, expectSyncResult); + if (actualRet == OK) { std::unique_lock uniqueLock(dataMutex); cv.wait(uniqueLock, [&finish]() { return finish; @@ -161,35 +181,34 @@ void DistributedDBCloudKvTest::BlockSync(KvStoreNbDelegate *delegate, DBStatus e lastProcess_ = last; } -DataBaseSchema DistributedDBCloudKvTest::GetDataBaseSchema() +DataBaseSchema DistributedDBCloudKvTest::GetDataBaseSchema(bool invalidSchema) { DataBaseSchema schema; TableSchema tableSchema; - tableSchema.name = "sync_data"; + tableSchema.name = invalidSchema ? "invalid_schema_name" : CloudDbConstant::CLOUD_KV_TABLE_NAME; Field field; - field.colName = "key"; + field.colName = CloudDbConstant::CLOUD_KV_FIELD_KEY; field.type = TYPE_INDEX; field.primary = true; tableSchema.fields.push_back(field); - field.colName = "device"; + field.colName = CloudDbConstant::CLOUD_KV_FIELD_DEVICE; field.primary = false; tableSchema.fields.push_back(field); - field.colName = "oridevice"; + field.colName = CloudDbConstant::CLOUD_KV_FIELD_ORI_DEVICE; tableSchema.fields.push_back(field); - field.colName = "value"; + field.colName = CloudDbConstant::CLOUD_KV_FIELD_VALUE; tableSchema.fields.push_back(field); - field.colName = "device_create_time"; + field.colName = CloudDbConstant::CLOUD_KV_FIELD_DEVICE_CREATE_TIME; field.type = TYPE_INDEX; tableSchema.fields.push_back(field); schema.tables.push_back(tableSchema); return schema; } -void DistributedDBCloudKvTest::GetKvStore(KvStoreNbDelegate *&delegate, const std::string &storeId, int securityLabel) +DBStatus DistributedDBCloudKvTest::GetKvStore(KvStoreNbDelegate *&delegate, const std::string &storeId, + KvStoreNbDelegate::Option option, bool invalidSchema) { - KvStoreNbDelegate::Option option; DBStatus openRet = OK; - option.secOption.securityLabel = securityLabel; g_mgr.GetKvStore(storeId, option, [&openRet, &delegate](DBStatus status, KvStoreNbDelegate *openDelegate) { openRet = status; delegate = openDelegate; @@ -199,10 +218,12 @@ void DistributedDBCloudKvTest::GetKvStore(KvStoreNbDelegate *&delegate, const st std::map> cloudDbs; cloudDbs[USER_ID] = virtualCloudDb_; + cloudDbs[USER_ID_2] = virtualCloudDb2_; delegate->SetCloudDB(cloudDbs); std::map schemas; - schemas[USER_ID] = GetDataBaseSchema(); - delegate->SetCloudDbSchema(schemas); + schemas[USER_ID] = GetDataBaseSchema(invalidSchema); + schemas[USER_ID_2] = GetDataBaseSchema(invalidSchema); + return delegate->SetCloudDbSchema(schemas); } void DistributedDBCloudKvTest::CloseKvStore(KvStoreNbDelegate *&delegate, const std::string &storeId) @@ -232,11 +253,11 @@ HWTEST_F(DistributedDBCloudKvTest, NormalSync001, TestSize.Level0) LOGW("origin is %s", origin.c_str()); return origin + "1"; }); - BlockSync(kvDelegatePtrS1_, OK); + BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption); for (const auto &table : lastProcess_.tableProcess) { EXPECT_EQ(table.second.upLoadInfo.total, 1u); } - BlockSync(kvDelegatePtrS2_, OK); + BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption); Value actualValue; EXPECT_EQ(kvDelegatePtrS2_->Get(key, actualValue), OK); EXPECT_EQ(actualValue, expectValue); @@ -261,6 +282,7 @@ HWTEST_F(DistributedDBCloudKvTest, NormalSync002, TestSize.Level0) * @tc.steps: step1. store1 put (k1,v1) store2 put (k2,v2) * @tc.expected: step1. both put ok */ + communicatorAggregator_->SetLocalDeviceId("DEVICES_A"); Key key1 = {'k', '1'}; Value expectValue1 = {'v', '1'}; Key key2 = {'k', '2'}; @@ -271,19 +293,24 @@ HWTEST_F(DistributedDBCloudKvTest, NormalSync002, TestSize.Level0) * @tc.steps: step2. both store1 and store2 sync * @tc.expected: step2. both sync ok, and store2 got (k1,v1) store1 not exist (k2,v2) */ - BlockSync(kvDelegatePtrS1_, OK); + BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption); LOGW("Store1 sync end"); - BlockSync(kvDelegatePtrS2_, OK); + communicatorAggregator_->SetLocalDeviceId("DEVICES_B"); + BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption); LOGW("Store2 sync end"); Value actualValue; EXPECT_EQ(kvDelegatePtrS2_->Get(key1, actualValue), OK); + std::vector entries; + EXPECT_EQ(kvDelegatePtrS2_->GetDeviceEntries(std::string("DEVICES_A"), entries), OK); + EXPECT_EQ(entries.size(), 1u); // 1 record + communicatorAggregator_->SetLocalDeviceId("DEVICES_A"); EXPECT_EQ(actualValue, expectValue1); EXPECT_EQ(kvDelegatePtrS1_->Get(key2, actualValue), NOT_FOUND); /** * @tc.steps: step3. store1 sync again * @tc.expected: step3. sync ok store1 got (k2,v2) */ - BlockSync(kvDelegatePtrS1_, OK); + BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption); LOGW("Store1 sync end"); EXPECT_EQ(kvDelegatePtrS1_->Get(key2, actualValue), OK); EXPECT_EQ(actualValue, expectValue2); @@ -312,8 +339,8 @@ HWTEST_F(DistributedDBCloudKvTest, NormalSync003, TestSize.Level0) * @tc.steps: step2. both store1 and store2 sync * @tc.expected: step2. both sync ok and store2 got (k1,v2) */ - BlockSync(kvDelegatePtrS1_, OK); - BlockSync(kvDelegatePtrS2_, OK); + BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption); + BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption); Value actualValue; EXPECT_EQ(kvDelegatePtrS2_->Get(key, actualValue), OK); EXPECT_EQ(actualValue, expectValue2); @@ -321,7 +348,7 @@ HWTEST_F(DistributedDBCloudKvTest, NormalSync003, TestSize.Level0) * @tc.steps: step2. store1 sync again * @tc.expected: step2. sync ok and store1 got (k1,v2) */ - BlockSync(kvDelegatePtrS1_, OK); + BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption); EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), OK); EXPECT_EQ(actualValue, expectValue2); } @@ -342,8 +369,8 @@ HWTEST_F(DistributedDBCloudKvTest, NormalSync004, TestSize.Level0) Key key = {'k'}; Value expectValue = {'v'}; ASSERT_EQ(kvDelegatePtrS1_->Put(key, expectValue), OK); - BlockSync(kvDelegatePtrS1_, OK); - BlockSync(kvDelegatePtrS2_, OK); + BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption); + BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption); Value actualValue; EXPECT_EQ(kvDelegatePtrS2_->Get(key, actualValue), OK); EXPECT_EQ(actualValue, expectValue); @@ -352,8 +379,8 @@ HWTEST_F(DistributedDBCloudKvTest, NormalSync004, TestSize.Level0) * @tc.expected: step2. both put ok */ ASSERT_EQ(kvDelegatePtrS1_->Delete(key), OK); - BlockSync(kvDelegatePtrS1_, OK); - BlockSync(kvDelegatePtrS2_, OK); + BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption); + BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption); actualValue.clear(); EXPECT_EQ(kvDelegatePtrS2_->Get(key, actualValue), NOT_FOUND); EXPECT_NE(actualValue, expectValue); @@ -375,8 +402,8 @@ HWTEST_F(DistributedDBCloudKvTest, NormalSync005, TestSize.Level1) expectValue.push_back(static_cast(i)); ASSERT_EQ(kvDelegatePtrS1_->Put(key, expectValue), OK); } - BlockSync(kvDelegatePtrS1_, OK); - BlockSync(kvDelegatePtrS2_, OK); + BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption); + BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption); } /** @@ -397,8 +424,8 @@ HWTEST_F(DistributedDBCloudKvTest, NormalSync006, TestSize.Level0) ASSERT_EQ(kvDelegatePtrS1_->Put(k2, v2), OK); ASSERT_EQ(kvDelegatePtrS1_->Put(k2, v3), OK); ASSERT_EQ(kvDelegatePtrS1_->Delete(k1), OK); - BlockSync(kvDelegatePtrS1_, OK); - BlockSync(kvDelegatePtrS2_, OK); + BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption); + BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption); Value actualValue; EXPECT_EQ(kvDelegatePtrS2_->Get(k1, actualValue), NOT_FOUND); EXPECT_EQ(kvDelegatePtrS2_->Get(k2, actualValue), OK); @@ -429,10 +456,10 @@ HWTEST_F(DistributedDBCloudKvTest, NormalSync007, TestSize.Level0) ASSERT_EQ(kvDelegatePtrS1_->Put(k2, v2), OK); ASSERT_EQ(kvDelegatePtrS1_->Put(k4, v2), OK); std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep 100ms - BlockSync(kvDelegatePtrS1_, OK); + BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption); ASSERT_EQ(kvDelegatePtrS2_->Put(k4, v3), OK); ASSERT_EQ(kvDelegatePtrS1_->Delete(k2), OK); - BlockSync(kvDelegatePtrS2_, OK); + BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption); } /** @@ -451,8 +478,12 @@ HWTEST_F(DistributedDBCloudKvTest, NormalSync008, TestSize.Level0) Value actualValue; EXPECT_EQ(kvDelegatePtrS2_->Get(k1, actualValue), OK); EXPECT_EQ(actualValue, v1); - BlockSync(kvDelegatePtrS2_, OK, SyncMode::SYNC_MODE_CLOUD_FORCE_PUSH); - BlockSync(kvDelegatePtrS1_, OK); + CloudSyncOption option; + option.mode = SyncMode::SYNC_MODE_CLOUD_FORCE_PUSH; + option.users.push_back(USER_ID); + option.devices.push_back("cloud"); + BlockSync(kvDelegatePtrS2_, OK, option); + BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption); EXPECT_EQ(kvDelegatePtrS1_->Get(k1, actualValue), NOT_FOUND); } @@ -475,55 +506,731 @@ HWTEST_F(DistributedDBCloudKvTest, NormalSync009, TestSize.Level0) ASSERT_EQ(kvDelegatePtrS1_->Put(k2, v1), OK); ASSERT_EQ(kvDelegatePtrS1_->Delete(k1), OK); std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep 100ms - BlockSync(kvDelegatePtrS1_, OK); + BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption); ASSERT_EQ(kvDelegatePtrS2_->Put(k1, v2), OK); ASSERT_EQ(kvDelegatePtrS2_->Put(k3, v2), OK); - BlockSync(kvDelegatePtrS2_, OK); + BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption); std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep 100ms - BlockSync(kvDelegatePtrS1_, OK); + BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption); } /** * @tc.name: NormalSync010 + * @tc.desc: Test normal push sync for add data with different user. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangshijie + */ +HWTEST_F(DistributedDBCloudKvTest, NormalSync010, TestSize.Level0) +{ + // add , sync to cloud with user1 + Key key1 = {'k', '1'}; + Value expectValue1 = {'v', '1'}; + ASSERT_EQ(kvDelegatePtrS1_->Put(key1, expectValue1), OK); + CloudSyncOption option; + option.users.push_back(USER_ID); + option.devices.push_back("cloud"); + BlockSync(kvDelegatePtrS1_, OK, option); + for (const auto &table : lastProcess_.tableProcess) { + EXPECT_EQ(table.second.upLoadInfo.total, 1u); + } + + // add , sync to cloud with user2 + Key key2 = {'k', '2'}; + Value expectValue2 = {'v', '2'}; + ASSERT_EQ(kvDelegatePtrS1_->Put(key2, expectValue2), OK); + option.users.clear(); + option.users.push_back(USER_ID_2); + BlockSync(kvDelegatePtrS1_, OK, option); + for (const auto &table : lastProcess_.tableProcess) { + EXPECT_EQ(table.second.upLoadInfo.total, 2u); + } + + option.users.clear(); + option.users.push_back(USER_ID); + option.users.push_back(USER_ID_2); + BlockSync(kvDelegatePtrS2_, OK, option); + for (const auto &table : lastProcess_.tableProcess) { + EXPECT_EQ(table.second.downLoadInfo.total, 2u); + } + Value actualValue; + EXPECT_EQ(kvDelegatePtrS2_->Get(key1, actualValue), OK); + EXPECT_EQ(actualValue, expectValue1); + Value actualValue2; + EXPECT_EQ(kvDelegatePtrS2_->Get(key2, actualValue2), OK); + EXPECT_EQ(actualValue2, expectValue2); +} + +/** + * @tc.name: NormalSync011 * @tc.desc: Do not synchronize when security label is S4. * @tc.type: FUNC * @tc.require: * @tc.author: liaoyonghuang */ -HWTEST_F(DistributedDBCloudKvTest, NormalSync010, TestSize.Level0) +HWTEST_F(DistributedDBCloudKvTest, NormalSync011, TestSize.Level0) { std::shared_ptr g_adapter = std::make_shared(); RuntimeContext::GetInstance()->SetProcessSystemApiAdapter(g_adapter); KvStoreNbDelegate* kvDelegatePtrS3_ = nullptr; - GetKvStore(kvDelegatePtrS3_, STORE_ID_3, S4); - BlockSync(kvDelegatePtrS1_, OK); - BlockSync(kvDelegatePtrS2_, OK); - BlockSync(kvDelegatePtrS3_, OK, SyncMode::SYNC_MODE_CLOUD_MERGE, SECURITY_OPTION_CHECK_ERROR); + KvStoreNbDelegate::Option option; + option.secOption.securityLabel = S4; + EXPECT_EQ(GetKvStore(kvDelegatePtrS3_, STORE_ID_3, option), OK); + BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption); + BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption); + BlockSync(kvDelegatePtrS3_, OK, g_CloudSyncoption, SECURITY_OPTION_CHECK_ERROR); + CloseKvStore(kvDelegatePtrS3_, STORE_ID_3); +} + +/** + * @tc.name: NormalSync012 + * @tc.desc: Test normal push sync with memory db. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBCloudKvTest, NormalSync012, TestSize.Level0) +{ + KvStoreNbDelegate *memoryDB1 = nullptr; + KvStoreNbDelegate::Option option1; + option1.isMemoryDb = true; + GetKvStore(memoryDB1, STORE_ID_3, option1); + ASSERT_NE(memoryDB1, nullptr); + KvStoreNbDelegate *memoryDB2 = nullptr; + KvStoreNbDelegate::Option option2; + option2.isMemoryDb = true; + GetKvStore(memoryDB2, STORE_ID_4, option2); + EXPECT_NE(memoryDB2, nullptr); + Key key1 = {'k', '1'}; + Value expectValue1 = {'v', '1'}; + EXPECT_EQ(memoryDB1->Put(key1, expectValue1), OK); + BlockSync(memoryDB1, OK, g_CloudSyncoption); + BlockSync(memoryDB2, OK, g_CloudSyncoption); + EXPECT_EQ(g_mgr.CloseKvStore(memoryDB1), OK); + EXPECT_EQ(g_mgr.CloseKvStore(memoryDB2), OK); +} + +/** + * @tc.name: NormalSync013 + * @tc.desc: Test the wrong schema. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liaoyonghuang + */ +HWTEST_F(DistributedDBCloudKvTest, NormalSync013, TestSize.Level0) +{ + KvStoreNbDelegate* kvDelegatePtrS3_ = nullptr; + KvStoreNbDelegate::Option option; + EXPECT_EQ(GetKvStore(kvDelegatePtrS3_, STORE_ID_3, option, true), INVALID_SCHEMA); CloseKvStore(kvDelegatePtrS3_, STORE_ID_3); } -void DistributedDBCloudKvTest::SetFlag(const Key &key, bool isCloudFlag) +/** + * @tc.name: NormalSync014 + * @tc.desc: Test sync after user change. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liaoyonghuang + */ +HWTEST_F(DistributedDBCloudKvTest, NormalSync014, TestSize.Level1) +{ + g_mgr.SetSyncActivationCheckCallback([] (const std::string &userId, const std::string &appId, + const std::string &storeId)-> bool { + return true; + }); + + KvStoreNbDelegate* kvDelegatePtrS3_ = nullptr; + KvStoreNbDelegate::Option option; + option.syncDualTupleMode = true; + GetKvStore(kvDelegatePtrS3_, STORE_ID_3, option); + Key key = {'k', '1'}; + Value value = {'v', '1'}; + ASSERT_EQ(kvDelegatePtrS3_->Put(key, value), OK); + + virtualCloudDb_->SetBlockTime(2000); // 2000ms + std::thread thread([&]() { + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // sleep for 1000ms + g_mgr.SetSyncActivationCheckCallback([] (const std::string &userId, const std::string &appId, + const std::string &storeId)-> bool { + return false; + }); + RuntimeContext::GetInstance()->NotifyUserChanged(); + }); + BlockSync(kvDelegatePtrS3_, USER_CHANGED, g_CloudSyncoption); + thread.join(); + CloseKvStore(kvDelegatePtrS3_, STORE_ID_3); +} + +/** + * @tc.name: NormalSync015 + * @tc.desc: Test sync in all process. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBCloudKvTest, NormalSync015, TestSize.Level0) +{ + Key key = {'k'}; + Value expectValue = {'v'}; + ASSERT_EQ(kvDelegatePtrS1_->Put(key, expectValue), OK); + auto option = g_CloudSyncoption; + auto action = static_cast(LockAction::INSERT) | static_cast(LockAction::UPDATE) + | static_cast(LockAction::DELETE) | static_cast(LockAction::DOWNLOAD); + option.lockAction = static_cast(action); + BlockSync(kvDelegatePtrS1_, OK, option); + for (const auto &table : lastProcess_.tableProcess) { + EXPECT_EQ(table.second.upLoadInfo.total, 1u); + } + BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption); + Value actualValue; + EXPECT_EQ(kvDelegatePtrS2_->Get(key, actualValue), OK); + EXPECT_EQ(actualValue, expectValue); +} + +/** + * @tc.name: NormalSync016 + * @tc.desc: Device A and device B have the same key data, + * and then devices B and A perform cloud synchronization sequentially. + * Finally, device A updates the data and performs cloud synchronization. + * Test if there is new data inserted into the cloud database. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liaoyonghuang + */ +HWTEST_F(DistributedDBCloudKvTest, NormalSync016, TestSize.Level0) +{ + Key key = {'k', '1'}; + Value value1 = {'v', '1'}; + ASSERT_EQ(kvDelegatePtrS1_->Put(key, value1), OK); + Value value2 = {'v', '2'}; + ASSERT_EQ(kvDelegatePtrS2_->Put(key, value2), OK); + BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption); + BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption); + + Value value3 = {'v', '3'}; + ASSERT_EQ(kvDelegatePtrS1_->Put(key, value3), OK); + virtualCloudDb_->SetInsertHook([](VBucket &record) { + for (auto &recordData : record) { + std::string insertKey = "key"; + Type insertValue = "k1"; + EXPECT_FALSE(recordData.first == insertKey && recordData.second == insertValue); + } + }); + BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption); + virtualCloudDb_->SetInsertHook(nullptr); +} + +/** + * @tc.name: NormalSync017 + * @tc.desc: Test duplicate addition, deletion, and sync. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liaoyonghuang + */ +HWTEST_F(DistributedDBCloudKvTest, NormalSync017, TestSize.Level0) +{ + Key key = {'k'}; + Value value = {'v'}; + ASSERT_EQ(kvDelegatePtrS1_->Put(key, value), OK); + BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption); + ASSERT_EQ(kvDelegatePtrS1_->Delete(key), OK); + BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption); + ASSERT_EQ(kvDelegatePtrS1_->Put(key, value), OK); + BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption); +} + +/** + * @tc.name: NormalSync018 + * @tc.desc: Test putBatch and sync with memory db. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liaoyonghuang + */ +HWTEST_F(DistributedDBCloudKvTest, NormalSync018, TestSize.Level0) +{ + /** + * @tc.steps:step1. Get two Memory DB. + * @tc.expected: step1 OK. + */ + KvStoreNbDelegate *memoryDB1 = nullptr; + KvStoreNbDelegate::Option option1; + option1.isMemoryDb = true; + GetKvStore(memoryDB1, STORE_ID_3, option1); + ASSERT_NE(memoryDB1, nullptr); + KvStoreNbDelegate *memoryDB2 = nullptr; + KvStoreNbDelegate::Option option2; + option2.isMemoryDb = true; + GetKvStore(memoryDB2, STORE_ID_4, option2); + EXPECT_NE(memoryDB2, nullptr); + + /** + * @tc.steps:step2. put 301 records and sync to cloud. + * @tc.expected: step2 OK. + */ + vector entries; + int count = 301; // put 301 records. + for (int i = 0; i < count; i++) { + std::string keyStr = "k_" + std::to_string(i); + std::string valueStr = "v_" + std::to_string(i); + Key key(keyStr.begin(), keyStr.end()); + Value value(valueStr.begin(), valueStr.end()); + entries.push_back({key, value}); + } + EXPECT_EQ(memoryDB1->PutBatch(entries), OK); + BlockSync(memoryDB1, OK, g_CloudSyncoption); + + /** + * @tc.steps:step3. Sync from cloud and check values. + * @tc.expected: step3 OK. + */ + BlockSync(memoryDB2, OK, g_CloudSyncoption); + for (int i = 0; i < count; i++) { + std::string keyStr = "k_" + std::to_string(i); + std::string valueStr = "v_" + std::to_string(i); + Key key(keyStr.begin(), keyStr.end()); + Value expectValue(valueStr.begin(), valueStr.end()); + Value actualValue; + EXPECT_EQ(memoryDB2->Get(key, actualValue), OK); + EXPECT_EQ(actualValue, expectValue); + } + EXPECT_EQ(g_mgr.CloseKvStore(memoryDB1), OK); + EXPECT_EQ(g_mgr.CloseKvStore(memoryDB2), OK); +} + +/** + * @tc.name: NormalSync019 + * @tc.desc: Test dataItem has same time. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBCloudKvTest, NormalSync019, TestSize.Level0) +{ + Key k1 = {'k', '1'}; + Value v1 = {'v', '1'}; + ASSERT_EQ(kvDelegatePtrS2_->Put(k1, v1), OK); + deviceB_->Sync(SyncMode::SYNC_MODE_PULL_ONLY, true); + + VirtualDataItem dataItem; + deviceB_->GetData(k1, dataItem); + EXPECT_EQ(dataItem.timestamp, dataItem.writeTimestamp); +} + +/** + * @tc.name: NormalSync020 + * @tc.desc: Test sync with two users. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liaoyonghuang + */ +HWTEST_F(DistributedDBCloudKvTest, NormalSync020, TestSize.Level0) +{ + /** + * @tc.steps:step1. Inserts a piece of data. + * @tc.expected: step1 OK. + */ + Key k1 = {'k', '1'}; + Value v1 = {'v', '1'}; + ASSERT_EQ(kvDelegatePtrS1_->Put(k1, v1), OK); + /** + * @tc.steps:step2. sync with two users. + * @tc.expected: step2 OK. + */ + CloudSyncOption option; + option.mode = SyncMode::SYNC_MODE_CLOUD_MERGE; + option.users.push_back(USER_ID); + option.users.push_back(USER_ID_2); + option.devices.push_back("cloud"); + BlockSync(kvDelegatePtrS1_, OK, option); + /** + * @tc.steps:step3. Check upLoadInfo.batchIndex of two users. + * @tc.expected: Both users have a upLoadInfo.batchIndex of 1. + */ + for (const auto &table : lastProcess_.tableProcess) { + EXPECT_EQ(table.second.upLoadInfo.batchIndex, 1u); + } +} + +/** + * @tc.name: NormalSync021 + * @tc.desc: Test Get Func to get cloudVersion. + * @tc.type: FUNC + * @tc.require: + * @tc.author: caihaoting + */ +HWTEST_F(DistributedDBCloudKvTest, NormalSync021, TestSize.Level0) +{ + /** + * @tc.steps:step1. store2 GetCloudVersion. + * @tc.expected: step1 OK. + */ + Key key = {'k'}; + Value expectValue = {'v'}; + ASSERT_EQ(kvDelegatePtrS1_->Put(key, expectValue), OK); + kvDelegatePtrS1_->SetGenCloudVersionCallback([](const std::string &origin) { + LOGW("origin is %s", origin.c_str()); + return origin + "1"; + }); + BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption); + for (const auto &table : lastProcess_.tableProcess) { + EXPECT_EQ(table.second.upLoadInfo.total, 1u); + } + BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption); + Value actualValue; + EXPECT_EQ(kvDelegatePtrS2_->Get(key, actualValue), OK); + EXPECT_EQ(actualValue, expectValue); + kvDelegatePtrS1_->SetGenCloudVersionCallback(nullptr); + auto result = kvDelegatePtrS2_->GetCloudVersion(""); + EXPECT_EQ(result.first, OK); + for (auto item : result.second) { + EXPECT_EQ(item.second, "1"); + } + /** + * @tc.steps:step2. store2 GetCloudVersion. + * @tc.expected: step2 NOT_FOUND. + */ + Key keyB; + Value actualValueB; + std::string deviceB = DBCommon::TransferStringToHex(DBCommon::TransferHashString("DEVICE_B")); + std::string versionDeviceBStr = "naturalbase_cloud_version_" + deviceB; + const char *buffer = versionDeviceBStr.c_str(); + for (uint32_t i = 0; i < versionDeviceBStr.size(); i++) { + keyB.emplace_back(buffer[i]); + } + EXPECT_EQ(kvDelegatePtrS2_->Get(keyB, actualValueB), NOT_FOUND); +} + +/** + * @tc.name: NormalSync022 + * @tc.desc: Test Cloud sync without schema. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBCloudKvTest, NormalSync022, TestSize.Level0) +{ + /** + * @tc.steps:step1. Get Memory DB. + * @tc.expected: step1 OK. + */ + KvStoreNbDelegate *memoryDB1 = nullptr; + KvStoreNbDelegate::Option option; + option.isMemoryDb = true; + DBStatus openRet = OK; + g_mgr.GetKvStore(STORE_ID_4, option, [&openRet, &memoryDB1](DBStatus status, KvStoreNbDelegate *openDelegate) { + openRet = status; + memoryDB1 = openDelegate; + }); + EXPECT_EQ(openRet, OK); + ASSERT_NE(memoryDB1, nullptr); + /** + * @tc.steps:step2. Sync without cloud schema. + * @tc.expected: step2 CLOUD_ERROR. + */ + BlockSync(memoryDB1, OK, g_CloudSyncoption, CLOUD_ERROR); + std::map> cloudDbs; + cloudDbs[USER_ID] = virtualCloudDb_; + cloudDbs[USER_ID_2] = virtualCloudDb2_; + memoryDB1->SetCloudDB(cloudDbs); + BlockSync(memoryDB1, OK, g_CloudSyncoption, CLOUD_ERROR); + EXPECT_EQ(g_mgr.CloseKvStore(memoryDB1), OK); +} + +/** + * @tc.name: NormalSync023 + * @tc.desc: Test normal local delete before cloud delete. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBCloudKvTest, NormalSync023, TestSize.Level0) +{ + Key k1 = {'k', '1'}; + Value v1 = {'v', '1'}; + ASSERT_EQ(kvDelegatePtrS1_->Put(k1, v1), OK); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep 100ms + BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption); + BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption); + ASSERT_EQ(kvDelegatePtrS2_->Delete(k1), OK); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep 100ms + ASSERT_EQ(kvDelegatePtrS1_->Delete(k1), OK); + BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption); + BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption); +} + +/** + * @tc.name: NormalSync024 + * @tc.desc: Test duplicate addition, deletion, and sync. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liaoyonghuang + */ +HWTEST_F(DistributedDBCloudKvTest, NormalSync024, TestSize.Level0) +{ + /** + * @tc.steps:step1. Device A inserts data and synchronizes, then Device B synchronizes. + * @tc.expected: step1 OK. + */ + Key key = {'k'}; + Value value = {'v'}; + ASSERT_EQ(kvDelegatePtrS1_->Put(key, value), OK); + BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption); + BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption); + /** + * @tc.steps:step2. Device A deletes data and synchronizes, then Device B synchronizes. + * @tc.expected: step2 OK. + */ + ASSERT_EQ(kvDelegatePtrS1_->Delete(key), OK); + BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption); + BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption); + /** + * @tc.steps:step3. Device B inserts data and synchronizes it. + * @tc.expected: step3 OK. + */ + int insertNum = 0; + virtualCloudDb_->SetInsertHook([&insertNum](VBucket &record) { + insertNum++; + }); + ASSERT_EQ(kvDelegatePtrS2_->Put(key, value), OK); + BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption); + EXPECT_TRUE(insertNum > 0); + virtualCloudDb_->SetInsertHook(nullptr); +} + +/** + * @tc.name: NormalSync026 + * @tc.desc: Test delete when sync mode DEVICE_COLLABORATION. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liaoyonghuang + */ +HWTEST_F(DistributedDBCloudKvTest, NormalSync026, TestSize.Level0) +{ + /** + * @tc.steps:step1. Create a database with the DEVICE_COLLABORATION mode on device1. + * @tc.expected: step1 OK. + */ + KvStoreNbDelegate* kvDelegatePtrS3_ = nullptr; + KvStoreNbDelegate::Option option; + option.conflictResolvePolicy = DEVICE_COLLABORATION; + EXPECT_EQ(GetKvStore(kvDelegatePtrS3_, STORE_ID_3, option), OK); + /** + * @tc.steps:step2. put 1 record and sync. + * @tc.expected: step2 OK. + */ + Key key = {'k'}; + Value expectValue1 = {'v', '1'}; + ASSERT_EQ(kvDelegatePtrS3_->Put(key, expectValue1), OK); + BlockSync(kvDelegatePtrS3_, OK, g_CloudSyncoption); + /** + * @tc.steps:step3. Update this record on device2. + * @tc.expected: step3 OK. + */ + BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption); + ASSERT_EQ(kvDelegatePtrS1_->Delete(key), OK); + BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption); + /** + * @tc.steps:step4. device1 sync. + * @tc.expected: The record was not covered by the cloud and cloud was covered. + */ + BlockSync(kvDelegatePtrS3_, OK, g_CloudSyncoption); + Value actualValue1; + EXPECT_EQ(kvDelegatePtrS3_->Get(key, actualValue1), OK); + EXPECT_EQ(actualValue1, expectValue1); + CloseKvStore(kvDelegatePtrS3_, STORE_ID_3); +} + +/** + * @tc.name: SyncOptionCheck001 + * @tc.desc: Test sync without user. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liaoyonghuang + */ +HWTEST_F(DistributedDBCloudKvTest, SyncOptionCheck001, TestSize.Level0) +{ + /** + * @tc.steps:step1. Device 1 inserts a piece of data. + * @tc.expected: step1 OK. + */ + Key key = {'k'}; + Value value = {'v'}; + ASSERT_EQ(kvDelegatePtrS1_->Put(key, value), OK); + /** + * @tc.steps:step2. Set option without user, and attempt to sync + * @tc.expected: step2 return INVALID_ARGS. + */ + CloudSyncOption option; + option.mode = SyncMode::SYNC_MODE_CLOUD_MERGE; + option.devices.push_back("cloud"); + BlockSync(kvDelegatePtrS1_, OK, option, INVALID_ARGS); + /** + * @tc.steps:step3. Device 2 sync and attempt to get data. + * @tc.expected: step3 sync OK but data NOT_FOUND. + */ + BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption); + Value actualValue; + EXPECT_EQ(kvDelegatePtrS2_->Get(key, actualValue), NOT_FOUND); +} + +/** + * @tc.name: SyncOptionCheck002 + * @tc.desc: Test sync with invalid waitTime. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liaoyonghuang + */ +HWTEST_F(DistributedDBCloudKvTest, SyncOptionCheck002, TestSize.Level0) +{ + /** + * @tc.steps:step1. Device 1 inserts a piece of data. + * @tc.expected: step1 OK. + */ + Key key = {'k'}; + Value value = {'v'}; + ASSERT_EQ(kvDelegatePtrS1_->Put(key, value), OK); + /** + * @tc.steps:step2. Set invalid waitTime of sync option and sync. + * @tc.expected: step2 return INVALID_ARGS. + */ + CloudSyncOption option; + option.mode = SyncMode::SYNC_MODE_CLOUD_MERGE; + option.users.push_back(USER_ID); + option.devices.push_back("cloud"); + option.waitTime = -2; // -2 is invalid waitTime. + BlockSync(kvDelegatePtrS1_, OK, option, INVALID_ARGS); + /** + * @tc.steps:step3. Device 2 sync and attempt to get data. + * @tc.expected: step3 sync OK but data NOT_FOUND. + */ + BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption); + Value actualValue; + EXPECT_EQ(kvDelegatePtrS2_->Get(key, actualValue), NOT_FOUND); +} + +/** + * @tc.name: SyncOptionCheck003 + * @tc.desc: Test sync with users which have not been sync to cloud. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liaoyonghuang + */ +HWTEST_F(DistributedDBCloudKvTest, SyncOptionCheck003, TestSize.Level0) +{ + /** + * @tc.steps:step1. Device 1 inserts a piece of data. + * @tc.expected: step1 OK. + */ + Key key = {'k'}; + Value value = {'v'}; + ASSERT_EQ(kvDelegatePtrS1_->Put(key, value), OK); + /** + * @tc.steps:step2. Set user1 and user3 to option and sync. + * @tc.expected: step2 return INVALID_ARGS. + */ + CloudSyncOption option; + option.mode = SyncMode::SYNC_MODE_CLOUD_MERGE; + option.users.push_back(USER_ID); + option.users.push_back(USER_ID_3); + option.devices.push_back("cloud"); + BlockSync(kvDelegatePtrS1_, OK, option, INVALID_ARGS); + /** + * @tc.steps:step3. Device 2 sync and attempt to get data. + * @tc.expected: step3 sync OK but data NOT_FOUND. + */ + BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption); + Value actualValue; + EXPECT_EQ(kvDelegatePtrS2_->Get(key, actualValue), NOT_FOUND); +} + +/** + * @tc.name: SyncOptionCheck004 + * @tc.desc: Test sync with user when schema is not same. + * @tc.type: FUNC + * @tc.require: + * @tc.author: caihaoting + */ +HWTEST_F(DistributedDBCloudKvTest, SyncOptionCheck004, TestSize.Level0) +{ + /** + * @tc.steps:step1. Device 1 inserts a piece of data. + * @tc.expected: step1 OK. + */ + Key key = {'k'}; + Value value = {'v'}; + ASSERT_EQ(kvDelegatePtrS1_->Put(key, value), OK); + /** + * @tc.steps:step2. Set user1 to option and user2 to schema and sync. + * @tc.expected: step2 return SCHEMA_MISMATCH. + */ + CloudSyncOption option; + option.mode = SyncMode::SYNC_MODE_CLOUD_MERGE; + option.users.push_back(USER_ID); + option.devices.push_back("cloud"); + std::map schemas; + schemas[USER_ID_2] = GetDataBaseSchema(false); + kvDelegatePtrS1_->SetCloudDbSchema(schemas); + BlockSync(kvDelegatePtrS1_, OK, option, SCHEMA_MISMATCH); +} + +/** + * @tc.name: SyncOptionCheck005 + * @tc.desc: Testing registration of observer exceeded the upper limit. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liaoyonghuang + */ +HWTEST_F(DistributedDBCloudKvTest, SyncOptionCheck005, TestSize.Level0) +{ + /** + * @tc.steps:step1. Register MAX_OBSERVER_COUNT observers. + * @tc.expected: step1 OK. + */ + std::vector observerList; + for (int i = 0; i < DBConstant::MAX_OBSERVER_COUNT; i++) { + auto *observer = new (std::nothrow) KvStoreObserverUnitTest; + observerList.push_back(observer); + EXPECT_EQ(kvDelegatePtrS1_->RegisterObserver({}, OBSERVER_CHANGES_CLOUD, observer), OK); + } + /** + * @tc.steps:step2. Register one more observer. + * @tc.expected: step2 Registration failed, return OVER_MAX_LIMITS. + */ + auto *overMaxObserver = new (std::nothrow) KvStoreObserverUnitTest; + EXPECT_EQ(kvDelegatePtrS1_->RegisterObserver({}, OBSERVER_CHANGES_CLOUD, overMaxObserver), OVER_MAX_LIMITS); + /** + * @tc.steps:step3. UnRegister all observers. + * @tc.expected: step3 OK. + */ + EXPECT_EQ(kvDelegatePtrS1_->UnRegisterObserver(overMaxObserver), NOT_FOUND); + delete overMaxObserver; + overMaxObserver = nullptr; + for (auto &observer : observerList) { + EXPECT_EQ(kvDelegatePtrS1_->UnRegisterObserver(observer), OK); + delete observer; + observer = nullptr; + } +} + +void DistributedDBCloudKvTest::SetFlag(const Key &key, LogInfoFlag flag) { sqlite3 *db_; - uint64_t flag = SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; + uint64_t openFlag = SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; std::string fileUrl = g_testDir + "/" \ "2d23c8a0ffadafcaa03507a4ec2290c83babddcab07c0e2945fbba93efc7eec0/single_ver/main/gen_natural_store.db"; - ASSERT_TRUE(sqlite3_open_v2(fileUrl.c_str(), &db_, flag, nullptr) == SQLITE_OK); + ASSERT_TRUE(sqlite3_open_v2(fileUrl.c_str(), &db_, openFlag, nullptr) == SQLITE_OK); int errCode = E_OK; - std::string sql; - if (isCloudFlag) { - sql = "UPDATE sync_data SET flag=256 WHERE Key=?"; - } else { - sql = "UPDATE sync_data SET flag=2 WHERE Key=?"; - } + std::string sql = "UPDATE sync_data SET flag=? WHERE Key=?"; sqlite3_stmt *statement = nullptr; errCode = SQLiteUtils::GetStatement(db_, sql, statement); if (errCode != E_OK) { SQLiteUtils::ResetStatement(statement, true, errCode); } ASSERT_EQ(errCode, E_OK); - errCode = SQLiteUtils::BindBlobToStatement(statement, 1, key, true); // only one arg. + errCode = SQLiteUtils::BindInt64ToStatement(statement, 1, static_cast(flag)); // 1st arg. + ASSERT_EQ(errCode, E_OK); + errCode = SQLiteUtils::BindBlobToStatement(statement, 2, key, true); // 2nd arg. ASSERT_EQ(errCode, E_OK); if (errCode != E_OK) { SQLiteUtils::ResetStatement(statement, true, errCode); @@ -534,22 +1241,17 @@ void DistributedDBCloudKvTest::SetFlag(const Key &key, bool isCloudFlag) sqlite3_close_v2(db_); } -int DistributedDBCloudKvTest::CheckFlag(const Key &key, bool isCloudFlag) +int DistributedDBCloudKvTest::CheckFlag(const Key &key, LogInfoFlag flag) { sqlite3 *db_; - uint64_t flag = SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; + uint64_t openFlag = SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; std::string fileUrl = g_testDir + "/" \ "2d23c8a0ffadafcaa03507a4ec2290c83babddcab07c0e2945fbba93efc7eec0/single_ver/main/gen_natural_store.db"; - int errCode = sqlite3_open_v2(fileUrl.c_str(), &db_, flag, nullptr); + int errCode = sqlite3_open_v2(fileUrl.c_str(), &db_, openFlag, nullptr); if (errCode != E_OK) { return NOT_FOUND; } - std::string sql; - if (isCloudFlag) { - sql = "SELECT * FROM sync_data WHERE Key =? AND (flag=0x100)"; - } else { - sql = "SELECT * FROM sync_data WHERE Key =? AND (flag=0x02)"; - } + std::string sql = "SELECT * FROM sync_data WHERE Key =? AND (flag=?)"; sqlite3_stmt *statement = nullptr; errCode = SQLiteUtils::GetStatement(db_, sql, statement); if (errCode != E_OK) { @@ -557,7 +1259,12 @@ int DistributedDBCloudKvTest::CheckFlag(const Key &key, bool isCloudFlag) return NOT_FOUND; } std::vector keyVec(key.begin(), key.end()); - errCode = SQLiteUtils::BindBlobToStatement(statement, 1, keyVec, true); // only one arg. + errCode = SQLiteUtils::BindBlobToStatement(statement, 1, keyVec, true); // 1st arg. + if (errCode != E_OK) { + SQLiteUtils::ResetStatement(statement, true, errCode); + return NOT_FOUND; + } + errCode = SQLiteUtils::BindInt64ToStatement(statement, 2, static_cast(flag)); // 2nd arg. if (errCode != E_OK) { SQLiteUtils::ResetStatement(statement, true, errCode); return NOT_FOUND; @@ -672,7 +1379,7 @@ int DistributedDBCloudKvTest::CheckLogTable(const std::string &deviceId) return NOT_FOUND; } std::string sql = "SELECT * FROM naturalbase_kv_aux_sync_data_log WHERE hash_key IN" \ - "(SELECT hash_key FROM sync_data WHERE device =? AND (flag=0x100));"; + "(SELECT hash_key FROM sync_data WHERE device =?);"; sqlite3_stmt *statement = nullptr; errCode = SQLiteUtils::GetStatement(db_, sql, statement); if (errCode != E_OK) { @@ -722,8 +1429,7 @@ int DistributedDBCloudKvTest::ChangeUserId(const std::string &deviceId, const st return INVALID_ARGS; } int bindIndex = 1; - std::vector wantUserIdVec(wantUserId.begin(), wantUserId.end()); - errCode = SQLiteUtils::BindBlobToStatement(statement, bindIndex, wantUserIdVec, true); // only one arg. + errCode = SQLiteUtils::BindTextToStatement(statement, bindIndex, wantUserId); // only one arg. if (errCode != E_OK) { SQLiteUtils::ResetStatement(statement, true, errCode); return INVALID_ARGS; @@ -796,8 +1502,8 @@ void DistributedDBCloudKvTest::InsertRecord(int num) value.push_back('k'); value.push_back('0' + i); ASSERT_EQ(kvDelegatePtrS1_->Put(key, value), OK); - BlockSync(kvDelegatePtrS1_, OK); - SetFlag(key, true); + BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption); + SetFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE); std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep for 100ms } } @@ -822,7 +1528,7 @@ HWTEST_F(DistributedDBCloudKvTest, RemoveDeviceTest001, TestSize.Level0) Key key; key.push_back('k'); key.push_back('0' + i); - SetFlag(key, true); + SetFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE); SetDeviceId(key, std::to_string(i)); std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep for 100ms } @@ -838,7 +1544,7 @@ HWTEST_F(DistributedDBCloudKvTest, RemoveDeviceTest001, TestSize.Level0) EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), OK); std::string deviceId = std::to_string(i); EXPECT_EQ(CheckLogTable(deviceId), OK); - EXPECT_EQ(CheckFlag(key, true), OK); + EXPECT_EQ(CheckFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE), OK); EXPECT_EQ(CheckWaterMark(""), OK); } /** @@ -854,7 +1560,7 @@ HWTEST_F(DistributedDBCloudKvTest, RemoveDeviceTest001, TestSize.Level0) EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), OK); std::string deviceId = std::to_string(i); EXPECT_EQ(CheckLogTable(deviceId), NOT_FOUND); - EXPECT_EQ(CheckFlag(key, false), OK); + EXPECT_EQ(CheckFlag(key, LogInfoFlag::FLAG_LOCAL), OK); EXPECT_EQ(CheckWaterMark(""), NOT_FOUND); } } @@ -879,7 +1585,7 @@ HWTEST_F(DistributedDBCloudKvTest, RemoveDeviceTest002, TestSize.Level0) Key key; key.push_back('k'); key.push_back('0' + i); - SetFlag(key, true); + SetFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE); SetDeviceId(key, std::to_string(i)); std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep for 100ms } @@ -934,7 +1640,7 @@ HWTEST_F(DistributedDBCloudKvTest, RemoveDeviceTest003, TestSize.Level0) Key key; key.push_back('k'); key.push_back('0' + i); - SetFlag(key, true); + SetFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE); SetDeviceId(key, std::to_string(i)); std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep for 100ms } @@ -950,7 +1656,7 @@ HWTEST_F(DistributedDBCloudKvTest, RemoveDeviceTest003, TestSize.Level0) EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), OK); std::string deviceId = std::to_string(i); EXPECT_EQ(CheckLogTable(deviceId), OK); - EXPECT_EQ(CheckFlag(key, true), OK); // flag become 0x2; + EXPECT_EQ(CheckFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE), OK); // flag become 0x2; EXPECT_EQ(CheckWaterMark(""), OK); } /** @@ -964,7 +1670,7 @@ HWTEST_F(DistributedDBCloudKvTest, RemoveDeviceTest003, TestSize.Level0) Value actualValue; EXPECT_EQ(kvDelegatePtrS1_->Get(key1, actualValue), OK); EXPECT_EQ(CheckLogTable(deviceId1), NOT_FOUND); - EXPECT_EQ(CheckFlag(key1, false), OK); // flag become 0x2; + EXPECT_EQ(CheckFlag(key1, LogInfoFlag::FLAG_LOCAL), OK); // flag become 0x2; Key key2({'k', '2'}); std::string deviceId2 = "2"; EXPECT_EQ(kvDelegatePtrS1_->Get(key2, actualValue), NOT_FOUND); @@ -993,11 +1699,11 @@ HWTEST_F(DistributedDBCloudKvTest, RemoveDeviceTest004, TestSize.Level0) Key key; key.push_back('k'); key.push_back('0' + i); - SetFlag(key, true); + SetFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE); SetDeviceId(key, std::to_string(i)); ChangeUserId(std::to_string(i), userHead + std::to_string(i)); std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep for 100ms - EXPECT_EQ(CheckFlag(key, true), OK); + EXPECT_EQ(CheckFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE), OK); } EXPECT_EQ(CheckWaterMark(userHead + "0"), OK); /** @@ -1024,7 +1730,7 @@ HWTEST_F(DistributedDBCloudKvTest, RemoveDeviceTest004, TestSize.Level0) Value actualValue; EXPECT_EQ(kvDelegatePtrS1_->Get(key0, actualValue), OK); EXPECT_EQ(CheckLogTable(deviceId1), NOT_FOUND); - EXPECT_EQ(CheckFlag(key0, false), OK); // flag become 0x2; + EXPECT_EQ(CheckFlag(key0, LogInfoFlag::FLAG_LOCAL), OK); // flag become 0x2; EXPECT_EQ(CheckWaterMark(userHead + "0"), NOT_FOUND); Key key2({'k', '2'}); std::string deviceId2 = "2"; @@ -1053,7 +1759,7 @@ HWTEST_F(DistributedDBCloudKvTest, RemoveDeviceTest005, TestSize.Level0) Key key; key.push_back('k'); key.push_back('0' + i); - SetFlag(key, true); + SetFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE); SetDeviceId(key, std::to_string(i)); ChangeUserId(std::to_string(i), userHead + std::to_string(i)); std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep for 100ms @@ -1071,7 +1777,7 @@ HWTEST_F(DistributedDBCloudKvTest, RemoveDeviceTest005, TestSize.Level0) EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), OK); std::string deviceId = std::to_string(i); EXPECT_EQ(CheckLogTable(deviceId), OK); - EXPECT_EQ(CheckFlag(key, true), OK); + EXPECT_EQ(CheckFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE), OK); } /** * @tc.steps: step3. remove "user1" userid log data with FLAG_AND_DATA, remove "user0" userid with FLAG_ONLY. @@ -1089,7 +1795,7 @@ HWTEST_F(DistributedDBCloudKvTest, RemoveDeviceTest005, TestSize.Level0) Value actualValue; EXPECT_EQ(kvDelegatePtrS1_->Get(key0, actualValue), OK); EXPECT_EQ(CheckLogTable(deviceId0), NOT_FOUND); - EXPECT_EQ(CheckFlag(key0, false), OK); // flag become 0x2; + EXPECT_EQ(CheckFlag(key0, LogInfoFlag::FLAG_LOCAL), OK); // flag become 0x2; EXPECT_EQ(CheckWaterMark(userHead + "0"), NOT_FOUND); Key key1({'k', '1'}); EXPECT_EQ(kvDelegatePtrS1_->Get(key1, actualValue), NOT_FOUND); @@ -1120,7 +1826,7 @@ HWTEST_F(DistributedDBCloudKvTest, RemoveDeviceTest006, TestSize.Level0) Key key; key.push_back('k'); key.push_back('0' + i); - SetFlag(key, true); + SetFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE); SetDeviceId(key, std::to_string(i)); ChangeUserId(std::to_string(i), userHead + std::to_string(i)); std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep for 100ms @@ -1156,7 +1862,7 @@ HWTEST_F(DistributedDBCloudKvTest, RemoveDeviceTest006, TestSize.Level0) EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId1, "user2", ClearMode::FLAG_AND_DATA), OK); EXPECT_EQ(kvDelegatePtrS1_->Get(key1, actualValue), OK); EXPECT_EQ(CheckLogTable(deviceId1), OK); // only user0 match the hash_key that same as device1. - EXPECT_EQ(CheckFlag(key1, true), OK); // flag still 0x100; + EXPECT_EQ(CheckFlag(key1, LogInfoFlag::FLAG_CLOUD_WRITE), OK); // flag still 0x100; EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId1, "user0", ClearMode::FLAG_AND_DATA), OK); // all log have been deleted, so data would also be deleted. EXPECT_EQ(kvDelegatePtrS1_->Get(key1, actualValue), NOT_FOUND); @@ -1192,4 +1898,130 @@ HWTEST_F(DistributedDBCloudKvTest, RemoveDeviceTest007, TestSize.Level0) EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId, ClearMode::CLEAR_SHARED_TABLE), NOT_SUPPORT); EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId, "user1", ClearMode::CLEAR_SHARED_TABLE), NOT_SUPPORT); } + +/** + * @tc.name: RemoveDeviceTest008 + * @tc.desc: remove record without mode. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liaoyonnghuang + */ +HWTEST_F(DistributedDBCloudKvTest, RemoveDeviceTest008, TestSize.Level0) +{ + /** + * @tc.steps: step1. Insert three record (Key:k0, device:0, userId:user0), (Key:k1, device:1, userId:user1), + * (Key:k2, device:2, userId:2) + * * @tc.expected: step1. insert successfully + */ + int recordNum = 3; + InsertRecord(recordNum); + for (int i = 0; i < recordNum; i++) { + Key key; + key.push_back('k'); + key.push_back('0' + i); + SetFlag(key, LogInfoFlag::FLAG_CLOUD); + SetDeviceId(key, std::to_string(i)); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep for 100ms + } + + /** + * @tc.steps: step2. Check three Log record whether exist or not; + * * @tc.expected: step2. record exist + */ + for (int i = 0; i < recordNum; i++) { + Key key; + key.push_back('k'); + key.push_back('0' + i); + Value actualValue; + EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), OK); + } + /** + * @tc.steps: step3. Remove data without mode. + * * @tc.expected: step3. remove OK, there are not user record exist in log table. + */ + for (int i = 0; i < recordNum; i++) { + EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(std::to_string(i)), OK); + } + for (int i = 0; i < recordNum; i++) { + Key key; + key.push_back('k'); + key.push_back('0' + i); + Value actualValue; + EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), NOT_FOUND); + } +} + +/** + * @tc.name: RemoveDeviceTest009 + * @tc.desc: remove record without mode FLAG_AND_DATA. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liaoyonnghuang + */ +HWTEST_F(DistributedDBCloudKvTest, RemoveDeviceTest009, TestSize.Level0) +{ + /** + * @tc.steps: step1. Insert three record (Key:k0, device:0, userId:user0), (Key:k1, device:1, userId:user1), + * (Key:k2, device:2, userId:2) + * * @tc.expected: step1. insert successfully + */ + int recordNum = 3; + InsertRecord(recordNum); + for (int i = 0; i < recordNum; i++) { + Key key; + key.push_back('k'); + key.push_back('0' + i); + SetFlag(key, LogInfoFlag::FLAG_CLOUD); + SetDeviceId(key, std::to_string(i)); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep for 100ms + } + + /** + * @tc.steps: step2. Check three Log record whether exist or not; + * * @tc.expected: step2. record exist + */ + for (int i = 0; i < recordNum; i++) { + Key key; + key.push_back('k'); + key.push_back('0' + i); + Value actualValue; + EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), OK); + std::string deviceId = std::to_string(i); + EXPECT_EQ(CheckLogTable(deviceId), OK); + } + /** + * @tc.steps: step3. Remove data without mode FLAG_AND_DATA. + * * @tc.expected: step3. remove OK, there are not user record exist in log table. + */ + for (int i = 0; i < recordNum; i++) { + EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(std::to_string(i), ClearMode::FLAG_AND_DATA), OK); + } + for (int i = 0; i < recordNum; i++) { + Key key; + key.push_back('k'); + key.push_back('0' + i); + Value actualValue; + EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), OK); + std::string deviceId = std::to_string(i); + EXPECT_EQ(CheckLogTable(deviceId), NOT_FOUND); + } +} + +/** + * @tc.name: RemoveDeviceTest010 + * @tc.desc: remove record with invalid mode. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBCloudKvTest, RemoveDeviceTest010, TestSize.Level0) +{ + std::string deviceId = std::string(128, 'a'); + EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId, "", ClearMode::FLAG_ONLY), INVALID_ARGS); + EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId, "", ClearMode::CLEAR_SHARED_TABLE), INVALID_ARGS); + EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId, "", ClearMode::FLAG_AND_DATA), INVALID_ARGS); + EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId, "", ClearMode::DEFAULT), OK); + EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData("", "", ClearMode::DEFAULT), OK); + EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData("", ClearMode::DEFAULT), OK); +} } \ No newline at end of file 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 33751770..c1921eb1 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 @@ -228,6 +228,11 @@ void InsertCloudDBData(int64_t begin, int64_t count, int64_t gidStart, const std std::vector record; std::vector extend; GenerateDataRecords(begin, count, gidStart, record, extend); + if (tableName == ASSETS_TABLE_NAME_SHARED) { + for (auto &vBucket: record) { + vBucket.insert_or_assign(CloudDbConstant::CLOUD_OWNER, std::string("cloudA")); + } + } ASSERT_EQ(g_virtualCloudDb->BatchInsertWithGid(tableName, std::move(record), extend), DBStatus::OK); } @@ -253,7 +258,13 @@ void CallSync(const std::vector &tableNames, SyncMode mode, DBStatu ASSERT_EQ(g_syncProcess.errCode, errCode); } }; - ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, mode, query, callback, SYNC_WAIT_TIME), dbStatus); + CloudSyncOption option; + option.devices = {DEVICE_CLOUD}; + option.mode = mode; + option.query = query; + option.waitTime = SYNC_WAIT_TIME; + option.lockAction = static_cast(0xff); // lock all + ASSERT_EQ(g_delegate->Sync(option, callback), dbStatus); if (dbStatus == DBStatus::OK) { WaitForSyncFinish(g_syncProcess, SYNC_WAIT_TIME); @@ -319,13 +330,17 @@ void UpdateAssetsForLocal(sqlite3 *&db, int id, uint32_t status) void CheckConsistentCount(sqlite3 *db, int64_t expectCount) { - EXPECT_EQ(sqlite3_exec(db, QUERY_CONSISTENT_SQL.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, + std::string sql = "select count(*) from " + DBCommon::GetLogTableName(ASSETS_TABLE_NAME) + + " where flag&0x20=0;"; + EXPECT_EQ(sqlite3_exec(db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, reinterpret_cast(expectCount), nullptr), SQLITE_OK); } void CheckCompensatedCount(sqlite3 *db, int64_t expectCount) { - EXPECT_EQ(sqlite3_exec(db, QUERY_COMPENSATED_SQL.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, + std::string sql = "select count(*) from " + DBCommon::GetLogTableName(ASSETS_TABLE_NAME) + + " where flag&0x10!=0;"; + EXPECT_EQ(sqlite3_exec(db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, reinterpret_cast(expectCount), nullptr), SQLITE_OK); } @@ -507,6 +522,11 @@ void DistributedDBCloudSyncerDownloadAssetsTest::InitDataStatusTest(bool needDow EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); std::this_thread::sleep_for(std::chrono::milliseconds(1)); InsertCloudDBData(0, localCount, 0, ASSETS_TABLE_NAME); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + sql = "update " + ASSETS_TABLE_NAME + " set age='666' where id in (4);"; + EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); + sql = "update " + logName + " SET status = 1 where data_key in (4);"; + EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); } void DistributedDBCloudSyncerDownloadAssetsTest::DataStatusTest001(bool needDownload) @@ -517,7 +537,7 @@ void DistributedDBCloudSyncerDownloadAssetsTest::DataStatusTest001(bool needDown count++; if (count == 1) { std::string sql = "select count(*) from " + DBCommon::GetLogTableName(ASSETS_TABLE_NAME) + " WHERE " - " (status = 3 and data_key in (2,3,12,13)) or (status = 1 and data_key = 11) or (status = 0)"; + " (status = 3 and data_key in (2,3,12,13)) or (status = 1 and data_key in (11, 4)) or (status = 0)"; CloudDBSyncUtilsTest::CheckCount(db, sql, cloudCount); } if (count == 2) { // 2 is compensated sync @@ -539,7 +559,7 @@ void DistributedDBCloudSyncerDownloadAssetsTest::DataStatusTest003() count++; if (count == 1) { std::string sql = "select count(*) from " + DBCommon::GetLogTableName(ASSETS_TABLE_NAME) + " WHERE " - " (status = 3 and data_key in (0,2,3,12,13)) or (status = 1 and data_key = 11)"; + " (status = 3 and data_key in (0,2,3,12,13)) or (status = 0 and data_key = 11)"; CloudDBSyncUtilsTest::CheckCount(db, sql, 6); // 6 is match count } if (count == 2) { // 2 is compensated sync @@ -571,12 +591,12 @@ void DistributedDBCloudSyncerDownloadAssetsTest::DataStatusTest004() if (count == 1) { std::string sql = "select count(*) from " + DBCommon::GetLogTableName(ASSETS_TABLE_NAME) + " WHERE " " (status = 3 and data_key in (2,3,12,13)) or (status = 1 and data_key in (-1,11))"; - CloudDBSyncUtilsTest::CheckCount(db, sql, 6); // 6 is match count + CloudDBSyncUtilsTest::CheckCount(db, sql, 5); // 5 is match count } if (count == 2) { // 2 is compensated sync std::string sql = "select count(*) from " + DBCommon::GetLogTableName(ASSETS_TABLE_NAME) + " WHERE " " (status = 3 and data_key in (2,3,12,13)) or (status = 0)"; - CloudDBSyncUtilsTest::CheckCount(db, sql, 20); // 20 is match count + CloudDBSyncUtilsTest::CheckCount(db, sql, 19); // 19 is match count g_processCondition.notify_one(); } }); @@ -591,6 +611,15 @@ void DistributedDBCloudSyncerDownloadAssetsTest::DataStatusTest004() EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); } }); + int queryIdx = 0; + g_virtualCloudDb->ForkQuery([this, &queryIdx](const std::string &, VBucket &) { + LOGD("query index:%d", ++queryIdx); + if (queryIdx == 4) { // 4 is compensated sync + std::string sql = "update " + DBCommon::GetLogTableName(ASSETS_TABLE_NAME) + + " SET status = 1 where data_key=15;"; + EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); + } + }); InitDataStatusTest(true); CallSync({ASSETS_TABLE_NAME}, SYNC_MODE_CLOUD_MERGE, DBStatus::OK); WaitForSync(count); @@ -603,7 +632,7 @@ void DistributedDBCloudSyncerDownloadAssetsTest::DataStatusTest005() count++; if (count == 1) { std::string sql = "select count(*) from " + DBCommon::GetLogTableName(ASSETS_TABLE_NAME) + " WHERE " - " (status = 3 and data_key in (0,2,3,12,13)) or (status = 1 and data_key in (11))"; + " (status = 3 and data_key in (0,2,3,12,13)) or (status = 0 and data_key in (11))"; CloudDBSyncUtilsTest::CheckCount(db, sql, 6); // 6 is match count } if (count == 2) { // 2 is compensated sync @@ -636,7 +665,8 @@ void DistributedDBCloudSyncerDownloadAssetsTest::DataStatusTest006() count++; if (count == 1) { std::string sql = "select count(*) from " + DBCommon::GetLogTableName(ASSETS_TABLE_NAME) + " WHERE " - " (status = 3 and data_key in (2,3,12,13)) or (status = 1 and data_key in (0,11))"; + " (status = 3 and data_key in (2,3,12,13)) or (status = 1 and data_key in (0)) or " + "(status = 0 and data_key in (11))"; CloudDBSyncUtilsTest::CheckCount(db, sql, 6); // 6 is match count } if (count == 2) { // 2 is compensated sync @@ -709,7 +739,7 @@ HWTEST_F(DistributedDBCloudSyncerDownloadAssetsTest, DownloadAssetForDupDataTest ASSERT_EQ(g_delegate->SetIAssetLoader(assetLoader), DBStatus::OK); int index = 1; EXPECT_CALL(*assetLoader, Download(testing::_, testing::_, testing::_, testing::_)) - .Times(4) + .Times(2) .WillRepeatedly( [&index](const std::string &, const std::string &gid, const Type &, std::map &assets) { LOGD("Download GID:%s", gid.c_str()); @@ -906,6 +936,9 @@ HWTEST_F(DistributedDBCloudSyncerDownloadAssetsTest, FillAssetId006, TestSize.Le */ HWTEST_F(DistributedDBCloudSyncerDownloadAssetsTest, FillAssetId007, TestSize.Level0) { + CloudSyncConfig config; + config.maxUploadCount = 200; // max upload 200 + g_delegate->SetCloudSyncConfig(config); /** * @tc.steps:step1. local insert assets and sync, check the local assetId. * @tc.expected: step1. return OK. @@ -1096,7 +1129,6 @@ HWTEST_F(DistributedDBCloudSyncerDownloadAssetsTest, FillAssetId012, TestSize.Le g_virtualCloudDb->SetClearExtend(count); UpdateLocalData(db, ASSETS_TABLE_NAME, ASSETS_COPY1); CallSync({ASSETS_TABLE_NAME}, SYNC_MODE_CLOUD_MERGE, DBStatus::OK, DBStatus::CLOUD_ERROR); - CheckLocaLAssets(ASSETS_TABLE_NAME, "0", {}); } /** @@ -1433,7 +1465,7 @@ HWTEST_F(DistributedDBCloudSyncerDownloadAssetsTest, DownloadAssetForDupDataTest * @tc.expected: step3. return OK */ CallSync({ASSETS_TABLE_NAME}, SYNC_MODE_CLOUD_MERGE, DBStatus::OK); - EXPECT_GE(index, 4); // 4 is download num + EXPECT_GE(index, 2); // 2 is download num } /** @@ -1909,5 +1941,93 @@ HWTEST_F(DistributedDBCloudSyncerDownloadAssetsTest, SyncDataStatusTest007, Test { DataStatusTest007(); } + +/** + * @tc.name: SyncDataStatusTest008 + * @tc.desc: Test upload process when data locked + * @tc.type: FUNC + * @tc.require: + * @tc.author: bty + */ +HWTEST_F(DistributedDBCloudSyncerDownloadAssetsTest, SyncDataStatusTest008, TestSize.Level0) +{ + /** + * @tc.steps:step1. init local data + * @tc.expected: step1. return OK. + */ + int localCount = 40; + InsertLocalData(db, 0, localCount, ASSETS_TABLE_NAME, true); + std::string logName = DBCommon::GetLogTableName(ASSETS_TABLE_NAME); + std::string sql = "update " + logName + " SET status = 2 where data_key >=20;"; + EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); + + /** + * @tc.steps:step2. sync and check process + * @tc.expected: step2. return OK. + */ + g_syncProcess = {}; + Query query = Query::Select().FromTable({ ASSETS_TABLE_NAME }); + std::vector expectProcess = { + { PROCESSING, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }, + { FINISHED, { 0, 0, 0, 0 }, { 1, 40, 40, 0 } } // 1 is index, 40 is count + }; + int index = 0; + CloudSyncConfig config; + config.maxUploadCount = 100; // max upload 100 + g_delegate->SetCloudSyncConfig(config); + CloudSyncStatusCallback callback = [&index, &expectProcess](const std::map &process) { + g_syncProcess = std::move(process.begin()->second); + ASSERT_LT(index, 2); + for (const auto &[tableName, info]: g_syncProcess.tableProcess) { + EXPECT_EQ(info.process, expectProcess[index].process); + EXPECT_EQ(info.upLoadInfo.batchIndex, expectProcess[index].upLoadInfo.batchIndex); + EXPECT_EQ(info.upLoadInfo.total, expectProcess[index].upLoadInfo.total); + EXPECT_EQ(info.upLoadInfo.successCount, expectProcess[index].upLoadInfo.successCount); + EXPECT_EQ(tableName, ASSETS_TABLE_NAME); + } + index++; + if (g_syncProcess.process == FINISHED) { + g_processCondition.notify_one(); + ASSERT_EQ(g_syncProcess.errCode, DBStatus::OK); + } + }; + ASSERT_EQ(g_delegate->Sync({DEVICE_CLOUD}, SYNC_MODE_CLOUD_MERGE, query, callback, SYNC_WAIT_TIME), OK); + WaitForSyncFinish(g_syncProcess, SYNC_WAIT_TIME); +} + +/** + * @tc.name: DownloadAssetTest001 + * @tc.desc: Test the asset status after the share table sync + * @tc.type: FUNC + * @tc.require: + * @tc.author: bty + */ +HWTEST_F(DistributedDBCloudSyncerDownloadAssetsTest, DownloadAssetTest001, TestSize.Level0) +{ + /** + * @tc.steps:step1. init data and sync + * @tc.expected: step1. return OK. + */ + int cloudCount = 10; // 10 is num of cloud + InsertCloudDBData(0, cloudCount, 0, ASSETS_TABLE_NAME_SHARED); + CallSync({ASSETS_TABLE_NAME_SHARED}, SYNC_MODE_CLOUD_MERGE, DBStatus::OK); + + /** + * @tc.steps:step2. check asset status + * @tc.expected: step2. return OK. + */ + SqlCondition condition; + condition.sql = "select assets from " + ASSETS_TABLE_NAME_SHARED + " where _rowid_ = 1;"; + condition.readOnly = true; + std::vector records; + EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK); + for (const auto &data: records) { + Assets assets; + CloudStorageUtils::GetValueFromVBucket(COL_ASSETS, data, assets); + for (const auto &asset: assets) { + EXPECT_EQ(asset.status, AssetStatus::NORMAL); + } + } +} } // namespace #endif // RELATIONAL_STORE diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_download_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_download_test.cpp index 212fb7ba..1e7b84c6 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_download_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_download_test.cpp @@ -59,6 +59,7 @@ void DistributedDBCloudSyncerDownloadTest::TearDownTestCase(void) g_cloudSyncer = nullptr; g_storageProxy = nullptr; delete g_iCloud; + g_iCloud = nullptr; } void DistributedDBCloudSyncerDownloadTest::SetUp(void) @@ -711,7 +712,11 @@ HWTEST_F(DistributedDBCloudSyncerDownloadTest, DownloadMockTest007, TestSize.Lev { TaskId taskId = 1u; EXPECT_CALL(*g_iCloud, StartTransaction(_)).WillRepeatedly(Return(E_OK)); - EXPECT_CALL(*g_iCloud, GetUploadCount(_, _, _, _, _)).WillRepeatedly(Return(E_OK)); + EXPECT_CALL(*g_iCloud, GetUploadCount(_, _, _, _, _)).WillRepeatedly([](const QuerySyncObject &, + const Timestamp &, bool, bool, int64_t &count) { + count = 1; + return E_OK; + }); EXPECT_CALL(*g_iCloud, Commit()).WillRepeatedly(Return(E_OK)); EXPECT_CALL(*g_iCloud, Rollback()).WillRepeatedly(Return(E_OK)); EXPECT_CALL(*g_iCloud, PutCloudSyncData(_, _)).WillRepeatedly(Return(E_OK)); @@ -727,8 +732,18 @@ HWTEST_F(DistributedDBCloudSyncerDownloadTest, DownloadMockTest007, TestSize.Lev g_cloudSyncer->InitCloudSyncer(taskId, SYNC_MODE_CLOUD_MERGE); ExpectQueryCall(); ExpectGetInfoByPrimaryKeyOrGidCall(); - int errCode = g_cloudSyncer->CallDoDownload(taskId); + EXPECT_CALL(*g_idb, GetEmptyCursor(_)).WillRepeatedly([](const std::string &) { + return std::pair(OK, std::string("test")); + }); + int errCode = g_cloudSyncer->CallDoDownloadInNeed(true, true); EXPECT_EQ(errCode, E_OK); + auto downloadStatus = g_cloudSyncer->GetDownloadFinishedStatus(); + for (const auto &item : downloadStatus) { + for (const auto &[table, finish] : item.second) { + LOGI("check table %s", table.c_str()); + EXPECT_TRUE(finish); + } + } } /** diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_lock_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_lock_test.cpp index 6bcd4866..d5c75540 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_lock_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_lock_test.cpp @@ -199,9 +199,10 @@ void DistributedDBCloudSyncerLockTest::GenerateDataRecords( Asset asset = ASSET_COPY; asset.name = ASSET_COPY.name + std::to_string(i); assets.emplace_back(asset); + VBucket data; + data.insert_or_assign(COL_ASSET, asset); asset.name = ASSET_COPY.name + std::to_string(i) + "_copy"; assets.emplace_back(asset); - VBucket data; data.insert_or_assign(COL_ID, i); data.insert_or_assign(COL_NAME, "name" + std::to_string(g_nameId++)); data.insert_or_assign(COL_ASSETS, assets); @@ -288,12 +289,14 @@ void DistributedDBCloudSyncerLockTest::CallSync(const CloudSyncOption &option, D std::mutex dataMutex; std::condition_variable cv; bool finish = false; - auto callback = [&cv, &dataMutex, &finish](const std::map &process) { + SyncProcess last; + auto callback = [&last, &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; + last = item.second; } cv.notify_one(); } @@ -306,6 +309,7 @@ void DistributedDBCloudSyncerLockTest::CallSync(const CloudSyncOption &option, D return finish; }); } + g_syncProcess = last; } void DistributedDBCloudSyncerLockTest::TestConflictSync001(bool isUpdate) @@ -497,7 +501,120 @@ HWTEST_F(DistributedDBCloudSyncerLockTest, RDBConflictCloudSync004, TestSize.Lev sql = "select count(*) from " + ASSETS_TABLE_NAME + " where name = 'name30' AND id = '20';"; EXPECT_EQ(sqlite3_exec(db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, reinterpret_cast(1), nullptr), SQLITE_OK); + for (const auto &table : g_syncProcess.tableProcess) { + EXPECT_EQ(table.second.upLoadInfo.failCount, 0u); + } +} + +/** + * @tc.name: QueryCursorTest001 + * @tc.desc: Test cursor after querying no data + * @tc.type: FUNC + * @tc.require: + * @tc.author: bty + */ +HWTEST_F(DistributedDBCloudSyncerLockTest, QueryCursorTest001, TestSize.Level0) +{ + /** + * @tc.steps:step1. init data and Query with cursor tha exceeds range + * @tc.expected: step1. return ok. + */ + int cloudCount = 20; + InsertCloudDBData(0, cloudCount, 0, ASSETS_TABLE_NAME); + VBucket extend; + extend[CloudDbConstant::CURSOR_FIELD] = std::to_string(30); + std::vector data; + + /** + * @tc.steps:step2. check cursor output param + * @tc.expected: step2. return QUERY_END. + */ + EXPECT_EQ(g_virtualCloudDb->Query(ASSETS_TABLE_NAME, extend, data), QUERY_END); + EXPECT_EQ(std::get(extend[CloudDbConstant::CURSOR_FIELD]), std::to_string(cloudCount)); +} + +/** + * @tc.name: QueryCursorTest002 + * @tc.desc: Test cursor in conditional query sync + * @tc.type: FUNC + * @tc.require: + * @tc.author: bty + */ +HWTEST_F(DistributedDBCloudSyncerLockTest, QueryCursorTest002, TestSize.Level0) +{ + /** + * @tc.steps:step1. init data + * @tc.expected: step1. return ok. + */ + int count = 10; + InsertCloudDBData(0, count, 0, ASSETS_TABLE_NAME); + InsertLocalData(0, count, ASSETS_TABLE_NAME, true); + std::vector idVec = {2, 3}; + CloudSyncOption option = PrepareOption(Query::Select().From(ASSETS_TABLE_NAME).In("id", idVec), + LockAction::DOWNLOAD, true); + int index = 0; + + /** + * @tc.steps:step2. sync and check cursor + * @tc.expected: step2. return ok. + */ + g_virtualCloudDb->ForkQuery([&index](const std::string &, VBucket &extend) { + if (index == 1) { + std::string cursor; + CloudStorageUtils::GetValueFromVBucket(CloudDbConstant::CURSOR_FIELD, extend, cursor); + EXPECT_EQ(cursor, std::string("")); + } + index++; + }); + CallSync(option); } +/** + * @tc.name: RecordConflictTest001 + * @tc.desc: Test the asset input param after download return CLOUD_RECORD_EXIST_CONFLICT + * @tc.type: FUNC + * @tc.require: + * @tc.author: bty + */ +HWTEST_F(DistributedDBCloudSyncerLockTest, RecordConflictTest001, TestSize.Level0) +{ + /** + * @tc.steps:step1. init data and sync + * @tc.expected: step1. return ok. + */ + int count = 10; + InsertCloudDBData(0, count, 0, ASSETS_TABLE_NAME); + g_virtualAssetLoader->SetDownloadStatus(DBStatus::CLOUD_RECORD_EXIST_CONFLICT); + CloudSyncOption option = PrepareOption(Query::Select().FromTable({ ASSETS_TABLE_NAME }), LockAction::INSERT); + int callCount = 0; + g_cloudStoreHook->SetSyncFinishHook([&callCount]() { + callCount++; + g_processCondition.notify_all(); + }); + CallSync(option); + { + std::unique_lock lock(g_processMutex); + bool result = g_processCondition.wait_for(lock, std::chrono::seconds(WAIT_TIME), + [&callCount]() { return callCount == 2; }); // 2 is compensated sync + ASSERT_EQ(result, true); + } + + /** + * @tc.steps:step2. sync again and check asset + * @tc.expected: step2. return ok. + */ + g_virtualAssetLoader->SetDownloadStatus(DBStatus::OK); + g_virtualAssetLoader->ForkDownload([](std::map &assets) { + EXPECT_EQ(assets.find(COL_ASSET) != assets.end(), true); + }); + CallSync(option); + { + std::unique_lock lock(g_processMutex); + bool result = g_processCondition.wait_for(lock, std::chrono::seconds(WAIT_TIME), + [&callCount]() { return callCount == 4; }); // 4 is compensated sync + ASSERT_EQ(result, true); + } + g_cloudStoreHook->SetSyncFinishHook(nullptr); +} } // namespace #endif // RELATIONAL_STORE \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/mock_asset_loader.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/mock_asset_loader.h index 2ccdb760..f694ef09 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/mock_asset_loader.h +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/mock_asset_loader.h @@ -16,7 +16,7 @@ #ifndef MOCK_ASSET_LOADER_H #define MOCK_ASSET_LOADER_H #include -#include "cloud/iAssetLoader.h" +#include "iAssetLoader.h" namespace DistributedDB { class MockAssetLoader : public IAssetLoader { diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/mock_icloud_sync_storage_interface.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/mock_icloud_sync_storage_interface.h index 2fc2e5f5..ec34ffe9 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/mock_icloud_sync_storage_interface.h +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/mock_icloud_sync_storage_interface.h @@ -50,6 +50,7 @@ public: MOCK_CONST_METHOD0(GetIdentify, std::string()); MOCK_METHOD1(CheckQueryValid, int(const QuerySyncObject &)); MOCK_METHOD1(IsSharedTable, bool(const std::string &)); + MOCK_CONST_METHOD0(GetCloudSyncConfig, CloudSyncConfig()); }; } 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 95e17fd1..ed270fda 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 @@ -50,7 +50,9 @@ DBStatus VirtualCloudDb::BatchInsert(const std::string &tableName, std::vector 0) { - extend.erase(extend.end()); + if (!extend.empty()) { + extend.pop_back(); + } } else if (missingExtendCount_ < 0) { VBucket vBucket; extend.push_back(vBucket); @@ -71,6 +73,9 @@ DBStatus VirtualCloudDb::InnerBatchInsert(const std::string &tableName, std::vec { DBStatus res = OK; for (size_t i = 0; i < record.size(); ++i) { + if (insertCheckFunc_) { + insertCheckFunc_(record[i]); + } if (extend[i].find(g_gidField) != extend[i].end()) { LOGE("[VirtualCloudDb] Insert data should not have gid"); return DB_ERROR; @@ -137,7 +142,9 @@ DBStatus VirtualCloudDb::BatchInsertWithGid(const std::string &tableName, std::v cloudData_[tableName].push_back(cloudData); } if (missingExtendCount_ > 0) { - extend.erase(extend.end()); + if (!extend.empty()) { + extend.pop_back(); + } } else if (missingExtendCount_ < 0) { VBucket vBucket; extend.push_back(vBucket); @@ -287,6 +294,9 @@ DBStatus VirtualCloudDb::Query(const std::string &tableName, VBucket &extend, st } else { cursor = cursor.empty() ? "0" : cursor; GetCloudData(cursor, isIncreCursor, cloudData_[tableName], data, extend); + if (data.empty()) { + extend[g_cursorField] = std::to_string(currentCursor_ - 1); + } } if (!isIncreCursor && data.empty() && isSetCrementCloudData_) { extend[g_cursorField] = increPrefix_; @@ -317,6 +327,9 @@ void VirtualCloudDb::GetCloudData(const std::string &cursor, bool isIncreCursor, bucket.insert(ex); } data.push_back(std::move(bucket)); + if (!isIncreCursor) { + extend[g_cursorField] = srcCursor; + } } if (data.size() >= static_cast(queryLimit_)) { return; @@ -403,7 +416,9 @@ DBStatus VirtualCloudDb::InnerUpdate(const std::string &tableName, std::vector 0) { - extend.erase(extend.end()); + if (!extend.empty()) { + extend.pop_back(); + } } else if (missingExtendCount_ < 0) { VBucket vBucket; extend.push_back(vBucket); @@ -510,12 +525,12 @@ void VirtualCloudDb::ClearHeartbeatCount() heartbeatCount_ = 0; } -int32_t VirtualCloudDb::GetHeartbeatCount() +int32_t VirtualCloudDb::GetHeartbeatCount() const { return heartbeatCount_; } -bool VirtualCloudDb::GetLockStatus() +bool VirtualCloudDb::GetLockStatus() const { return lockStatus_; } @@ -525,6 +540,11 @@ void VirtualCloudDb::SetHeartbeatError(bool heartbeatError) heartbeatError_ = heartbeatError; } +void VirtualCloudDb::SetInsertHook(const std::function &insertCheckFunc) +{ + insertCheckFunc_ = insertCheckFunc; +} + void VirtualCloudDb::SetIncrementData(const std::string &tableName, const VBucket &record, const VBucket &extend) { std::lock_guard autoLock(cloudDataMutex_); @@ -646,8 +666,8 @@ void VirtualCloudDb::SetHeartbeatBlockTime(int32_t blockTime) } void VirtualCloudDb::ForkInsertConflict(const std::function &)> &func) + std::vector &)> &forkUploadFunc) { - forkUploadConflictFunc_ = func; + forkUploadConflictFunc_ = forkUploadFunc; } } \ 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 6a7b098e..6232bb0a 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 @@ -59,9 +59,9 @@ public: void ClearHeartbeatCount(); - int32_t GetHeartbeatCount(); + int32_t GetHeartbeatCount() const; - bool GetLockStatus(); + bool GetLockStatus() const; void SetHeartbeatError(bool heartbeatError); @@ -95,6 +95,8 @@ public: void SetConflictInUpload(bool conflict); void SetHeartbeatBlockTime(int32_t blockTime); + + void SetInsertHook(const std::function &insertCheckFunc); private: DBStatus InnerBatchInsert(const std::string &tableName, std::vector &&record, std::vector &extend); @@ -148,6 +150,7 @@ private: std::function forkUploadFunc_; std::function &)> forkUploadConflictFunc_; + std::function insertCheckFunc_; }; } #endif // VIRTUAL_CLOUD_DB_H diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_syncer.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_syncer.cpp index 7c490fac..43fb8c54 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_syncer.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_syncer.cpp @@ -116,4 +116,14 @@ int VirtualCloudSyncer::CallTagStatusByStrategy(bool isExist, const DataInfoWith dataInfo.cloudLogInfo = cloudInfo; return CloudSyncer::TagStatusByStrategy(isExist, param, dataInfo, strategyOpResult); } + +void VirtualCloudSyncer::PauseCurrentTask() +{ + std::lock_guard autoLock(dataLock_); + if (currentContext_.currentTaskId == INVALID_TASK_ID) { + return; + } + cloudTaskInfos_[currentContext_.currentTaskId].pause = true; + LOGD("[CloudSyncer] Mark taskId %" PRIu64 " paused success", currentContext_.currentTaskId); +} } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_syncer.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_syncer.h index 88e245be..5ffb2c21 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_syncer.h +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_cloud_syncer.h @@ -46,6 +46,8 @@ public: int CallTagStatusByStrategy(bool isExist, const DataInfoWithLog &localInfo, const LogInfo &cloudInfo, OpType &strategyOpResult); + + void PauseCurrentTask(); private: std::function downloadFunc_; std::function downloadInNeedFunc_; diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_meta_data_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_meta_data_test.cpp index b7557004..f61cc77c 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_meta_data_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_meta_data_test.cpp @@ -308,4 +308,23 @@ HWTEST_F(DistributedDBMetaDataTest, MetadataTest006, TestSize.Level0) EXPECT_EQ(metadata_->EraseDeviceWaterMark(DEVICE_A, true), E_OK); EXPECT_TRUE(metadata_->IsAbilitySyncFinish(DEVICE_A)); } + +/** + * @tc.name: MetadataTest007 + * @tc.desc: Test metadata init with time change if need. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBMetaDataTest, MetadataTest007, TestSize.Level0) +{ + /** + * @tc.steps: step1. Check time sync finish by meta. + * @tc.expected: step1. B is change because of time change. + */ + RuntimeContext::GetInstance()->SetTimeChanged(true); + EXPECT_TRUE(metadata_->IsTimeChange(DEVICE_B)); + RuntimeContext::GetInstance()->SetTimeChanged(false); + RuntimeContext::GetInstance()->StopTimeTickMonitorIfNeed(); +} } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_multi_sub_user_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_multi_sub_user_test.cpp new file mode 100644 index 00000000..184559e9 --- /dev/null +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_multi_sub_user_test.cpp @@ -0,0 +1,765 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "cloud_db_sync_utils_test.h" +#include "db_constant.h" +#include "distributeddb_data_generate_unit_test.h" +#include "distributeddb_tools_unit_test.h" +#include "kv_store_nb_delegate.h" +#include "kv_virtual_device.h" +#include "platform_specific.h" +#include "relational_store_manager.h" +#include "runtime_config.h" +#include "virtual_asset_loader.h" +#include "virtual_cloud_data_translate.h" + +using namespace testing::ext; +using namespace DistributedDB; +using namespace DistributedDBUnitTest; +using namespace std; + +namespace { + std::shared_ptr g_testDir = nullptr; + VirtualCommunicatorAggregator* g_communicatorAggregator = nullptr; + const std::string DEVICE_A = "real_device"; + const std::string DEVICE_B = "deviceB"; + const std::string KEY_INSTANCE_ID = "INSTANCE_ID"; + const std::string KEY_SUB_USER = "SUB_USER"; + KvVirtualDevice *g_deviceB = nullptr; + DistributedDBToolsUnitTest g_tool; + CloudSyncOption g_CloudSyncoption; + std::shared_ptr virtualCloudDb_ = nullptr; + std::shared_ptr g_virtualCloudDataTranslate; + const string ASSETS_TABLE_NAME = "student"; + const string ASSETS_TABLE_NAME_SHARED = "student_shared"; + const string COL_ID = "id"; + const string COL_NAME = "name"; + const string COL_ASSET = "asset"; + const string COL_ASSETS = "assets"; + const int64_t WAIT_TIME = 5; + const std::vector CLOUD_FIELDS = {{COL_ID, TYPE_INDEX, true}, {COL_NAME, TYPE_INDEX}, + {COL_ASSET, TYPE_INDEX}, {COL_ASSETS, TYPE_INDEX}}; + const string CREATE_SINGLE_PRIMARY_KEY_TABLE = "CREATE TABLE IF NOT EXISTS " + ASSETS_TABLE_NAME + "(" + COL_ID + + " INTEGER PRIMARY KEY," + COL_NAME + " TEXT ," + COL_ASSET + " ASSET," + COL_ASSETS + " ASSETS" + ");"; + const Asset ASSET_COPY = {.version = 1, + .name = "Phone", + .assetId = "0", + .subpath = "/local/sync", + .uri = "/local/sync", + .modifyTime = "123456", + .createTime = "", + .size = "256", + .hash = "ASE"}; + int64_t g_nameId = 0; + + DBStatus OpenDelegate(const std::string &dlpPath, KvStoreNbDelegate *&delegatePtr, + KvStoreDelegateManager &mgr, bool syncDualTupleMode = false) + { + if (g_testDir == nullptr) { + return DB_ERROR; + } + std::string dbPath = *g_testDir + dlpPath; + KvStoreConfig storeConfig; + storeConfig.dataDir = dbPath; + OS::MakeDBDirectory(dbPath); + mgr.SetKvStoreConfig(storeConfig); + + string dir = dbPath + "/single_ver"; + DIR* dirTmp = opendir(dir.c_str()); + if (dirTmp == nullptr) { + OS::MakeDBDirectory(dir); + } else { + closedir(dirTmp); + } + + KvStoreNbDelegate::Option option; + option.syncDualTupleMode = syncDualTupleMode; + DBStatus res = OK; + mgr.GetKvStore(STORE_ID_1, option, [&delegatePtr, &res](DBStatus status, KvStoreNbDelegate *delegate) { + delegatePtr = delegate; + res = status; + }); + return res; + } + + DataBaseSchema GetDataBaseSchema() + { + DataBaseSchema schema; + TableSchema tableSchema; + tableSchema.name = CloudDbConstant::CLOUD_KV_TABLE_NAME; + Field field; + field.colName = CloudDbConstant::CLOUD_KV_FIELD_KEY; + field.type = TYPE_INDEX; + field.primary = true; + tableSchema.fields.push_back(field); + field.colName = CloudDbConstant::CLOUD_KV_FIELD_DEVICE; + field.primary = false; + tableSchema.fields.push_back(field); + field.colName = CloudDbConstant::CLOUD_KV_FIELD_ORI_DEVICE; + tableSchema.fields.push_back(field); + field.colName = CloudDbConstant::CLOUD_KV_FIELD_VALUE; + tableSchema.fields.push_back(field); + field.colName = CloudDbConstant::CLOUD_KV_FIELD_DEVICE_CREATE_TIME; + field.type = TYPE_INDEX; + tableSchema.fields.push_back(field); + schema.tables.push_back(tableSchema); + return schema; + } + + DBStatus SetCloudDB(KvStoreNbDelegate *&delegatePtr) + { + std::map> cloudDbs; + cloudDbs[USER_ID] = virtualCloudDb_; + delegatePtr->SetCloudDB(cloudDbs); + std::map schemas; + schemas[USER_ID] = GetDataBaseSchema(); + return delegatePtr->SetCloudDbSchema(schemas); + } + + DBStatus OpenDelegate(const std::string &dlpPath, RelationalStoreDelegate *&rdbDelegatePtr, + RelationalStoreManager &mgr, sqlite3 *&db) + { + if (g_testDir == nullptr) { + return DB_ERROR; + } + std::string dbDir = *g_testDir + dlpPath; + OS::MakeDBDirectory(dbDir); + std::string dbPath = dbDir + "/test.db"; + db = RelationalTestUtils::CreateDataBase(dbPath); + EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK); + EXPECT_EQ(RelationalTestUtils::ExecSql(db, CREATE_SINGLE_PRIMARY_KEY_TABLE), SQLITE_OK); + RelationalStoreObserverUnitTest *observer = new (std::nothrow) RelationalStoreObserverUnitTest(); + RelationalStoreDelegate::Option option = { .observer = observer }; + return mgr.OpenStore(dbPath, STORE_ID_1, option, rdbDelegatePtr); + } + + void GetCloudDbSchema(DataBaseSchema &dataBaseSchema) + { + TableSchema assetsTableSchema = {.name = ASSETS_TABLE_NAME, .sharedTableName = ASSETS_TABLE_NAME_SHARED, + .fields = CLOUD_FIELDS}; + dataBaseSchema.tables.push_back(assetsTableSchema); + } + + DBStatus SetCloudDB(RelationalStoreDelegate *&delegatePtr) + { + EXPECT_EQ(delegatePtr->CreateDistributedTable(ASSETS_TABLE_NAME, CLOUD_COOPERATION), DBStatus::OK); + std::shared_ptr virtualAssetLoader = make_shared(); + EXPECT_EQ(delegatePtr->SetCloudDB(virtualCloudDb_), DBStatus::OK); + EXPECT_EQ(delegatePtr->SetIAssetLoader(virtualAssetLoader), DBStatus::OK); + DataBaseSchema dataBaseSchema; + GetCloudDbSchema(dataBaseSchema); + return delegatePtr->SetCloudDbSchema(dataBaseSchema); + } + + void CloseDelegate(KvStoreNbDelegate *&delegatePtr, KvStoreDelegateManager &mgr, std::string storeID) + { + if (delegatePtr == nullptr) { + return; + } + EXPECT_EQ(mgr.CloseKvStore(delegatePtr), OK); + delegatePtr = nullptr; + EXPECT_EQ(mgr.DeleteKvStore(storeID), OK); + } + + void CloseDelegate(RelationalStoreDelegate *&delegatePtr, RelationalStoreManager &mgr, sqlite3 *&db) + { + EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); + db = nullptr; + if (delegatePtr == nullptr) { + return; + } + EXPECT_EQ(mgr.CloseStore(delegatePtr), OK); + delegatePtr = nullptr; + } + +class DistributedDBSingleVerMultiSubUserTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +protected: + void BlockSync(KvStoreNbDelegate *delegate, DBStatus expectDBStatus, CloudSyncOption option, + int expectSyncResult = OK); + void InsertLocalData(int64_t begin, int64_t count, const std::string &tableName, bool isAssetNull, sqlite3 *&db); + void GenerateDataRecords(int64_t begin, int64_t count, int64_t gidStart, std::vector &record, + std::vector &extend); + CloudSyncOption PrepareOption(const Query &query, LockAction action); + void CallSync(RelationalStoreDelegate *delegate, const CloudSyncOption &option, DBStatus expectResult = OK); + SyncProcess lastProcess_; +}; + +void DistributedDBSingleVerMultiSubUserTest::SetUpTestCase(void) +{ + /** + * @tc.setup: Init datadir and Virtual Communicator. + */ + std::string testDir; + DistributedDBToolsUnitTest::TestDirInit(testDir); + if (g_testDir == nullptr) { + g_testDir = std::make_shared(testDir); + } + + g_communicatorAggregator = new (std::nothrow) VirtualCommunicatorAggregator(); + ASSERT_TRUE(g_communicatorAggregator != nullptr); + RuntimeContext::GetInstance()->SetCommunicatorAggregator(g_communicatorAggregator); + + g_CloudSyncoption.mode = SyncMode::SYNC_MODE_CLOUD_MERGE; + g_CloudSyncoption.users.push_back(USER_ID); + g_CloudSyncoption.devices.push_back("cloud"); + g_virtualCloudDataTranslate = std::make_shared(); + RuntimeConfig::SetCloudTranslate(g_virtualCloudDataTranslate); +} + +void DistributedDBSingleVerMultiSubUserTest::TearDownTestCase(void) +{ + /** + * @tc.teardown: Release virtual Communicator and clear data dir. + */ + if (g_testDir != nullptr && DistributedDBToolsUnitTest::RemoveTestDbFiles(*g_testDir) != 0) { + LOGE("rm test db files error!"); + } + RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr); +} + +void DistributedDBSingleVerMultiSubUserTest::SetUp(void) +{ + virtualCloudDb_ = std::make_shared(); + DistributedDBToolsUnitTest::PrintTestCaseInfo(); + g_deviceB = new (std::nothrow) KvVirtualDevice(DEVICE_B); + ASSERT_TRUE(g_deviceB != nullptr); + VirtualSingleVerSyncDBInterface *syncInterfaceB = new (std::nothrow) VirtualSingleVerSyncDBInterface(); + ASSERT_TRUE(syncInterfaceB != nullptr); + ASSERT_EQ(g_deviceB->Initialize(g_communicatorAggregator, syncInterfaceB), E_OK); +} + +void DistributedDBSingleVerMultiSubUserTest::TearDown(void) +{ + virtualCloudDb_ = nullptr; + if (g_deviceB != nullptr) { + delete g_deviceB; + g_deviceB = nullptr; + } + PermissionCheckCallbackV3 nullCallback = nullptr; + RuntimeConfig::SetPermissionCheckCallback(nullCallback); + SyncActivationCheckCallbackV2 activeCallBack = nullptr; + RuntimeConfig::SetSyncActivationCheckCallback(activeCallBack); + RuntimeConfig::SetPermissionConditionCallback(nullptr); + if (DistributedDBToolsUnitTest::RemoveTestDbFiles(*g_testDir) != 0) { + LOGE("rm test db files error."); + } +} + +void DistributedDBSingleVerMultiSubUserTest::BlockSync(KvStoreNbDelegate *delegate, DBStatus expectDBStatus, + CloudSyncOption option, int expectSyncResult) +{ + if (delegate == nullptr) { + return; + } + std::mutex dataMutex; + std::condition_variable cv; + bool finish = false; + SyncProcess last; + auto callback = [expectDBStatus, &last, &cv, &dataMutex, &finish, &option](const std::map &process) { + size_t notifyCnt = 0; + for (const auto &item: process) { + LOGD("user = %s, status = %d", item.first.c_str(), item.second.process); + if (item.second.process != DistributedDB::FINISHED) { + continue; + } + EXPECT_EQ(item.second.errCode, expectDBStatus); + { + std::lock_guard autoLock(dataMutex); + notifyCnt++; + if (notifyCnt == option.users.size()) { + finish = true; + last = item.second; + cv.notify_one(); + } + } + } + }; + EXPECT_EQ(delegate->Sync(option, callback), expectSyncResult); + if (expectSyncResult == OK) { + std::unique_lock uniqueLock(dataMutex); + cv.wait(uniqueLock, [&finish]() { + return finish; + }); + } + lastProcess_ = last; +} + +void DistributedDBSingleVerMultiSubUserTest::GenerateDataRecords( + int64_t begin, int64_t count, int64_t gidStart, std::vector &record, std::vector &extend) +{ + for (int64_t i = begin; i < begin + count; i++) { + Assets assets; + Asset asset = ASSET_COPY; + asset.name = ASSET_COPY.name + std::to_string(i); + assets.emplace_back(asset); + asset.name = ASSET_COPY.name + std::to_string(i) + "_copy"; + assets.emplace_back(asset); + VBucket data; + data.insert_or_assign(COL_ID, i); + data.insert_or_assign(COL_NAME, "name" + std::to_string(g_nameId++)); + data.insert_or_assign(COL_ASSETS, assets); + record.push_back(data); + + VBucket log; + Timestamp now = TimeHelper::GetSysCurrentTime(); + log.insert_or_assign(CloudDbConstant::CREATE_FIELD, (int64_t)now / CloudDbConstant::TEN_THOUSAND); + log.insert_or_assign(CloudDbConstant::MODIFY_FIELD, (int64_t)now / CloudDbConstant::TEN_THOUSAND); + log.insert_or_assign(CloudDbConstant::DELETE_FIELD, false); + log.insert_or_assign(CloudDbConstant::GID_FIELD, std::to_string(i + gidStart)); + extend.push_back(log); + } +} + +void DistributedDBSingleVerMultiSubUserTest::InsertLocalData(int64_t begin, int64_t count, + const std::string &tableName, bool isAssetNull, sqlite3 *&db) +{ + int errCode; + std::vector record; + std::vector extend; + GenerateDataRecords(begin, count, 0, record, extend); + const string sql = "insert or replace into " + tableName + " values (?,?,?,?);"; + for (VBucket vBucket : record) { + sqlite3_stmt *stmt = nullptr; + ASSERT_EQ(SQLiteUtils::GetStatement(db, sql, stmt), E_OK); + ASSERT_EQ(SQLiteUtils::BindInt64ToStatement(stmt, 1, std::get(vBucket[COL_ID])), E_OK); // 1 is id + ASSERT_EQ(SQLiteUtils::BindTextToStatement(stmt, 2, std::get(vBucket[COL_NAME])), E_OK); // 2 is name + if (isAssetNull) { + ASSERT_EQ(sqlite3_bind_null(stmt, 3), SQLITE_OK); // 3 is asset + } else { + std::vector assetBlob = g_virtualCloudDataTranslate->AssetToBlob(ASSET_COPY); + ASSERT_EQ(SQLiteUtils::BindBlobToStatement(stmt, 3, assetBlob, false), E_OK); // 3 is asset + } + std::vector assetsBlob = g_virtualCloudDataTranslate->AssetsToBlob( + std::get(vBucket[COL_ASSETS])); + ASSERT_EQ(SQLiteUtils::BindBlobToStatement(stmt, 4, assetsBlob, false), E_OK); // 4 is assets + EXPECT_EQ(SQLiteUtils::StepWithRetry(stmt), SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)); + SQLiteUtils::ResetStatement(stmt, true, errCode); + } +} + +CloudSyncOption DistributedDBSingleVerMultiSubUserTest::PrepareOption(const Query &query, LockAction action) +{ + CloudSyncOption option; + option.devices = { "CLOUD" }; + option.mode = SYNC_MODE_CLOUD_MERGE; + option.query = query; + option.waitTime = WAIT_TIME; + option.priorityTask = false; + option.compensatedSyncOnly = false; + option.lockAction = action; + return option; +} + +void DistributedDBSingleVerMultiSubUserTest::CallSync(RelationalStoreDelegate *delegate, const CloudSyncOption &option, + DBStatus expectResult) +{ + std::mutex dataMutex; + std::condition_variable cv; + bool finish = false; + auto callback = [&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; + } + cv.notify_one(); + } + } + }; + ASSERT_EQ(delegate->Sync(option, callback), expectResult); + if (expectResult == OK) { + std::unique_lock uniqueLock(dataMutex); + cv.wait(uniqueLock, [&finish]() { + return finish; + }); + } +} + +/** + * @tc.name: KvDelegateInvalidParamTest001 + * @tc.desc: Test kv delegate open with invalid subUser. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhaoliang + */ +HWTEST_F(DistributedDBSingleVerMultiSubUserTest, KvDelegateInvalidParamTest001, TestSize.Level1) +{ + std::string subUser1 = std::string(129, 'a'); + KvStoreDelegateManager mgr1(APP_ID, USER_ID, subUser1, INSTANCE_ID_1); + KvStoreNbDelegate *delegatePtr1 = nullptr; + EXPECT_EQ(OpenDelegate("/subUser1", delegatePtr1, mgr1), INVALID_ARGS); + ASSERT_EQ(delegatePtr1, nullptr); + + std::string subUser2 = "subUser-1"; + KvStoreDelegateManager mgr2(APP_ID, USER_ID, subUser2, INSTANCE_ID_1); + KvStoreNbDelegate *delegatePtr2 = nullptr; + EXPECT_EQ(OpenDelegate("/subUser1", delegatePtr2, mgr2), INVALID_ARGS); + ASSERT_EQ(delegatePtr2, nullptr); + + std::string subUser3 = std::string(128, 'a'); + KvStoreDelegateManager mgr3(APP_ID, USER_ID, subUser3, INSTANCE_ID_1); + KvStoreNbDelegate *delegatePtr3 = nullptr; + EXPECT_EQ(OpenDelegate("/subUser1", delegatePtr3, mgr3), OK); + ASSERT_NE(delegatePtr3, nullptr); + + CloseDelegate(delegatePtr3, mgr3, STORE_ID_1); +} + +/** + * @tc.name: RDBDelegateInvalidParamTest001 + * @tc.desc: Test rdb delegate open with invalid subUser. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhaoliang + */ +HWTEST_F(DistributedDBSingleVerMultiSubUserTest, RDBDelegateInvalidParamTest001, TestSize.Level1) +{ + std::string subUser1 = std::string(129, 'a'); + RelationalStoreManager mgr1(APP_ID, USER_ID, subUser1, INSTANCE_ID_1); + RelationalStoreDelegate *rdbDelegatePtr1 = nullptr; + sqlite3 *db1; + EXPECT_EQ(OpenDelegate("/subUser1", rdbDelegatePtr1, mgr1, db1), INVALID_ARGS); + ASSERT_EQ(rdbDelegatePtr1, nullptr); + + std::string subUser2 = "subUser-1"; + RelationalStoreManager mgr2(APP_ID, USER_ID, subUser2, INSTANCE_ID_1); + RelationalStoreDelegate *rdbDelegatePtr2 = nullptr; + sqlite3 *db2; + EXPECT_EQ(OpenDelegate("/subUser1", rdbDelegatePtr2, mgr2, db2), INVALID_ARGS); + ASSERT_EQ(rdbDelegatePtr2, nullptr); + + std::string subUser3 = std::string(128, 'a'); + RelationalStoreManager mgr3(APP_ID, USER_ID, subUser3, INSTANCE_ID_1); + RelationalStoreDelegate *rdbDelegatePtr3 = nullptr; + sqlite3 *db3; + EXPECT_EQ(OpenDelegate("/subUser1", rdbDelegatePtr3, mgr3, db3), OK); + ASSERT_NE(rdbDelegatePtr3, nullptr); + + CloseDelegate(rdbDelegatePtr3, mgr3, db3); +} + +/** + * @tc.name: SameDelegateTest001 + * @tc.desc: Test kv delegate open with diff subUser. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhaoliang + */ +HWTEST_F(DistributedDBSingleVerMultiSubUserTest, SameDelegateTest001, TestSize.Level1) +{ + KvStoreDelegateManager mgr1(APP_ID, USER_ID, SUB_USER_1, INSTANCE_ID_1); + KvStoreNbDelegate *delegatePtr1 = nullptr; + EXPECT_EQ(OpenDelegate("/subUser1", delegatePtr1, mgr1), OK); + ASSERT_NE(delegatePtr1, nullptr); + + KvStoreDelegateManager mgr2(APP_ID, USER_ID, SUB_USER_2, INSTANCE_ID_1); + KvStoreNbDelegate *delegatePtr2 = nullptr; + EXPECT_EQ(OpenDelegate("/subUser2", delegatePtr2, mgr2), OK); + ASSERT_NE(delegatePtr2, nullptr); + + Key key1 = {'k', '1'}; + Value value1 = {'v', '1'}; + delegatePtr1->Put(key1, value1); + Key key2 = {'k', '2'}; + Value value2 = {'v', '2'}; + delegatePtr2->Put(key2, value2); + + Value value; + EXPECT_EQ(delegatePtr1->Get(key1, value), OK); + EXPECT_EQ(value1, value); + EXPECT_EQ(delegatePtr2->Get(key2, value), OK); + EXPECT_EQ(value2, value); + + EXPECT_EQ(delegatePtr1->Get(key2, value), NOT_FOUND); + EXPECT_EQ(delegatePtr2->Get(key1, value), NOT_FOUND); + + CloseDelegate(delegatePtr1, mgr1, STORE_ID_1); + CloseDelegate(delegatePtr2, mgr2, STORE_ID_1); +} + +/** + * @tc.name: SameDelegateTest002 + * @tc.desc: Test rdb delegate open with diff subUser. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhaoliang + */ +HWTEST_F(DistributedDBSingleVerMultiSubUserTest, SameDelegateTest002, TestSize.Level1) +{ + RelationalStoreManager mgr1(APP_ID, USER_ID, SUB_USER_1, INSTANCE_ID_1); + RelationalStoreDelegate *rdbDelegatePtr1 = nullptr; + sqlite3 *db1; + EXPECT_EQ(OpenDelegate("/subUser1", rdbDelegatePtr1, mgr1, db1), OK); + ASSERT_NE(rdbDelegatePtr1, nullptr); + + RelationalStoreManager mgr2(APP_ID, USER_ID, SUB_USER_2, INSTANCE_ID_1); + RelationalStoreDelegate *rdbDelegatePtr2 = nullptr; + sqlite3 *db2; + EXPECT_EQ(OpenDelegate("/subUser2", rdbDelegatePtr2, mgr2, db2), OK); + ASSERT_NE(rdbDelegatePtr2, nullptr); + + int localCount = 10; + InsertLocalData(0, localCount, ASSETS_TABLE_NAME, true, db1); + InsertLocalData(10, localCount, ASSETS_TABLE_NAME, true, db2); + + std::string sql1 = "select count(*) from " + ASSETS_TABLE_NAME + " where id < 10;"; + std::string sql2 = "select count(*) from " + ASSETS_TABLE_NAME + " where id >= 10;"; + + EXPECT_EQ(sqlite3_exec(db1, sql1.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, + reinterpret_cast(10), nullptr), SQLITE_OK); + EXPECT_EQ(sqlite3_exec(db2, sql2.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, + reinterpret_cast(10), nullptr), SQLITE_OK); + + EXPECT_EQ(sqlite3_exec(db1, sql2.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, + reinterpret_cast(0), nullptr), SQLITE_OK); + EXPECT_EQ(sqlite3_exec(db2, sql1.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, + reinterpret_cast(0), nullptr), SQLITE_OK); + + CloseDelegate(rdbDelegatePtr1, mgr1, db1); + CloseDelegate(rdbDelegatePtr2, mgr2, db2); +} + +/** + * @tc.name: SubUserDelegateCRUDTest001 + * @tc.desc: Test subUser rdb delegate crud function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhaoliang + */ +HWTEST_F(DistributedDBSingleVerMultiSubUserTest, SubUserDelegateCRUDTest001, TestSize.Level1) +{ + RelationalStoreManager mgr1(APP_ID, USER_ID, SUB_USER_1, INSTANCE_ID_1); + RelationalStoreDelegate *rdbDelegatePtr1 = nullptr; + sqlite3 *db1; + EXPECT_EQ(OpenDelegate("/subUser1", rdbDelegatePtr1, mgr1, db1), OK); + ASSERT_NE(rdbDelegatePtr1, nullptr); + + int localCount = 10; + InsertLocalData(0, localCount, ASSETS_TABLE_NAME, true, db1); + std::string sql1 = "select count(*) from " + ASSETS_TABLE_NAME + ";"; + EXPECT_EQ(sqlite3_exec(db1, sql1.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, + reinterpret_cast(10), nullptr), SQLITE_OK); + + InsertLocalData(0, localCount, ASSETS_TABLE_NAME, true, db1); + EXPECT_EQ(sqlite3_exec(db1, sql1.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, + reinterpret_cast(10), nullptr), SQLITE_OK); + + std::string sql2 = "delete from " + ASSETS_TABLE_NAME + ";"; + EXPECT_EQ(sqlite3_exec(db1, sql2.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, + reinterpret_cast(0), nullptr), SQLITE_OK); + EXPECT_EQ(sqlite3_exec(db1, sql1.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, + reinterpret_cast(0), nullptr), SQLITE_OK); + + CloseDelegate(rdbDelegatePtr1, mgr1, db1); +} + +/** + * @tc.name: SubUserDelegateCRUDTest002 + * @tc.desc: Test subUser kv delegate crud function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhaoliang + */ +HWTEST_F(DistributedDBSingleVerMultiSubUserTest, SubUserDelegateCRUDTest002, TestSize.Level1) +{ + KvStoreDelegateManager mgr1(APP_ID, USER_ID, SUB_USER_1, INSTANCE_ID_1); + KvStoreNbDelegate *delegatePtr1 = nullptr; + EXPECT_EQ(OpenDelegate("/subUser1", delegatePtr1, mgr1), OK); + ASSERT_NE(delegatePtr1, nullptr); + + Key key1 = {'k', '1'}; + Value value1 = {'v', '1'}; + delegatePtr1->Put(key1, value1); + + Value value; + EXPECT_EQ(delegatePtr1->Get(key1, value), OK); + EXPECT_EQ(value1, value); + + Value value2 = {'v', '2'}; + delegatePtr1->Put(key1, value2); + EXPECT_EQ(delegatePtr1->Get(key1, value), OK); + EXPECT_EQ(value2, value); + + EXPECT_EQ(delegatePtr1->Delete(key1), OK); + EXPECT_EQ(delegatePtr1->Get(key1, value), NOT_FOUND); + + CloseDelegate(delegatePtr1, mgr1, STORE_ID_1); +} + +/** + * @tc.name: SubUserDelegateCloudSyncTest001 + * @tc.desc: Test subUser kv delegate cloud sync function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhaoliang + */ +HWTEST_F(DistributedDBSingleVerMultiSubUserTest, SubUserDelegateCloudSyncTest001, TestSize.Level0) +{ + KvStoreDelegateManager mgr1(APP_ID, USER_ID, SUB_USER_1, INSTANCE_ID_1); + KvStoreNbDelegate *delegatePtr1 = nullptr; + EXPECT_EQ(OpenDelegate("/subUser1", delegatePtr1, mgr1), OK); + ASSERT_NE(delegatePtr1, nullptr); + EXPECT_EQ(SetCloudDB(delegatePtr1), OK); + + KvStoreDelegateManager mgr2(APP_ID, USER_ID, SUB_USER_2, INSTANCE_ID_1); + KvStoreNbDelegate *delegatePtr2 = nullptr; + EXPECT_EQ(OpenDelegate("/subUser2", delegatePtr2, mgr2), OK); + ASSERT_NE(delegatePtr2, nullptr); + EXPECT_EQ(SetCloudDB(delegatePtr2), OK); + + Key key = {'k'}; + Value expectValue = {'v'}; + ASSERT_EQ(delegatePtr1->Put(key, expectValue), OK); + BlockSync(delegatePtr1, OK, g_CloudSyncoption); + for (const auto &table : lastProcess_.tableProcess) { + EXPECT_EQ(table.second.upLoadInfo.total, 1u); + } + BlockSync(delegatePtr2, OK, g_CloudSyncoption); + for (const auto &table : lastProcess_.tableProcess) { + EXPECT_EQ(table.second.downLoadInfo.total, 1u); + } + Value actualValue; + EXPECT_EQ(delegatePtr2->Get(key, actualValue), OK); + EXPECT_EQ(actualValue, expectValue); + + CloseDelegate(delegatePtr1, mgr1, STORE_ID_1); + CloseDelegate(delegatePtr2, mgr2, STORE_ID_1); +} + +/** + * @tc.name: SubUserDelegateCloudSyncTest002 + * @tc.desc: Test subUser rdb delegate cloud sync function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhaoliang + */ +HWTEST_F(DistributedDBSingleVerMultiSubUserTest, SubUserDelegateCloudSyncTest002, TestSize.Level0) +{ + RelationalStoreManager mgr1(APP_ID, USER_ID, SUB_USER_1, INSTANCE_ID_1); + RelationalStoreDelegate *rdbDelegatePtr1 = nullptr; + sqlite3 *db1; + EXPECT_EQ(OpenDelegate("/subUser1", rdbDelegatePtr1, mgr1, db1), OK); + ASSERT_NE(rdbDelegatePtr1, nullptr); + EXPECT_EQ(SetCloudDB(rdbDelegatePtr1), OK); + + RelationalStoreManager mgr2(APP_ID, USER_ID, SUB_USER_2, INSTANCE_ID_1); + RelationalStoreDelegate *rdbDelegatePtr2 = nullptr; + sqlite3 *db2; + EXPECT_EQ(OpenDelegate("/subUser2", rdbDelegatePtr2, mgr2, db2), OK); + ASSERT_NE(rdbDelegatePtr2, nullptr); + EXPECT_EQ(SetCloudDB(rdbDelegatePtr2), OK); + + int localCount = 10; + InsertLocalData(0, localCount, ASSETS_TABLE_NAME, true, db1); + CloudSyncOption option = PrepareOption(Query::Select().FromTable({ ASSETS_TABLE_NAME }), LockAction::NONE); + CallSync(rdbDelegatePtr1, option); + CallSync(rdbDelegatePtr2, option); + + std::string sql = "select count(*) from " + ASSETS_TABLE_NAME + ";"; + EXPECT_EQ(sqlite3_exec(db2, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, + reinterpret_cast(10), nullptr), SQLITE_OK); + + CloseDelegate(rdbDelegatePtr1, mgr1, db1); + CloseDelegate(rdbDelegatePtr2, mgr2, db2); +} + +/** + * @tc.name: MultiSubUserDelegateSync001 + * @tc.desc: Test subUser delegate sync function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhaoliang + */ +HWTEST_F(DistributedDBSingleVerMultiSubUserTest, MultiSubUserDelegateSync001, TestSize.Level1) +{ + KvStoreDelegateManager mgr1(APP_ID, USER_ID, SUB_USER_1, INSTANCE_ID_1); + RuntimeConfig::SetPermissionCheckCallback([](const PermissionCheckParam ¶m, uint8_t flag) { + if ((flag & PermissionCheckFlag::CHECK_FLAG_RECEIVE) != 0) { + bool res = false; + if (param.extraConditions.find(KEY_SUB_USER) != param.extraConditions.end()) { + res = param.extraConditions.at(KEY_SUB_USER) == SUB_USER_1; + } + return res; + } + if (param.userId != USER_ID || param.appId != APP_ID || param.storeId != STORE_ID_1 || + (param.instanceId != INSTANCE_ID_1 && param.instanceId != 0)) { + return false; + } + return true; + }); + RuntimeConfig::SetPermissionConditionCallback([](const PermissionConditionParam ¶m) { + std::map res; + res.emplace(KEY_SUB_USER, SUB_USER_1); + return res; + }); + + KvStoreNbDelegate *delegatePtr1 = nullptr; + EXPECT_EQ(OpenDelegate("/subUser1", delegatePtr1, mgr1), OK); + ASSERT_NE(delegatePtr1, nullptr); + + Key key1 = {'k', '1'}; + Value value1 = {'v', '1'}; + delegatePtr1->Put(key1, value1); + + std::map result; + DBStatus status = g_tool.SyncTest(delegatePtr1, { DEVICE_B }, SYNC_MODE_PUSH_ONLY, result); + EXPECT_TRUE(status == OK); + EXPECT_EQ(result[DEVICE_B], OK); + + CloseDelegate(delegatePtr1, mgr1, STORE_ID_1); +} + +/** + * @tc.name: MultiSubUserDelegateSync002 + * @tc.desc: Test subUser delegate sync active if callback return true. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhaoliang + */ +HWTEST_F(DistributedDBSingleVerMultiSubUserTest, MultiSubUserDelegateSync002, TestSize.Level1) +{ + KvStoreDelegateManager mgr1(APP_ID, USER_ID, SUB_USER_1, INSTANCE_ID_1); + RuntimeConfig::SetSyncActivationCheckCallback([](const ActivationCheckParam ¶m) { + if (param.userId == USER_ID && param.appId == APP_ID && param.storeId == STORE_ID_1 && + param.instanceId == INSTANCE_ID_1) { + return true; + } + return false; + }); + + KvStoreNbDelegate *delegatePtr1 = nullptr; + EXPECT_EQ(OpenDelegate("/subUser1", delegatePtr1, mgr1, true), OK); + ASSERT_NE(delegatePtr1, nullptr); + + std::map result; + DBStatus status = g_tool.SyncTest(delegatePtr1, { DEVICE_B }, SYNC_MODE_PUSH_ONLY, result); + EXPECT_EQ(status, OK); + EXPECT_EQ(result[DEVICE_B], OK); + + CloseDelegate(delegatePtr1, mgr1, STORE_ID_1); +} + +} // namespace \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_multi_user_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_multi_user_test.cpp index 4de8c7ed..6ceb49ef 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_multi_user_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_multi_user_test.cpp @@ -486,6 +486,7 @@ HWTEST_F(DistributedDBSingleVerMultiUserTest, MultiUser003, TestSize.Level3) * @tc.expected: step4. success. */ EXPECT_TRUE(g_deviceB->Sync(SYNC_MODE_PUSH_ONLY, true) == OK); + std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME)); EXPECT_TRUE(observer->GetCallCount() == 1); // only A /** * @tc.steps: step5. deviceA have {k1,v1} diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_complex_sync_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_complex_sync_test.cpp index 83dc5191..c02cdb55 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_complex_sync_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_complex_sync_test.cpp @@ -1938,6 +1938,109 @@ HWTEST_F(DistributedDBSingleVerP2PComplexSyncTest, InterceptDataFail001, TestSiz EXPECT_EQ(g_deviceB->GetData(key, item), -E_NOT_FOUND); } +/** + * @tc.name: InterceptDataFail002 + * @tc.desc: test intercept data failed when sync + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBSingleVerP2PComplexSyncTest, InterceptDataFail002, TestSize.Level0) +{ + ASSERT_TRUE(g_kvDelegatePtr != nullptr); + /** + * @tc.steps: step1. device A set intercept data errCode and B put some data + * @tc.expected: step1. interface return ok + */ + g_kvDelegatePtr->SetReceiveDataInterceptor( + [](InterceptedData &data, const std::string &sourceID, const std::string &targetID) { + auto entries = data.GetEntries(); + LOGD("====on receive,size=%d", entries.size()); + for (size_t i = 0; i < entries.size(); i++) { + Key newKey; + int errCode = data.ModifyKey(i, newKey); + if (errCode != OK) { + return errCode; + } + } + return E_OK; + } + ); + Key key = {'1'}; + Value value = {'1'}; + g_deviceB->PutData(key, value, 1u, 0); // 1 is timestamp + /** + * @tc.steps: step2. device A sync to device B and check data + * @tc.expected: step2. interface return ok + */ + std::vector devices = { g_deviceB->GetDeviceId() }; + std::map result; + ASSERT_TRUE(g_tool.SyncTest(g_kvDelegatePtr, devices, SYNC_MODE_PULL_ONLY, result) == OK); + ASSERT_TRUE(result.size() == devices.size()); + for (const auto &pair : result) { + LOGD("dev %s, status %d", pair.first.c_str(), pair.second); + EXPECT_EQ(pair.second, INTERCEPT_DATA_FAIL); + } + Value actualValue; + EXPECT_EQ(g_kvDelegatePtr->Get(key, actualValue), NOT_FOUND); +} + +/** + * @tc.name: InterceptData001 + * @tc.desc: test intercept receive data when sync + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBSingleVerP2PComplexSyncTest, InterceptData001, TestSize.Level0) +{ + ASSERT_TRUE(g_kvDelegatePtr != nullptr); + /** + * @tc.steps: step1. device A set intercept data errCode and B put some data + * @tc.expected: step1. interface return ok + */ + g_kvDelegatePtr->SetReceiveDataInterceptor( + [](InterceptedData &data, const std::string &sourceID, const std::string &targetID) { + auto entries = data.GetEntries(); + LOGD("====on receive,size=%d", entries.size()); + for (size_t i = 0; i < entries.size(); i++) { + Key newKey = {'2'}; + int errCode = data.ModifyKey(i, newKey); + if (errCode != OK) { + return errCode; + } + Value newValue = {'3'}; + errCode = data.ModifyValue(i, newValue); + if (errCode != OK) { + return errCode; + } + } + return E_OK; + } + ); + Key key = {'1'}; + Value value = {'1'}; + g_deviceB->PutData(key, value, 1u, 0); // 1 is timestamp + /** + * @tc.steps: step2. device A sync to device B and check data + * @tc.expected: step2. interface return ok + */ + std::vector devices = { g_deviceB->GetDeviceId() }; + std::map result; + ASSERT_TRUE(g_tool.SyncTest(g_kvDelegatePtr, devices, SYNC_MODE_PULL_ONLY, result) == OK); + ASSERT_TRUE(result.size() == devices.size()); + for (const auto &pair : result) { + LOGD("dev %s, status %d", pair.first.c_str(), pair.second); + EXPECT_EQ(pair.second, OK); + } + Value actualValue; + EXPECT_EQ(g_kvDelegatePtr->Get(key, actualValue), NOT_FOUND); + key = {'2'}; + EXPECT_EQ(g_kvDelegatePtr->Get(key, actualValue), OK); + value = {'3'}; + EXPECT_EQ(actualValue, value); +} + /** * @tc.name: UpdateKey001 * @tc.desc: test update key can effect local data and sync data, without delete data diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_query_sync_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_query_sync_test.cpp index 2f836613..d663c43f 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_query_sync_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_query_sync_test.cpp @@ -646,7 +646,7 @@ HWTEST_F(DistributedDBSingleVerP2PQuerySyncTest, QueryRequestPacketTest001, Test /** * @tc.steps: step3. Serialization the message to a buffer. */ - int len = SingleVerSerializeManager::CalculateLen(&msg); + int len = static_cast(SingleVerSerializeManager::CalculateLen(&msg)); vector buffer(len); ASSERT_EQ(SingleVerSerializeManager::Serialization(buffer.data(), buffer.size(), &msg), E_OK); @@ -739,7 +739,7 @@ HWTEST_F(DistributedDBSingleVerP2PQuerySyncTest, QueryAckPacketTest001, TestSize /** * @tc.steps: step3. Serialization the message to a buffer. */ - int len = SingleVerSerializeManager::CalculateLen(&msg); + int len = static_cast(SingleVerSerializeManager::CalculateLen(&msg)); LOGE("test leng = %d", len); uint8_t *buffer = new (nothrow) uint8_t[len]; ASSERT_TRUE(buffer != nullptr); @@ -1444,7 +1444,7 @@ HWTEST_F(DistributedDBSingleVerP2PQuerySyncTest, VerifyLruMap001, TestSize.Level for (int i = startCount; i < maxCacheItems; i++) { std::string key = std::to_string(i); QueryWaterMark value; - value.recvWaterMark = i + 1; + value.recvWaterMark = static_cast(i + 1); EXPECT_EQ(lruMap.Put(key, value), E_OK); } diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_simple_sync_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_simple_sync_test.cpp index 6aec6ffd..b521762c 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_simple_sync_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_simple_sync_test.cpp @@ -1716,4 +1716,58 @@ HWTEST_F(DistributedDBSingleVerP2PSimpleSyncTest, GetWaterMarkInfo001, TestSize. EXPECT_EQ(res.second.sendMark, 0u); EXPECT_EQ(res.second.receiveMark, 0u); } -} // namespace \ No newline at end of file + +/** + * @tc.name: QuerySyncRetry001 + * @tc.desc: use sync retry sync use query pull by compress + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBSingleVerP2PSimpleSyncTest, QuerySyncRetry001, TestSize.Level3) +{ + if (g_kvDelegatePtr != nullptr) { + ASSERT_EQ(g_mgr.CloseKvStore(g_kvDelegatePtr), OK); + g_kvDelegatePtr = nullptr; + } + /** + * @tc.steps: step1. open db use Compress + * @tc.expected: step1, Pragma return OK. + */ + KvStoreNbDelegate::Option option; + option.isNeedCompressOnSync = true; + g_mgr.GetKvStore(STORE_ID, option, g_kvDelegateCallback); + ASSERT_TRUE(g_kvDelegateStatus == OK); + ASSERT_TRUE(g_kvDelegatePtr != nullptr); + + g_communicatorAggregator->SetDropMessageTypeByDevice(DEVICE_B, QUERY_SYNC_MESSAGE); + std::vector devices; + devices.push_back(g_deviceB->GetDeviceId()); + + /** + * @tc.steps: step2. set sync retry + * @tc.expected: step2, Pragma return OK. + */ + int pragmaData = 1; + PragmaData input = static_cast(&pragmaData); + EXPECT_TRUE(g_kvDelegatePtr->Pragma(SET_SYNC_RETRY, input) == OK); + + /** + * @tc.steps: step3. deviceA call sync and wait + * @tc.expected: step3. sync should return OK. + */ + std::map result; + auto query = Query::Select().PrefixKey({}); + ASSERT_TRUE(g_tool.SyncTest(g_kvDelegatePtr, devices, SYNC_MODE_PULL_ONLY, result, query) == OK); + + /** + * @tc.expected: step4. onComplete should be called, and status is time_out + */ + ASSERT_TRUE(result.size() == devices.size()); + for (const auto &pair : result) { + LOGD("dev %s, status %d", pair.first.c_str(), pair.second); + EXPECT_EQ(pair.second, OK); + } + g_communicatorAggregator->SetDropMessageTypeByDevice(DEVICE_B, UNKNOW_MESSAGE); +} +} \ No newline at end of file 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 cabce1e5..c23af4ef 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 @@ -102,6 +102,8 @@ public: static void TearDownTestCase(void); void SetUp(); void TearDown(); +protected: + static void WaitUntilNotify(KvVirtualDevice &virtualDevice); }; void DistributedDBSingleVerP2PSubscribeSyncTest::SetUpTestCase(void) @@ -179,6 +181,29 @@ void DistributedDBSingleVerP2PSubscribeSyncTest::TearDown(void) EXPECT_EQ(g_schemaMgr.SetPermissionCheckCallback(nullCallback), OK); } +void DistributedDBSingleVerP2PSubscribeSyncTest::WaitUntilNotify(KvVirtualDevice &virtualDevice) +{ + bool notify = false; + std::condition_variable cv; + std::mutex notifyMutex; + virtualDevice.SetPushNotifier([¬ify, &cv, ¬ifyMutex](const std::string &) { + { + std::lock_guard autoLock(notifyMutex); + notify = true; + } + cv.notify_all(); + }); + { + LOGI("Begin wait notify"); + std::unique_lock uniqueLock(notifyMutex); + (void)cv.wait_for(uniqueLock, std::chrono::milliseconds(DBConstant::MIN_TIMEOUT), [¬ify]() { + return notify; + }); + LOGI("End wait notify"); + } + virtualDevice.SetPushNotifier(nullptr); +} + void InitSubSchemaDb() { g_config.dataDir = g_testDir; @@ -262,7 +287,7 @@ HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, SubscribeRequestTest001, Te /** * @tc.steps: step3. Serialization the message to a buffer. */ - int len = SingleVerSerializeManager::CalculateLen(&msg); + int len = static_cast(SingleVerSerializeManager::CalculateLen(&msg)); LOGE("test leng = %d", len); uint8_t *buffer = new (nothrow) uint8_t[len]; ASSERT_TRUE(buffer != nullptr); @@ -315,7 +340,7 @@ HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, ControlAckTest001, TestSize /** * @tc.steps: step3. Serialization the message to a buffer. */ - int len = SingleVerSerializeManager::CalculateLen(&msg); + int len = static_cast(SingleVerSerializeManager::CalculateLen(&msg)); LOGE("test leng = %d", len); uint8_t *buffer = new (nothrow) uint8_t[len]; ASSERT_TRUE(buffer != nullptr); @@ -739,7 +764,7 @@ HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, SubscribeSync001, TestSize. Key key = {'1'}; status = g_schemaKvDelegatePtr->Put(key, value); EXPECT_EQ(status, OK); - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + WaitUntilNotify(*g_deviceB); /** * @tc.steps: step4. deviceB has {key11, SCHEMA_VALUE1} */ @@ -761,7 +786,7 @@ HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, SubscribeSync001, TestSize. Key key2 = {'2'}; status = g_schemaKvDelegatePtr->Put(key2, value2); EXPECT_EQ(status, OK); - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + WaitUntilNotify(*g_deviceB); /** * @tc.steps: step6. deviceB don't has {key2, SCHEMA_VALUE1} */ @@ -850,7 +875,7 @@ HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, SubscribeSync003, TestSize. {KEY_4, Value(SCHEMA_VALUE1.begin(), SCHEMA_VALUE1.end())}, {KEY_5, Value(SCHEMA_VALUE1.begin(), SCHEMA_VALUE1.end())}, })); - std::this_thread::sleep_for(std::chrono::milliseconds(500)); + WaitUntilNotify(*g_deviceB); /** * @tc.steps: step4. deviceB has k2k4, has no k1k3k5 @@ -873,7 +898,7 @@ HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, SubscribeSync003, TestSize. * @tc.require: AR000GOHO7 * @tc.author: lidongwei */ -HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, subscribeSync004, TestSize.Level1) +HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, SubscribeSync004, TestSize.Level1) { /** * @tc.steps: step1. InitSchemaDb @@ -899,7 +924,7 @@ HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, subscribeSync004, TestSize. {KEY_3, Value(SCHEMA_VALUE2.begin(), SCHEMA_VALUE2.end())}, {KEY_5, Value(SCHEMA_VALUE1.begin(), SCHEMA_VALUE1.end())}, })); - std::this_thread::sleep_for(std::chrono::milliseconds(500)); + WaitUntilNotify(*g_deviceB); /** * @tc.steps: step4. deviceB has k3, has no k1k5 @@ -919,7 +944,7 @@ HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, subscribeSync004, TestSize. * @tc.require: AR000GOHO7 * @tc.author: lidongwei */ -HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, subscribeSync005, TestSize.Level1) +HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, SubscribeSync005, TestSize.Level1) { /** * @tc.steps: step1. InitSchemaDb @@ -945,7 +970,7 @@ HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, subscribeSync005, TestSize. {key6, Value(SCHEMA_VALUE1.begin(), SCHEMA_VALUE1.end())}, {KEY_1, Value(SCHEMA_VALUE1.begin(), SCHEMA_VALUE1.end())}, })); - std::this_thread::sleep_for(std::chrono::milliseconds(500)); + WaitUntilNotify(*g_deviceB); /** * @tc.steps: step4. deviceB has key6, has no k1 @@ -1001,7 +1026,7 @@ HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, SubscribeSync006, TestSize. {key6, Value(SCHEMA_VALUE1.begin(), SCHEMA_VALUE1.end())}, {KEY_1, Value(SCHEMA_VALUE1.begin(), SCHEMA_VALUE1.end())}, })); - std::this_thread::sleep_for(std::chrono::seconds(1)); + WaitUntilNotify(*g_deviceB); /** * @tc.steps: step5. deviceB has key6, has no k1 @@ -1020,7 +1045,7 @@ HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, SubscribeSync006, TestSize. * @tc.require: AR000H5VLO * @tc.author: zhuwentao */ -HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, subscribeSync007, TestSize.Level1) +HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, SubscribeSync007, TestSize.Level1) { /** * @tc.steps: step1. InitSchemaDb @@ -1077,7 +1102,7 @@ HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, SubscribeSync008, TestSize. g_schemaKvDelegatePtr = nullptr; InitSubSchemaDb(); g_deviceB->Online(); - std::this_thread::sleep_for(std::chrono::seconds(1)); // sleep 1s for auto sync + WaitUntilNotify(*g_deviceB); /** * @tc.steps: step4. deviceB has key6 @@ -1315,7 +1340,7 @@ HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, SubscribeSync012, TestSize. Key key = { i }; dataKeys.push_back(key); EXPECT_EQ(g_schemaKvDelegatePtr->Put(key, Value(SCHEMA_VALUE1.begin(), SCHEMA_VALUE1.end())), OK); - std::this_thread::sleep_for(std::chrono::seconds(1)); + WaitUntilNotify(*g_deviceB); } /** * @tc.steps: step5. deviceB has key6, has no k1 @@ -1439,7 +1464,7 @@ HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, SubscribeSync014, TestSize. * @tc.require: DTS2023112110763 * @tc.author: mazhao */ -HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, subscribeSync015, TestSize.Level1) +HWTEST_F(DistributedDBSingleVerP2PSubscribeSyncTest, SubscribeSync015, TestSize.Level1) { /** * @tc.steps: step1. InitSchemaDb diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_sync_check_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_sync_check_test.cpp index 7f068b1f..5b82c09d 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_sync_check_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_sync_check_test.cpp @@ -424,15 +424,92 @@ HWTEST_F(DistributedDBSingleVerP2PSyncCheckTest, SecOptionCheck006, TestSize.Lev std::vector devices; devices.push_back(g_deviceB->GetDeviceId()); std::map result; - DBStatus status = g_tool.SyncTest(g_kvDelegatePtr, devices, SYNC_MODE_PUSH_PULL, result); + DBStatus status = g_tool.SyncTest(g_kvDelegatePtr, devices, SYNC_MODE_PULL_ONLY, result); EXPECT_EQ(status, OK); for (const auto &pair : result) { LOGD("dev %s, status %d", pair.first.c_str(), pair.second); EXPECT_TRUE(pair.second == OK); } + RuntimeContext::GetInstance()->SetProcessSystemApiAdapter(std::make_shared()); + g_syncInterfaceB->ForkGetSecurityOption(nullptr); +} + +/** + * @tc.name: sec option check Sync 007 + * @tc.desc: sync should send security option + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBSingleVerP2PSyncCheckTest, SecOptionCheck007, TestSize.Level0) +{ + /** + * @tc.steps: step1. fork check device security ability + * @tc.expected: step1. check param option should be S3 SECE. + */ + auto adapter = std::make_shared(); + RuntimeContext::GetInstance()->SetProcessSystemApiAdapter(adapter); + adapter->ForkCheckDeviceSecurityAbility([](const std::string &, const SecurityOption &option) { + EXPECT_EQ(option.securityLabel, SecurityLabel::S3); + EXPECT_EQ(option.securityFlag, SecurityFlag::SECE); + return true; + }); + /** + * @tc.steps: step2. sync twice + * @tc.expected: step2. sync success. + */ + std::vector devices; + devices.push_back(g_deviceB->GetDeviceId()); + std::map result; + g_tool.SyncTest(g_kvDelegatePtr, devices, SYNC_MODE_PUSH_ONLY, result); + auto status = g_tool.SyncTest(g_kvDelegatePtr, devices, SYNC_MODE_PUSH_ONLY, result); + ASSERT_TRUE(status == OK); + ASSERT_TRUE(result.size() == devices.size()); + for (const auto &pair : result) { + LOGD("dev %s, status %d", pair.first.c_str(), pair.second); + EXPECT_TRUE(pair.second == OK); + } RuntimeContext::GetInstance()->SetProcessSystemApiAdapter(nullptr); +} + +/** + * @tc.name: SecOptionCheck008 + * @tc.desc: pull compress sync when check device ability fail + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBSingleVerP2PSyncCheckTest, SecOptionCheck008, TestSize.Level0) +{ + auto adapter = std::make_shared(); + RuntimeContext::GetInstance()->SetProcessSystemApiAdapter(adapter); + auto deviceB = g_deviceB->GetDeviceId(); + adapter->ForkCheckDeviceSecurityAbility([deviceB](const std::string &dev, const SecurityOption &) { + if (dev != "real_device") { + return true; + } + return false; + }); + g_syncInterfaceB->ForkGetSecurityOption([](SecurityOption &option) { + option.securityLabel = SecurityLabel::S3; + option.securityFlag = SecurityFlag::SECE; + return E_OK; + }); + g_syncInterfaceB->SetCompressSync(true); + std::vector devices; + devices.push_back(deviceB); + std::map result; + DBStatus status = g_tool.SyncTest(g_kvDelegatePtr, devices, SYNC_MODE_PULL_ONLY, result); + EXPECT_EQ(status, OK); + for (const auto &pair : result) { + LOGD("dev %s, status %d", pair.first.c_str(), pair.second); + EXPECT_EQ(pair.second, SECURITY_OPTION_CHECK_ERROR); + } + + RuntimeContext::GetInstance()->SetProcessSystemApiAdapter(std::make_shared()); g_syncInterfaceB->ForkGetSecurityOption(nullptr); + g_syncInterfaceB->SetCompressSync(false); } #ifndef LOW_LEVEL_MEM_DEV @@ -1631,6 +1708,48 @@ HWTEST_F(DistributedDBSingleVerP2PSyncCheckTest, GetDataNotify002, TestSize.Leve std::this_thread::sleep_for(std::chrono::seconds(TEN_SECONDS)); } +/** + * @tc.name: DelaySync001 + * @tc.desc: Test delay first packet will not effect data conflict + * @tc.type: FUNC + * @tc.require: + * @tc.author: zqq + */ +HWTEST_F(DistributedDBSingleVerP2PSyncCheckTest, DelaySync001, TestSize.Level3) +{ + // B put (k, b) after A put (k, a) + Key key = {'k'}; + Value aValue = {'a'}; + g_kvDelegatePtr->Put(key, aValue); + std::this_thread::sleep_for(std::chrono::seconds(1)); // sleep 1s for data conflict + Timestamp currentTime = TimeHelper::GetSysCurrentTime() + TimeHelper::BASE_OFFSET; + Value bValue = {'b'}; + EXPECT_EQ(g_deviceB->PutData(key, bValue, currentTime, 0), OK); + + // delay time sync message, delay time/2 should greater than put sleep time + g_communicatorAggregator->SetTimeout(DEVICE_B, DBConstant::MAX_TIMEOUT); + g_communicatorAggregator->SetTimeout("real_device", DBConstant::MAX_TIMEOUT); + g_communicatorAggregator->RegBeforeDispatch([](const std::string &dstTarget, const Message *msg) { + if (dstTarget == DEVICE_B && msg->GetMessageId() == MessageId::TIME_SYNC_MESSAGE) { + std::this_thread::sleep_for(std::chrono::seconds(3)); // sleep for 3s + } + }); + + // A call sync and (k, b) in A + std::vector devices; + devices.push_back(g_deviceB->GetDeviceId()); + std::map result; + DBStatus status = g_tool.SyncTest(g_kvDelegatePtr, devices, SYNC_MODE_PULL_ONLY, result, true); + EXPECT_EQ(status, OK); + EXPECT_EQ(result.size(), devices.size()); + EXPECT_EQ(result[DEVICE_B], OK); + + Value actualValue; + g_kvDelegatePtr->Get(key, actualValue); + EXPECT_EQ(actualValue, bValue); + g_communicatorAggregator->RegBeforeDispatch(nullptr); +} + /** * @tc.name: KVAbilitySyncOpt001 * @tc.desc: check ability sync 2 packet @@ -1991,4 +2110,4 @@ HWTEST_F(DistributedDBSingleVerP2PSyncCheckTest, KVTimeChange001, TestSize.Level EXPECT_EQ(messageCount, 0); g_communicatorAggregator->RegOnDispatch(nullptr); } -} // namespace \ No newline at end of file +} \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_syncer_device_manager_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_syncer_device_manager_test.cpp index eb4fc9eb..5b76ae62 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_syncer_device_manager_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_syncer_device_manager_test.cpp @@ -194,8 +194,7 @@ HWTEST_F(DistributedDBSyncerDeviceManagerTest, GetDevices001, TestSize.Level0) * @tc.expected: step1, GetDevices return deviceB,C */ g_deviceManager->GetOnlineDevices(deviceList); - int size = deviceList.size(); - ASSERT_EQ(size, 2); + ASSERT_TRUE(deviceList.size() == 2); EXPECT_TRUE(deviceList[0] == g_deviceB->GetDeviceId()); EXPECT_TRUE(deviceList[1] == g_deviceC->GetDeviceId()); g_communicatorAggregator->OfflineDevice(g_deviceC->GetDeviceId()); diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/kv_virtual_device.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/kv_virtual_device.cpp index 2c068f9b..c2b58e7b 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/kv_virtual_device.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/kv_virtual_device.cpp @@ -145,4 +145,10 @@ void KvVirtualDevice::EraseWaterMark(const std::string &dev) { metadata_->EraseDeviceWaterMark(dev, true); } + +void KvVirtualDevice::SetPushNotifier(const std::function &pushNotifier) +{ + auto *syncAble = static_cast(storage_); + syncAble->SetPushNotifier(pushNotifier); +} } // namespace DistributedDB \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/kv_virtual_device.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/kv_virtual_device.h index a3be5e48..80e266c4 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/kv_virtual_device.h +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/kv_virtual_device.h @@ -43,6 +43,8 @@ public: void SetSaveDataCallback(const std::function &callback); void EraseWaterMark(const std::string &dev); + + void SetPushNotifier(const std::function &pushNotifier); }; } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_communicator.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_communicator.cpp index 85ff9c9b..6386e80c 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_communicator.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_communicator.cpp @@ -139,6 +139,7 @@ void VirtualCommunicator::SetCommunicatorMtuSize(uint32_t mtuSize) uint32_t VirtualCommunicator::GetTimeout() const { + LOGD("[VirtualCommunicator] Get timeout %" PRIu32, timeout_); return timeout_; } diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_communicator_aggregator.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_communicator_aggregator.cpp index 20764e07..c9e9b1a1 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_communicator_aggregator.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_communicator_aggregator.cpp @@ -100,10 +100,21 @@ void VirtualCommunicatorAggregator::RunOnConnectCallback(const std::string &targ int VirtualCommunicatorAggregator::GetLocalIdentity(std::string &outTarget) const { - outTarget = "DEVICES_A"; + std::lock_guard lock(localDeviceIdMutex_); + if (localDeviceId_.empty()) { + outTarget = "DEVICES_A"; + } else { + outTarget = localDeviceId_; + } return E_OK; } +void VirtualCommunicatorAggregator::SetLocalDeviceId(const std::string &deviceId) +{ + std::lock_guard lock(localDeviceIdMutex_); + localDeviceId_ = deviceId; +} + void VirtualCommunicatorAggregator::OnlineDevice(const std::string &deviceId) const { if (!isEnable_) { @@ -174,6 +185,15 @@ void VirtualCommunicatorAggregator::DispatchMessage(const std::string &srcTarget inMsg = nullptr; return CallSendEnd(-E_PERIPHERAL_INTERFACE_FAIL, onEnd); } + if (beforeDispatch_) { + beforeDispatch_(dstTarget, inMsg); + } + DispatchMessageInner(srcTarget, dstTarget, inMsg, onEnd); +} + +void VirtualCommunicatorAggregator::DispatchMessageInner(const std::string &srcTarget, const std::string &dstTarget, + const Message *inMsg, const OnSendEnd &onEnd) +{ std::lock_guard lock(communicatorsLock_); auto iter = communicators_.find(dstTarget); if (iter != communicators_.end()) { @@ -339,4 +359,10 @@ void VirtualCommunicatorAggregator::EnableCommunicator() communicator.second->Disable(); } } + +void VirtualCommunicatorAggregator::RegBeforeDispatch( + const std::function &beforeDispatch) +{ + beforeDispatch_ = beforeDispatch; +} } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_communicator_aggregator.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_communicator_aggregator.h index de75b313..1adc4c96 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_communicator_aggregator.h +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_communicator_aggregator.h @@ -87,12 +87,18 @@ public: void EnableCommunicator(); - ~VirtualCommunicatorAggregator() {}; - VirtualCommunicatorAggregator() {}; + void RegBeforeDispatch(const std::function &beforeDispatch); + + void SetLocalDeviceId(const std::string &deviceId); + + ~VirtualCommunicatorAggregator() override = default; + VirtualCommunicatorAggregator() = default; private: void CallSendEnd(int errCode, const OnSendEnd &onEnd); void DelayTimeHandle(uint32_t messageId, const std::string &dstTarget); + void DispatchMessageInner(const std::string &srcTarget, const std::string &dstTarget, const Message *inMsg, + const OnSendEnd &onEnd); mutable std::mutex communicatorsLock_; std::map communicators_; @@ -104,6 +110,7 @@ private: CommunicatorLackCallback onCommLack_; OnConnectCallback onConnect_; std::function onDispatch_; + std::function beforeDispatch_; std::string userId_; uint32_t sendDelayTime_ = 0; @@ -111,6 +118,9 @@ private: uint32_t delayTimes_ = 0; // ms uint32_t skipTimes_ = 0; std::set delayDevices_; + + mutable std::mutex localDeviceIdMutex_; + std::string localDeviceId_; }; } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_relational_ver_sync_db_interface.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_relational_ver_sync_db_interface.h index a542ce0b..12830ec5 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_relational_ver_sync_db_interface.h +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_relational_ver_sync_db_interface.h @@ -90,7 +90,7 @@ public: int GetVirtualSyncData(const std::string &tableName, const std::string &hashKey, VirtualRowData &data); int InterceptData(std::vector &entries, - const std::string &sourceID, const std::string &targetID) const override + const std::string &sourceID, const std::string &targetID, bool isPush) const override { return E_OK; } diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_single_ver_sync_db_Interface.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_single_ver_sync_db_Interface.cpp index 33bd2540..b3c402a0 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_single_ver_sync_db_Interface.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_single_ver_sync_db_Interface.cpp @@ -18,6 +18,7 @@ #include #include +#include "data_compression.h" #include "db_common.h" #include "db_errno.h" #include "generic_single_ver_kv_entry.h" @@ -170,7 +171,7 @@ int VirtualSingleVerSyncDBInterface::PutData(const Key &key, const Value &value, item.value = value; item.timestamp = time; item.writeTimestamp = time; - item.flag = flag; + item.flag = static_cast(flag); item.isLocal = true; dbData_.push_back(item); return E_OK; @@ -385,6 +386,11 @@ void VirtualSingleVerSyncDBInterface::SetSecurityOption(SecurityOption &option) void VirtualSingleVerSyncDBInterface::NotifyRemotePushFinished(const std::string &targetId) const { + std::lock_guard autoLock(pushNotifierMutex_); + if (pushNotifier_) { + pushNotifier_(targetId); + LOGI("[VirtualSingleVerSyncDBInterface] Notify remote push finished"); + } } int VirtualSingleVerSyncDBInterface::GetDatabaseCreateTimestamp(Timestamp &outTime) const @@ -447,11 +453,18 @@ int VirtualSingleVerSyncDBInterface::DeleteMetaDataByPrefixKey(const Key &keyPre int VirtualSingleVerSyncDBInterface::GetCompressionOption(bool &needCompressOnSync, uint8_t &compressionRate) const { + if (compressSync_) { + needCompressOnSync = true; + compressionRate = 100; // compress rate 100 + } return E_OK; } int VirtualSingleVerSyncDBInterface::GetCompressionAlgo(std::set &algorithmSet) const { + if (compressSync_) { + DataCompression::GetCompressionAlgo(algorithmSet); + } return E_OK; } @@ -466,7 +479,7 @@ int VirtualSingleVerSyncDBInterface::CheckAndInitQueryCondition(QueryObject &que } int VirtualSingleVerSyncDBInterface::InterceptData(std::vector &entries, - const std::string &sourceID, const std::string &targetID) const + const std::string &sourceID, const std::string &targetID, bool isPush) const { return E_OK; } @@ -602,4 +615,15 @@ void VirtualSingleVerSyncDBInterface::ForkGetSecurityOption(std::function &pushNotifier) +{ + std::lock_guard autoLock(pushNotifierMutex_); + pushNotifier_ = pushNotifier; +} + +void VirtualSingleVerSyncDBInterface::SetCompressSync(bool compressSync) +{ + compressSync_ = compressSync; +} } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_single_ver_sync_db_Interface.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_single_ver_sync_db_Interface.h index e34ceafb..b6e14116 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_single_ver_sync_db_Interface.h +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_single_ver_sync_db_Interface.h @@ -119,7 +119,7 @@ public: int CheckAndInitQueryCondition(QueryObject &query) const override; int InterceptData(std::vector &entries, const std::string &sourceID, - const std::string &targetID) const override; + const std::string &targetID, bool isPush) const override; int AddSubscribe(const std::string &subscribeId, const QueryObject &query, bool needCacheSubscribe) override; @@ -145,6 +145,10 @@ public: void SetSaveDataCallback(const std::function &callback); void ForkGetSecurityOption(std::function callBack); + + void SetPushNotifier(const std::function &pushNotifier); + + void SetCompressSync(bool compressSync); private: int GetSyncData(Timestamp begin, Timestamp end, const DataSizeSpecInfo &dataSizeInfo, std::vector &dataItems, ContinueToken &continueStmtToken) const; @@ -185,6 +189,11 @@ private: std::function saveDataCallback_; std::function getSecurityOptionCallBack_; + + mutable std::mutex pushNotifierMutex_; + std::function pushNotifier_; + + bool compressSync_ = false; }; } // namespace DistributedDB diff --git a/kv_store/interfaces/cj/BUILD.gn b/kv_store/interfaces/cj/BUILD.gn new file mode 100644 index 00000000..8909e13a --- /dev/null +++ b/kv_store/interfaces/cj/BUILD.gn @@ -0,0 +1,64 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//build/ohos/ace/ace.gni") +import("//foundation/distributeddatamgr/kv_store/kv_store.gni") + +ohos_shared_library("cj_distributed_kv_store_ffi") { + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + + include_dirs = [ + "${kv_store_base_path}/frameworks/common", + "${kv_store_base_path}/frameworks/jskitsimpl/distributedkvstore/include", + "${kv_store_base_path}/frameworks/innerkitsimpl/distributeddatafwk/include", + "${kv_store_base_path}/frameworks/innerkitsimpl/kvdb/include", + "${kv_store_base_path}/frameworks/cj/include", + ] + + if (product_name != "ohos-sdk") { + sources = [ + "../../frameworks/cj/src/distributed_kv_store_ffi.cpp", + "../../frameworks/cj/src/distributed_kv_store_impl.cpp", + "../../frameworks/cj/src/distributed_kv_store_utils.cpp", + ] + + deps = [ "${kv_store_base_path}/interfaces/innerkits/distributeddata:distributeddata_inner" ] + + external_deps = [ + "ability_base:want", + "ability_runtime:ability_connect_callback_stub", + "ability_runtime:ability_manager", + "ability_runtime:abilitykit_native", + "ability_runtime:napi_base_context", + "c_utils:utils", + "common_event_service:cesfwk_innerkits", + "hilog:libhilog", + "ipc:ipc_single", + "napi:ace_napi", + "napi:cj_bind_ffi", + "napi:cj_bind_native", + ] + } else { + defines += [ "PREVIEWER" ] + sources = + [ "../../kvstoremock/frameworks/cj/distributed_kv_store_mock.cpp" ] + } + innerapi_tags = [ "platformsdk" ] + subsystem_name = "distributeddatamgr" + part_name = "kv_store" +} diff --git a/kv_store/interfaces/innerkits/distributeddata/BUILD.gn b/kv_store/interfaces/innerkits/distributeddata/BUILD.gn index bea2ddcf..c9ad7d30 100644 --- a/kv_store/interfaces/innerkits/distributeddata/BUILD.gn +++ b/kv_store/interfaces/innerkits/distributeddata/BUILD.gn @@ -44,7 +44,6 @@ config("distributeddatafwk_config") { "../../../frameworks/innerkitsimpl/kvdb/src", "${datashare_innerapi_path}/common/include", "${datashare_innerapi_path}/provider/include", - "${distributedfilejs_path}/interfaces/kits/js/src/mod_securitylabel", ] } @@ -54,6 +53,7 @@ config("distributeddatafwk_public_config") { include_dirs = [ "include", "../../../frameworks/innerkitsimpl/distributeddatafwk/include", + "../../../frameworks/common", ] } @@ -112,11 +112,14 @@ external_deps_config = [ "huks:libhukssdk", "ipc:ipc_single", "samgr:samgr_proxy", + "file_api:securitylabel", ] ohos_shared_library("distributeddata_inner") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false @@ -136,6 +139,8 @@ ohos_shared_library("distributeddata_inner") { ohos_shared_library("distributeddata_client_sync") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false @@ -151,6 +156,7 @@ ohos_shared_library("distributeddata_client_sync") { external_deps = [ "c_utils:utils", + "file_api:securitylabel", "hilog:libhilog", ] innerapi_tags = [ "platformsdk" ] diff --git a/kv_store/interfaces/innerkits/distributeddata/include/end_point.h b/kv_store/interfaces/innerkits/distributeddata/include/end_point.h index e8e070ca..34692c7b 100644 --- a/kv_store/interfaces/innerkits/distributeddata/include/end_point.h +++ b/kv_store/interfaces/innerkits/distributeddata/include/end_point.h @@ -83,13 +83,13 @@ public: * @return Data size. */ virtual uint32_t GetMtuSize(const std::string &identifier) = 0; - + /** * @brief Obtains the ID of the loacl device info. * @return loacl device info. */ virtual std::string GetLocalDeviceInfos() = 0; - + /** * @brief Determines whether the device has the capability of data of this level. * @param devId Target device ID. diff --git a/kv_store/interfaces/innerkits/distributeddata/include/single_kvstore.h b/kv_store/interfaces/innerkits/distributeddata/include/single_kvstore.h index 5e0d4fe0..cd64998c 100644 --- a/kv_store/interfaces/innerkits/distributeddata/include/single_kvstore.h +++ b/kv_store/interfaces/innerkits/distributeddata/include/single_kvstore.h @@ -308,6 +308,29 @@ public: { return Status::SUCCESS; } + + /** + * @brief Get all entries in this store by deviceId. + * @param device deviceId. + * @param entries Entries will be returned in this parameter. + * @return Return SUCCESS for success, others for failure. + */ + virtual Status GetDeviceEntries(const std::string &device, std::vector &entries) const + { + return Status::SUCCESS; + } + + /** + * @brief set option of store. + * + * set option of store + * + * @return Return SUCCESS for success, others for failure. + */ + virtual Status SetConfig(const StoreConfig &storeConfig) + { + return Status::SUCCESS; + } }; } // namespace DistributedKv } // namespace OHOS diff --git a/kv_store/interfaces/innerkits/distributeddata/include/types.h b/kv_store/interfaces/innerkits/distributeddata/include/types.h index d56e684e..aa7a6716 100644 --- a/kv_store/interfaces/innerkits/distributeddata/include/types.h +++ b/kv_store/interfaces/innerkits/distributeddata/include/types.h @@ -371,6 +371,20 @@ struct Group { std::string groupId = ""; }; +/** + * @brief Cloud config +*/ +struct CloudConfig { + /** + * @brief enable cloud + */ + bool enableCloud = false; + /** + * @brief Set cloud sync is auto sync + */ + bool autoSync = false; +}; + enum IndexType : uint32_t { /** * use btree index type in database @@ -525,6 +539,10 @@ struct Options { uint32_t pageSize = 32u; uint32_t cacheSize = 2048u; } config; + /** + * Set cloud config of kv store. + */ + CloudConfig cloudConfig; }; /** @@ -542,6 +560,15 @@ struct UserInfo { int32_t userType; }; +/** + * @brief Cloud sync progress status. +*/ +enum Progress { + SYNC_BEGIN = 0, + SYNC_IN_PROGRESS, + SYNC_FINISH, +}; + /** * @brief Cloud sync statistic. */ @@ -628,6 +655,16 @@ struct SwitchNotification { */ SwitchState state = SwitchState::INSERT; }; + +/** + * @brief Set config of kv store. + */ +struct StoreConfig { + /** + * Set cloud config of kv store. + */ + CloudConfig cloudConfig; +}; } // namespace DistributedKv } // namespace OHOS #endif // DISTRIBUTED_KVSTORE_TYPES_H diff --git a/kv_store/interfaces/innerkits/distributeddatamgr/BUILD.gn b/kv_store/interfaces/innerkits/distributeddatamgr/BUILD.gn index 25ac5fda..a2ad46b1 100644 --- a/kv_store/interfaces/innerkits/distributeddatamgr/BUILD.gn +++ b/kv_store/interfaces/innerkits/distributeddatamgr/BUILD.gn @@ -36,6 +36,8 @@ config("data_mgr_public_config") { ohos_shared_library("distributeddata_mgr") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false diff --git a/kv_store/interfaces/jskits/distributeddata/BUILD.gn b/kv_store/interfaces/jskits/distributeddata/BUILD.gn index 24e36119..3481180e 100644 --- a/kv_store/interfaces/jskits/distributeddata/BUILD.gn +++ b/kv_store/interfaces/jskits/distributeddata/BUILD.gn @@ -13,7 +13,6 @@ import("//build/ohos.gni") import("//build/ohos/ace/ace.gni") -import("//foundation/distributeddatamgr/data_share/datashare.gni") import("//foundation/distributeddatamgr/kv_store/kv_store.gni") base_output_path = get_label_info(":distributed_data_js", "target_out_dir") @@ -40,6 +39,8 @@ ohos_copy("distributeddatamgr_declaration") { ohos_shared_library("distributeddata") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false @@ -49,8 +50,6 @@ ohos_shared_library("distributeddata") { "//foundation/distributeddatamgr/kv_store/frameworks/jskitsimpl/distributeddata/include", "//foundation/distributeddatamgr/kv_store/frameworks/innerkitsimpl/distributeddatafwk/include", "//foundation/distributeddatamgr/kv_store/frameworks/innerkitsimpl/kvdb/include", - "${datashare_innerapi_path}/common/include", - "${datashare_innerapi_path}/provider/include", ] sources = [ @@ -86,6 +85,11 @@ ohos_shared_library("distributeddata") { "napi:ace_napi", ] + public_external_deps = [ + "data_share:datashare_common", + "data_share:datashare_provider", + ] + subsystem_name = "distributeddatamgr" relative_install_dir = "module/data" part_name = "kv_store" diff --git a/kv_store/interfaces/jskits/distributedkvstore/BUILD.gn b/kv_store/interfaces/jskits/distributedkvstore/BUILD.gn index c82a6537..30fb7b48 100644 --- a/kv_store/interfaces/jskits/distributedkvstore/BUILD.gn +++ b/kv_store/interfaces/jskits/distributedkvstore/BUILD.gn @@ -13,7 +13,6 @@ import("//build/ohos.gni") import("//build/ohos/ace/ace.gni") -import("//foundation/distributeddatamgr/data_share/datashare.gni") import("//foundation/distributeddatamgr/kv_store/kv_store.gni") base_output_path = get_label_info(":distributed_kvstore_js", "target_out_dir") @@ -40,6 +39,8 @@ ohos_copy("distributeddatamgr_declaration") { ohos_shared_library("distributedkvstore") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false @@ -49,8 +50,6 @@ ohos_shared_library("distributedkvstore") { "//foundation/distributeddatamgr/kv_store/frameworks/jskitsimpl/distributedkvstore/include", "//foundation/distributeddatamgr/kv_store/frameworks/innerkitsimpl/distributeddatafwk/include", "//foundation/distributeddatamgr/kv_store/frameworks/innerkitsimpl/kvdb/include", - "${datashare_innerapi_path}/common/include", - "${datashare_innerapi_path}/provider/include", ] sources = [ @@ -86,6 +85,11 @@ ohos_shared_library("distributedkvstore") { "napi:ace_napi", ] + public_external_deps = [ + "data_share:datashare_common", + "data_share:datashare_provider", + ] + subsystem_name = "distributeddatamgr" relative_install_dir = "module/data" part_name = "kv_store" diff --git a/kv_store/kv_store.gni b/kv_store/kv_store.gni index d1ae3ee8..e7387205 100644 --- a/kv_store/kv_store.gni +++ b/kv_store/kv_store.gni @@ -17,8 +17,6 @@ kv_store_native_path = "${kv_store_base_path}/frameworks/native" kv_store_api_path = "${kv_store_base_path}/interfaces/inner_api" -distributedfilejs_path = "//foundation/distributeddatamgr/distributedfile" - third_party_path = "//third_party" use_platform_win = "${current_os}_${current_cpu}" == "mingw_x86_64" diff --git a/kv_store/kvstoremock/frameworks/cj/distributed_kv_store_mock.cpp b/kv_store/kvstoremock/frameworks/cj/distributed_kv_store_mock.cpp new file mode 100644 index 00000000..bee9e10e --- /dev/null +++ b/kv_store/kvstoremock/frameworks/cj/distributed_kv_store_mock.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cj_ffi/cj_common_ffi.h" + +extern "C" { + FFI_EXPORT int FfiOHOSDistributedKVStoreCreateKVManager = 0; + + FFI_EXPORT int FfiOHOSDistributedKVStoreGetKVStore = 0; + + FFI_EXPORT int FfiOHOSDistributedKVStoreCloseKVStore = 0; + + FFI_EXPORT int FfiOHOSDistributedKVStoreDeleteKVStore = 0; + + FFI_EXPORT int FfiOHOSDistributedKVStoreGetAllKVStoreId = 0; + + FFI_EXPORT int FfiOHOSDistributedKVStoreSingleKVStorePut = 0; + + FFI_EXPORT int FfiOHOSDistributedKVStoreSingleKVStorePutBatch = 0; + + FFI_EXPORT int FfiOHOSDistributedKVStoreSingleKVStoreDelete = 0; + + FFI_EXPORT int FfiOHOSDistributedKVStoreSingleKVStoreDeleteBatch = 0; + + FFI_EXPORT int FfiOHOSDistributedKVStoreSingleKVStoreGet = 0; + + FFI_EXPORT int FfiOHOSDistributedKVStoreSingleKVStoreBackup = 0; + + FFI_EXPORT int FfiOHOSDistributedKVStoreSingleKVStoreRestore = 0; + + FFI_EXPORT int FfiOHOSDistributedKVStoreSingleKVStoreStartTransaction = 0; + + FFI_EXPORT int FfiOHOSDistributedKVStoreSingleKVStoreCommit = 0; + + FFI_EXPORT int FfiOHOSDistributedKVStoreSingleKVStoreRollback = 0; + + FFI_EXPORT int FfiOHOSDistributedKVStoreSingleKVStoreEnableSync = 0; + + FFI_EXPORT int FfiOHOSDistributedKVStoreSingleKVStoreSetSyncParam = 0; + + FFI_EXPORT int FfiOHOSDistributedKVStoreQueryConstructor = 0; + + FFI_EXPORT int FfiOHOSDistributedKVStoreQueryReset = 0; + + FFI_EXPORT int FfiOHOSDistributedKVStoreQueryEqualTo = 0; + + FFI_EXPORT int FfiOHOSDistributedKVStoreDeviceKVStoreGet = 0; + + FFI_EXPORT int FfiOHOSDistributedKVStoreDeviceKVStoreGetEntries = 0; + + FFI_EXPORT int FfiOHOSDistributedKVStoreDeviceKVStoreGetEntriesQuery = 0; + + FFI_EXPORT int FfiOHOSDistributedKVStoreDeviceKVStoreGetResultSet = 0; + + FFI_EXPORT int FfiOHOSDistributedKVStoreDeviceKVStoreGetResultSetQuery = 0; + + FFI_EXPORT int FfiOHOSDistributedKVStoreDeviceKVStoreGetResultSize = 0; + + FFI_EXPORT int FfiOHOSDistributedKVStoreKVStoreResultSetGetCount = 0; +} \ No newline at end of file diff --git a/kv_store/kvstoremock/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h b/kv_store/kvstoremock/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h index abb6c902..f8eeb463 100644 --- a/kv_store/kvstoremock/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h +++ b/kv_store/kvstoremock/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h @@ -54,6 +54,7 @@ public: const std::function &&)> &onResult) override; Status GetEntries(const Key &prefix, std::vector &entries) const override; Status GetEntries(const DataQuery &query, std::vector &entries) const override; + Status GetDeviceEntries(const std::string &device, std::vector &entries) const override; Status GetResultSet(const Key &prefix, std::shared_ptr &resultSet) const override; Status GetResultSet(const DataQuery &query, std::shared_ptr &resultSet) const override; Status CloseResultSet(std::shared_ptr &resultSet) override; diff --git a/kv_store/kvstoremock/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp b/kv_store/kvstoremock/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp index b6769b79..bd75dcb4 100644 --- a/kv_store/kvstoremock/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp +++ b/kv_store/kvstoremock/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp @@ -36,7 +36,7 @@ Status SingleStoreImpl::Put(const Key &key, const Value &value) { std::shared_lock lock(rwMutex_); if (dbStore_ == nullptr) { - ZLOGE("db:%{public}s already closed!", storeId_.c_str()); + ZLOGE("db:%{public}s already closed!", StoreUtil::Anonymous(storeId_).c_str()); return ALREADY_CLOSED; } @@ -60,7 +60,7 @@ Status SingleStoreImpl::PutBatch(const std::vector &entries) { std::shared_lock lock(rwMutex_); if (dbStore_ == nullptr) { - ZLOGE("db:%{public}s already closed!", storeId_.c_str()); + ZLOGE("db:%{public}s already closed!", StoreUtil::Anonymous(storeId_).c_str()); return ALREADY_CLOSED; } @@ -88,7 +88,7 @@ Status SingleStoreImpl::Delete(const Key &key) { std::shared_lock lock(rwMutex_); if (dbStore_ == nullptr) { - ZLOGE("db:%{public}s already closed!", storeId_.c_str()); + ZLOGE("db:%{public}s already closed!", StoreUtil::Anonymous(storeId_).c_str()); return ALREADY_CLOSED; } @@ -110,7 +110,7 @@ Status SingleStoreImpl::DeleteBatch(const std::vector &keys) { std::shared_lock lock(rwMutex_); if (dbStore_ == nullptr) { - ZLOGE("db:%{public}s already closed!", storeId_.c_str()); + ZLOGE("db:%{public}s already closed!", StoreUtil::Anonymous(storeId_).c_str()); return ALREADY_CLOSED; } @@ -136,14 +136,14 @@ Status SingleStoreImpl::StartTransaction() { std::shared_lock lock(rwMutex_); if (dbStore_ == nullptr) { - ZLOGE("db:%{public}s already closed!", storeId_.c_str()); + ZLOGE("db:%{public}s already closed!", StoreUtil::Anonymous(storeId_).c_str()); return ALREADY_CLOSED; } auto dbStatus = dbStore_->StartTransaction(); auto status = StoreUtil::ConvertStatus(dbStatus); if (status != SUCCESS) { - ZLOGE("status:0x%{public}x storeId:%{public}s", status, storeId_.c_str()); + ZLOGE("status:0x%{public}x storeId:%{public}s", status, StoreUtil::Anonymous(storeId_).c_str()); } return status; } @@ -152,14 +152,14 @@ Status SingleStoreImpl::Commit() { std::shared_lock lock(rwMutex_); if (dbStore_ == nullptr) { - ZLOGE("db:%{public}s already closed!", storeId_.c_str()); + ZLOGE("db:%{public}s already closed!", StoreUtil::Anonymous(storeId_).c_str()); return ALREADY_CLOSED; } auto dbStatus = dbStore_->Commit(); auto status = StoreUtil::ConvertStatus(dbStatus); if (status != SUCCESS) { - ZLOGE("status:0x%{public}x storeId:%{public}s", status, dbStore_->GetStoreId().c_str()); + ZLOGE("status:0x%{public}x storeId:%{public}s", status, StoreUtil::Anonymous(storeId_).c_str()); } return status; } @@ -168,14 +168,14 @@ Status SingleStoreImpl::Rollback() { std::shared_lock lock(rwMutex_); if (dbStore_ == nullptr) { - ZLOGE("db:%{public}s already closed!", storeId_.c_str()); + ZLOGE("db:%{public}s already closed!", StoreUtil::Anonymous(storeId_).c_str()); return ALREADY_CLOSED; } auto dbStatus = dbStore_->Rollback(); auto status = StoreUtil::ConvertStatus(dbStatus); if (status != SUCCESS) { - ZLOGE("status:0x%{public}x storeId:%{public}s", status, storeId_.c_str()); + ZLOGE("status:0x%{public}x storeId:%{public}s", status, StoreUtil::Anonymous(storeId_).c_str()); } return status; } @@ -194,7 +194,7 @@ Status SingleStoreImpl::Get(const Key &key, Value &value) { std::shared_lock lock(rwMutex_); if (dbStore_ == nullptr) { - ZLOGE("db:%{public}s already closed!", storeId_.c_str()); + ZLOGE("db:%{public}s already closed!", StoreUtil::Anonymous(storeId_).c_str()); return ALREADY_CLOSED; } @@ -295,7 +295,7 @@ Status SingleStoreImpl::CloseResultSet(std::shared_ptr &resultSet) auto status = resultSet->Close(); if (status != SUCCESS) { - ZLOGE("status:0x%{public}x storeId:%{public}s", status, storeId_.c_str()); + ZLOGE("status:0x%{public}x storeId:%{public}s", status, StoreUtil::Anonymous(storeId_).c_str()); } resultSet = nullptr; return status; @@ -305,7 +305,7 @@ Status SingleStoreImpl::GetCount(const DataQuery &query, int &result) const { std::shared_lock lock(rwMutex_); if (dbStore_ == nullptr) { - ZLOGE("db:%{public}s already closed!", storeId_.c_str()); + ZLOGE("db:%{public}s already closed!", StoreUtil::Anonymous(storeId_).c_str()); return ALREADY_CLOSED; } @@ -322,7 +322,7 @@ Status SingleStoreImpl::GetSecurityLevel(SecurityLevel &secLevel) const { std::shared_lock lock(rwMutex_); if (dbStore_ == nullptr) { - ZLOGE("db:%{public}s already closed!", storeId_.c_str()); + ZLOGE("db:%{public}s already closed!", StoreUtil::Anonymous(storeId_).c_str()); return ALREADY_CLOSED; } @@ -340,7 +340,7 @@ Status SingleStoreImpl::RemoveDeviceData(const std::string &device) { std::shared_lock lock(rwMutex_); if (dbStore_ == nullptr) { - ZLOGE("db:%{public}s already closed!", storeId_.c_str()); + ZLOGE("db:%{public}s already closed!", StoreUtil::Anonymous(storeId_).c_str()); return ALREADY_CLOSED; } @@ -394,7 +394,7 @@ Status SingleStoreImpl::GetResultSet(const DBQuery &query, std::shared_ptr lock(rwMutex_); if (dbStore_ == nullptr) { - ZLOGE("db:%{public}s already closed!", storeId_.c_str()); + ZLOGE("db:%{public}s already closed!", StoreUtil::Anonymous(storeId_).c_str()); return ALREADY_CLOSED; } @@ -411,7 +411,7 @@ Status SingleStoreImpl::GetEntries(const DBQuery &query, std::vector &ent { std::shared_lock lock(rwMutex_); if (dbStore_ == nullptr) { - ZLOGE("db:%{public}s already closed!", storeId_.c_str()); + ZLOGE("db:%{public}s already closed!", StoreUtil::Anonymous(storeId_).c_str()); return ALREADY_CLOSED; } @@ -442,6 +442,12 @@ Status SingleStoreImpl::Sync(const std::vector &devices, SyncMode m { return SERVER_UNAVAILABLE; } + +Status SingleStoreImpl::GetDeviceEntries(const std::string &device, std::vector &entries) const +{ + return SUCCESS; +} + Status SingleStoreImpl::RegisterSyncCallback(std::shared_ptr callback) { return SERVER_UNAVAILABLE; diff --git a/kv_store/kvstoremock/frameworks/jskitsimpl/distributeddata/src/js_util.cpp b/kv_store/kvstoremock/frameworks/jskitsimpl/distributeddata/src/js_util.cpp index 77c52f40..a30db825 100644 --- a/kv_store/kvstoremock/frameworks/jskitsimpl/distributeddata/src/js_util.cpp +++ b/kv_store/kvstoremock/frameworks/jskitsimpl/distributeddata/src/js_util.cpp @@ -146,7 +146,7 @@ napi_status JSUtil::SetValue(napi_env env, const std::string& in, napi_value& ou } /* napi_value <-> std::vector */ -napi_status JSUtil::GetValue(napi_env env, napi_value in, std::vector& out) +napi_status JSUtil::GetValue(napi_env env, napi_value in, std::vector& out, bool checkLength) { ZLOGD("napi_value -> std::vector"); out.clear(); @@ -156,7 +156,10 @@ napi_status JSUtil::GetValue(napi_env env, napi_value in, std::vector 0), "get_array failed!", napi_invalid_arg); + CHECK_RETURN(status == napi_ok, "get_array length failed!", napi_invalid_arg); + if (checkLength) { + CHECK_RETURN(length > 0, "check array length failed!", napi_invalid_arg); + } for (uint32_t i = 0; i < length; ++i) { napi_value item = nullptr; status = napi_get_element(env, in, i, &item); diff --git a/kv_store/test/fuzztest/distributedkvdatamanager_fuzzer/distributedkvdatamanager_fuzzer.cpp b/kv_store/test/fuzztest/distributedkvdatamanager_fuzzer/distributedkvdatamanager_fuzzer.cpp index 7159ce94..6bfec15d 100644 --- a/kv_store/test/fuzztest/distributedkvdatamanager_fuzzer/distributedkvdatamanager_fuzzer.cpp +++ b/kv_store/test/fuzztest/distributedkvdatamanager_fuzzer/distributedkvdatamanager_fuzzer.cpp @@ -19,6 +19,7 @@ #include "distributed_kv_data_manager.h" #include "kvstore_death_recipient.h" +#include "kvstore_observer.h" #include "types.h" using namespace OHOS; @@ -51,6 +52,20 @@ public: } }; +class SwitchDataObserver : public KvStoreObserver { +public: + SwitchDataObserver() {} + ~SwitchDataObserver() {} + SwitchDataObserver(const SwitchDataObserver &) = delete; + SwitchDataObserver &operator=(const SwitchDataObserver &) = delete; + SwitchDataObserver(SwitchDataObserver &&) = delete; + SwitchDataObserver &operator=(SwitchDataObserver &&) = delete; + + void OnSwitchChange(const SwitchNotification ¬ification) override + { + } +}; + void SetUpTestCase(void) { userId.userId = "account"; @@ -198,6 +213,40 @@ void UnRegisterKvStoreServiceDeathRecipientFuzz() manager.UnRegisterKvStoreServiceDeathRecipient(kvStoreDeathRecipient); kvStoreDeathRecipient->OnRemoteDied(); } + +void PutSwitchFuzz(const uint8_t *data, size_t size) +{ + std::string appIds(data, data + size); + uint32_t input = static_cast(size); + SwitchData switchData; + switchData.value = input; + switchData.length = input & 0xFFFF; + manager.PutSwitch({ appIds }, switchData); + manager.PutSwitch({ "distributed_device_profile_service" }, switchData); +} + +void GetSwitchFuzz(const uint8_t *data, size_t size) +{ + std::string appIds(data, data + size); + std::string networkId(data, data + size); + manager.GetSwitch({ appIds }, networkId); + manager.GetSwitch({ "distributed_device_profile_service" }, networkId); +} + +void SubscribeSwitchDataFuzz(const uint8_t *data, size_t size) +{ + std::string appIds(data, data + size); + std::shared_ptr observer = std::make_shared(); + manager.SubscribeSwitchData({ appIds }, observer); +} + +void UnsubscribeSwitchDataFuzz(const uint8_t *data, size_t size) +{ + std::string appIds(data, data + size); + std::shared_ptr observer = std::make_shared(); + manager.SubscribeSwitchData({ appIds }, observer); + manager.UnsubscribeSwitchData({ appIds }, observer); +} } // namespace OHOS /* Fuzzer entry point */ @@ -214,6 +263,10 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) OHOS::DeleteAllKvStoreFuzz3(data, size); OHOS::RegisterKvStoreServiceDeathRecipientFuzz(); OHOS::UnRegisterKvStoreServiceDeathRecipientFuzz(); + OHOS::PutSwitchFuzz(data, size); + OHOS::GetSwitchFuzz(data, size); + OHOS::SubscribeSwitchDataFuzz(data, size); + OHOS::UnsubscribeSwitchDataFuzz(data, size); OHOS::TearDown(); return 0; } \ No newline at end of file diff --git a/kv_store/test/fuzztest/singlekvstore_fuzzer/singlekvstore_fuzzer.cpp b/kv_store/test/fuzztest/singlekvstore_fuzzer/singlekvstore_fuzzer.cpp index 969d6c46..57a0737e 100644 --- a/kv_store/test/fuzztest/singlekvstore_fuzzer/singlekvstore_fuzzer.cpp +++ b/kv_store/test/fuzztest/singlekvstore_fuzzer/singlekvstore_fuzzer.cpp @@ -480,6 +480,37 @@ void UnSubscribeWithQueryFuzz(const uint8_t *data, size_t size) dataQuery.KeyPrefix("name"); singleKvStore_->UnsubscribeWithQuery(deviceIds, dataQuery); } + +void AsyncGetFuzz(const uint8_t *data, size_t size) +{ + std::string strKey(data, data + size); + std::string strValue(data, data + size); + Key key = { strKey }; + Value val = { strValue }; + singleKvStore_->Put(key, val); + Value out; + std::function call = [](Status status, Value &&value) {}; + std::string networkId(data, data + size); + singleKvStore_->Get(key, networkId, call); + singleKvStore_->Delete(key); +} + +void AsyncGetEntriesFuzz(const uint8_t *data, size_t size) +{ + std::string prefix(data, data + size); + std::string keys = "test_"; + size_t sum = 10; + std::vector results; + for (size_t i = 0; i < sum; i++) { + singleKvStore_->Put(prefix + keys + std::to_string(i), { keys + std::to_string(i) }); + } + std::function &&)> call = [](Status status, std::vector &&entry) {}; + std::string networkId(data, data + size); + singleKvStore_->GetEntries(prefix, networkId, call); + for (size_t i = 0; i < sum; i++) { + singleKvStore_->Delete(prefix + keys + std::to_string(i)); + } +} } // namespace OHOS /* Fuzzer entry point */ @@ -508,6 +539,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) OHOS::SetCapabilityRangeFuzz(data, size); OHOS::SubscribeWithQueryFuzz(data, size); OHOS::UnSubscribeWithQueryFuzz(data, size); + OHOS::AsyncGetFuzz(data, size); + OHOS::AsyncGetEntriesFuzz(data, size); OHOS::TearDown(); return 0; } \ No newline at end of file diff --git a/kv_store/test/unittest/distributeddata/SchemaJsTest.js b/kv_store/test/unittest/distributeddata/SchemaJsTest.js index 45274899..6eec74b9 100644 --- a/kv_store/test/unittest/distributeddata/SchemaJsTest.js +++ b/kv_store/test/unittest/distributeddata/SchemaJsTest.js @@ -270,15 +270,37 @@ describe('schemaTest', function() { */ it('SchemaToJsonStringTest004', 0, async function(done) { try { - let english = new ddm.FieldNode('english'); - english.type = ddm.ValueType.STRING; + let name = new ddm.FieldNode('name'); + name.type = ddm.ValueType.FLOAT; + name.nullable = true; + name.default = '3.14'; let schema = new ddm.Schema(); - schema.root.appendChild(english); + schema.root.appendChild(name); schema.indexes = []; - expect(null).assertFail(); + schema.mode = 1; // COMPATIBLE + options.kvStoreType = ddm.KVStoreType.SINGLE_VERSION; + options.schema = schema; + await kvManager.getKVStore(TEST_STORE_ID, options).then(async (store) => { + console.info('SchemaToJsonStringTest005 getKVStore success' + JSON.stringify(options)); + kvStore = store; + expect(store != null).assertTrue(); + await kvStore.put("test_key_1", '{"name":1.5}'); + await kvStore.put("test_key_2", '{"name":2.5}'); + await kvStore.put("test_key_3", '{}'); + console.info('SchemaToJsonStringTest005 Put success'); + }); + console.info('SchemaToJsonStringTest005 start Query ...'); + await kvStore.getEntries('test_key_').then((entries) => { + console.info('SchemaToJsonStringTest005 get success : ' + JSON.stringify(entries)); + expect(entries.length == 3).assertTrue(); + }).catch((err) => { + console.info('SchemaToJsonStringTest005 get fail ' + err); + expect(null).assertFail(); + }); } catch (e) { - console.info("schema exception is: " + e); + console.info("SchemaToJsonStringTest005 fail on exception: " + e); + expect(null).assertFail(); } done(); }) diff --git a/mock/CMakeLists.txt b/mock/CMakeLists.txt index 5618dea4..c2cd9841 100644 --- a/mock/CMakeLists.txt +++ b/mock/CMakeLists.txt @@ -261,4 +261,5 @@ target_include_directories(mock PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/kits/ability/ target_include_directories(mock PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/kits/ability/native/distributed_ability_runtime) target_include_directories(mock PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/kits/ability/native/form_runtime) target_include_directories(mock PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/kits/ability/native) +target_include_directories(mock PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/kits/distributedfile/include) target_include_directories(mock PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/sqlite/include) \ No newline at end of file diff --git a/mock/include/CMakeLists.txt b/mock/include/CMakeLists.txt index ec05b925..d970c71e 100644 --- a/mock/include/CMakeLists.txt +++ b/mock/include/CMakeLists.txt @@ -199,6 +199,13 @@ include_directories(${MOCK_DIR}/innerkits/drivers_peripheral_vibrator/hdi_vibrat include_directories(${MOCK_DIR}/innerkits/drivers_peripheral_sensor/hdi_sensor/include) include_directories(${MOCK_DIR}/innerkits/napi) include_directories(${MOCK_DIR}/innerkits/napi/native_engine) +include_directories(${MOCK_DIR}/innerkits/filemanagement/file_api/interfaces/kits) +include_directories(${MOCK_DIR}/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/remote_file_share/include) +include_directories(${MOCK_DIR}/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/file_uri/include) +include_directories(${MOCK_DIR}/innerkits/filemanagement/app_file_service/interfaces/common/include) +include_directories(${MOCK_DIR}/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include) +include_directories(${MOCK_DIR}/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include) +include_directories(${MOCK_DIR}/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc) include_directories(${MOCK_DIR}/kits) include_directories(${MOCK_DIR}/kits/distributedfile/include) include_directories(${MOCK_DIR}/kits/ability/ability_runtime) @@ -218,8 +225,4 @@ include_directories(${MOCK_DIR}/kits/ability/native/continuation/remote_register include_directories(${MOCK_DIR}/kits/ability/native/distributed_ability_runtime) include_directories(${MOCK_DIR}/kits/ability/native/form_runtime) include_directories(${MOCK_DIR}/kits/ability/native) -include_directories(${MOCK_DIR}/sqlite/include) -include_directories(${MOCK_DIR}/innerkits/filemanagement/file_api/interfaces/kits) -include_directories(${MOCK_DIR}/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/remote_file_share/include) -include_directories(${MOCK_DIR}/innerkits/filemanagement/app_file_service/interfaces/innerkits/native/file_uri/include) -include_directories(${MOCK_DIR}/innerkits/filemanagement/app_file_service/interfaces/common/include) \ No newline at end of file +include_directories(${MOCK_DIR}/sqlite/include) \ No newline at end of file diff --git a/mock/innerkits/ability_runtime/uri_permission/include/uri_permission_manager_client.h b/mock/innerkits/ability_runtime/uri_permission/include/uri_permission_manager_client.h index 5eb88097..6ece7a89 100644 --- a/mock/innerkits/ability_runtime/uri_permission/include/uri_permission_manager_client.h +++ b/mock/innerkits/ability_runtime/uri_permission/include/uri_permission_manager_client.h @@ -94,7 +94,7 @@ public: * @param uri The file uri. * @param BundleName A BundleName of an application. */ - int RevokeUriPermissionManually(const Uri& uri, const std::string bundleName); + int RevokeUriPermissionManually(const Uri& uri, const std::string bundleName, int32_t instance = 0); /** * @brief verify if tokenId have uri permission of flag, including temporary permission and persistable permission diff --git a/mock/innerkits/common_event_service/cesfwk_innerkits/include/common_event_support.h b/mock/innerkits/common_event_service/cesfwk_innerkits/include/common_event_support.h index 0c9d5f34..49212fa6 100644 --- a/mock/innerkits/common_event_service/cesfwk_innerkits/include/common_event_support.h +++ b/mock/innerkits/common_event_service/cesfwk_innerkits/include/common_event_support.h @@ -1,17 +1,17 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +* Copyright (c) 2021-2023 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ #ifndef FOUNDATION_EVENT_CESFWK_KITS_NATIVE_INCLUDE_COMMON_EVENT_SUPPORT_H #define FOUNDATION_EVENT_CESFWK_KITS_NATIVE_INCLUDE_COMMON_EVENT_SUPPORT_H @@ -24,1080 +24,1298 @@ namespace EventFwk { class CommonEventSupport { public: /** - * Indicates the action of a common event that the user has finished booting and the system has been loaded. - * To subscribe to this common event, your application must have the ohos.permission.RECEIVER_STARTUP_COMPLETED - * permission. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that the user has finished booting and the system has been loaded. + * To subscribe to this common event, your application must have the ohos.permission.RECEIVER_STARTUP_COMPLETED + * permission. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_BOOT_COMPLETED; /** - * Indicates the action of a common event that the user has finished booting and the system has been loaded but the - * screen is still locked. - * To subscribe to this common event, your application must have the ohos.permission.RECEIVER_STARTUP_COMPLETED - * permission. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that the user has finished booting and the system has been loaded but the + * screen is still locked. + * To subscribe to this common event, your application must have the ohos.permission.RECEIVER_STARTUP_COMPLETED + * permission. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_LOCKED_BOOT_COMPLETED; /** - * Indicates the action of a common event that the device is being shut down and the final shutdown will proceed. - * This is different from sleeping. All unsaved data will be lost after shut down. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that the device is being shut down and the final shutdown will proceed. + * This is different from sleeping. All unsaved data will be lost after shut down. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_SHUTDOWN; /** - * Indicates the action of a common event that the charging state, level, and other information about the battery - * have changed. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that the charging state, level, and other information about the battery + * have changed. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_BATTERY_CHANGED; /** - * Indicates the action of a common event that the battery level is low. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that the battery level is low. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_BATTERY_LOW; /** - * Indicates the action of a common event that the battery exit the low state. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that the battery exit the low state. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_BATTERY_OKAY; /** - * Indicates the action of a common event that the device is connected to the external power. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that the device is connected to the external power. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_POWER_CONNECTED; /** - * Indicates the action of a common event that the device is disconnected from the external power. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that the device is disconnected from the external power. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_POWER_DISCONNECTED; /** - * Indicates the action of a common event that the device screen is off and the device is sleeping. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that the device screen is off and the device is sleeping. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_SCREEN_OFF; /** - * Indicates the action of a common event that the device screen is on and the device is interactive. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that the device screen is on and the device is interactive. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_SCREEN_ON; /** - * Indicates the action of a common event that the thermal level changed. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that the thermal level changed. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_THERMAL_LEVEL_CHANGED; /** - * Indicates the action of a common event that the device is idle and charging, - * services can do some business on the background. - * This common event can only be published by the system. - */ - static const std::string COMMON_EVENT_CHARGE_IDLE; + * Indicates the action of a common event that the device is idle and charging, + * services can do some business on the background. + * This common event can only be published by the system. + */ + static const std::string COMMON_EVENT_CHARGE_IDLE_MODE_CHANGED; /** - * Indicates the action of a common event that the user unlocks the device. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that the user unlocks the device. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_USER_PRESENT; /** - * Indicates the action of a common event that the system time has changed. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that the system time has changed. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_TIME_TICK; /** - * Indicates the action of a common event that the system time is set. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that the system time is set. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_TIME_CHANGED; /** - * Indicates the action of a common event that the system date has changed. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that the system date has changed. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_DATE_CHANGED; /** - * Indicates the action of a common event that the system time zone has changed. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that the system time zone has changed. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_TIMEZONE_CHANGED; /** - * Indicates the action of a common event that a user closes a temporary system dialog box. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that a user closes a temporary system dialog box. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_CLOSE_SYSTEM_DIALOGS; /** - * Indicates the action of a common event that bundle scan has finished. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that bundle scan has finished. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_BUNDLE_SCAN_FINISHED; /** - * Indicates the action of a common event that a new application package has been installed on the device. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that a new application package has been installed on the device. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_PACKAGE_ADDED; /** - * Indicates the action of a common event that a new version of an installed application package has replaced - * the previous one on the device. - * This common event can only be published by the system. - */ + * This commonEvent means when a new application package start to install on the device. + * This is a protected common event that can only be sent by system. + */ + static const std::string COMMON_EVENT_PACKAGE_INSTALLATION_STARTED; + /** + * This common event means an application package enables or disables a dynamic icon. + * This is a protected common event that can only be sent by system. + */ + static const std::string COMMON_EVENT_DYNAMIC_ICON_CHANGED; + /** + * Indicates the action of a common event that a new version of an installed application package has replaced + * the previous one on the device. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_PACKAGE_REPLACED; /** - * Indicates the action of a common event that a new version of your application package has replaced - * the previous one. This common event is sent only to the application that was replaced. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that a new version of your application package has replaced + * the previous one. This common event is sent only to the application that was replaced. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_MY_PACKAGE_REPLACED; /** - * Indicates the action of a common event that an installed application has been uninstalled from the device - * with the application data remained. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that an installed application has been uninstalled from the device + * with the application data remained. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_PACKAGE_REMOVED; /** - * Indicates the action of a common event that an installed bundle has been uninstalled from the device with the - * application data remained. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that an installed bundle has been uninstalled from the device with the + * application data remained. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_BUNDLE_REMOVED; /** - * Indicates the action of a common event that an installed application, including both the application data and - * code, have been completely uninstalled from the device. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that an installed application, including both the application data and + * code, have been completely uninstalled from the device. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_PACKAGE_FULLY_REMOVED; /** - * Indicates the action of a common event that an application package has been changed - * (for example, a component in the package has been enabled or disabled). - * This common event can only be published by the system. - */ + * Indicates the action of a common event that an application package has been changed + * (for example, a component in the package has been enabled or disabled). + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_PACKAGE_CHANGED; /** - * Indicates the action of a common event that the user has restarted the application package and killed all its - * processes. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that the user has restarted the application package and killed all its + * processes. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_PACKAGE_RESTARTED; /** - * Indicates the action of a common event that the user has cleared the application package data. - * This common event is published after COMMON_EVENT_PACKAGE_RESTARTED is triggered and the data has been cleared. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that the user has cleared the application package data. + * This common event is published after COMMON_EVENT_PACKAGE_RESTARTED is triggered and the data has been cleared. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_PACKAGE_DATA_CLEARED; /** - * Indicates the action of a common event that application packages have been suspended. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that the user has cleared the application package cache. + * This common event can only be published by the system. + */ + static const std::string COMMON_EVENT_PACKAGE_CACHE_CLEARED; + /** + * Indicates the action of a common event that application packages have been suspended. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_PACKAGES_SUSPENDED; /** - * Indicates the action of a common event that application packages have not been suspended. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that application packages have not been suspended. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_PACKAGES_UNSUSPENDED; /** - * Indicates the action of a common event that an application package has been suspended. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that an application package has been suspended. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_MY_PACKAGE_SUSPENDED; /** - * Indicates the action of a common event that an application package has not been suspended. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that an application package has not been suspended. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_MY_PACKAGE_UNSUSPENDED; /** - * Indicates the action of a common event that a user ID has been removed from the system. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that a user ID has been removed from the system. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_UID_REMOVED; /** - * Indicates the action of a common event that an installed application is started for the first time. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that an installed application is started for the first time. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_PACKAGE_FIRST_LAUNCH; /** - * Indicates the action of a common event that an application requires system verification. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that an application requires system verification. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_PACKAGE_NEEDS_VERIFICATION; /** - * Indicates the action of a common event that an application has been verified by the system. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that an application has been verified by the system. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_PACKAGE_VERIFIED; /** - * Indicates the action of a common event that applications installed on the external storage become - * available for the system. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that applications installed on the external storage become + * available for the system. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_EXTERNAL_APPLICATIONS_AVAILABLE; /** - * Indicates the action of a common event that applications installed on the external storage become unavailable for - * the system. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that applications installed on the external storage become unavailable for + * the system. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_EXTERNAL_APPLICATIONS_UNAVAILABLE; /** - * Indicates the action of a common event that the device state (for example, orientation and locale) has changed. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that the device state (for example, orientation and locale) has changed. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_CONFIGURATION_CHANGED; /** - * Indicates the action of a common event that the device locale has changed. - * This common event can only be published by the system. - */ + * Indicates the action of a common event that the device locale has changed. + * This common event can only be published by the system. + */ static const std::string COMMON_EVENT_LOCALE_CHANGED; /** - * Indicates the action of a common event that the device storage is insufficient. - */ + * Indicates the action of a common event that the device storage is insufficient. + */ static const std::string COMMON_EVENT_MANAGE_PACKAGE_STORAGE; /** - * Indicates the action of a common event that one sandbox package is installed. - */ + * Indicates the action of a common event that one sandbox package is installed. + */ static const std::string COMMON_EVENT_SANDBOX_PACKAGE_ADDED; /** - * Indicates the action of a common event that one sandbox package is uninstalled. - */ + * Indicates the action of a common event that one sandbox package is uninstalled. + */ static const std::string COMMON_EVENT_SANDBOX_PACKAGE_REMOVED; /** - * Indicates the action of a common event that the system is in driving mode. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event that the system is in driving mode. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_DRIVE_MODE; /** - * Indicates the action of a common event that the system is in home mode. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event that the system is in home mode. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_HOME_MODE; /** - * Indicates the action of a common event that the system is in office mode. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event that the system is in office mode. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_OFFICE_MODE; /** - * Indicates the action of a common event that the window mode is split screen. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event that the window mode is split screen. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_SPLIT_SCREEN; /** - * Indicates the action of a common event that the user has been started. - */ + * Indicates the action of a common event that the user has been started. + */ static const std::string COMMON_EVENT_USER_STARTED; /** - * Indicates the action of a common event that the user has been brought to the background. - */ + * Indicates the action of a common event that the user has been brought to the background. + */ static const std::string COMMON_EVENT_USER_BACKGROUND; /** - * Indicates the action of a common event that the user has been brought to the foreground. - */ + * Indicates the action of a common event that the user has been brought to the foreground. + */ static const std::string COMMON_EVENT_USER_FOREGROUND; /** - * Indicates the action of a common event that a user switch is happening. - * To subscribe to this common event, your application must have the ohos.permission.MANAGE_USERS permission. - */ + * Indicates the action of a common event that a user switch is happening. + * To subscribe to this common event, your application must have the ohos.permission.MANAGE_LOCAL_ACCOUNTS + * permission. + */ static const std::string COMMON_EVENT_USER_SWITCHED; /** - * Indicates the action of a common event that the user is going to be started. - * To subscribe to this common event, your application must have the ohos.permission.INTERACT_ACROSS_USERS - * permission. - */ + * Indicates the action of a common event that the user is going to be started. + * To subscribe to this common event, your application must have the ohos.permission.INTERACT_ACROSS_LOCAL_ACCOUNTS + * permission. + */ static const std::string COMMON_EVENT_USER_STARTING; /** - * Indicates the action of a common event that the credential-encrypted storage has become unlocked - * for the current user when the device is unlocked after being restarted. - */ + * Indicates the action of a common event that the credential-encrypted storage has become unlocked + * for the current user when the device is unlocked after being restarted. + */ static const std::string COMMON_EVENT_USER_UNLOCKED; /** - * Indicates the action of a common event that the user is going to be stopped. - * To subscribe to this common event, your application must have the ohos.permission.INTERACT_ACROSS_USERS - * permission. - */ + * Indicates the action of a common event that the user is going to be stopped. + * To subscribe to this common event, your application must have the ohos.permission.INTERACT_ACROSS_LOCAL_ACCOUNTS + * permission. + */ static const std::string COMMON_EVENT_USER_STOPPING; /** - * Indicates the action of a common event that the user has been stopped. - */ + * Indicates the action of a common event that the user has been stopped. + */ static const std::string COMMON_EVENT_USER_STOPPED; /** - * Indicates the action of a common event about a login of a user with account ID. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event about a login of a user with account ID. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_HWID_LOGIN; /** - * Indicates the action of a common event about a logout of a user with account ID. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event about a logout of a user with account ID. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_HWID_LOGOUT; /** - * Indicates the action of a common event that the account ID is invalid. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event that the account ID is invalid. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_HWID_TOKEN_INVALID; /** - * Indicates the action of a common event about a logoff of a account ID. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event about a logoff of a account ID. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_HWID_LOGOFF; /** - * Indicates the action of a common event about the Wi-Fi state, such as enabled and disabled. - */ + * Indicates the action of a common event about the Wi-Fi state, such as enabled and disabled. + */ static const std::string COMMON_EVENT_WIFI_POWER_STATE; /** - * Indicates the action of a common event that the Wi-Fi access point has been scanned and proven to be available. - * To subscribe to this common event, your application must have the ohos.permission.LOCATION permission. - */ + * Indicates the action of a common event that the Wi-Fi access point has been scanned and proven to be available. + * To subscribe to this common event, your application must have the ohos.permission.LOCATION permission. + */ static const std::string COMMON_EVENT_WIFI_SCAN_FINISHED; /** - * Indicates the action of a common event that the Wi-Fi signal strength (RSSI) has changed. - * To subscribe to this common event, your application must have the ohos.permission.GET_WIFI_INFO permission. - */ + * Indicates the action of a common event that the Wi-Fi signal strength (RSSI) has changed. + * To subscribe to this common event, your application must have the ohos.permission.GET_WIFI_INFO permission. + */ static const std::string COMMON_EVENT_WIFI_RSSI_VALUE; /** - * Indicates the action of a common event that the Wi-Fi connection state has changed. - */ + * Indicates the action of a common event that the Wi-Fi connection state has changed. + */ static const std::string COMMON_EVENT_WIFI_CONN_STATE; /** - * Indicates the action of a common event about the Wi-Fi hotspot state, such as enabled or disabled. - */ + * Indicates the action of a common event about the Wi-Fi hotspot state, such as enabled or disabled. + */ static const std::string COMMON_EVENT_WIFI_HOTSPOT_STATE; /** - * Indicates the action of a common event that a client has joined the Wi-Fi hotspot of the current device. You can - * register this common event to listen for information about the clients joining your hotspot. - * To subscribe to this common event, your application must have the ohos.permission.GET_WIFI_INFO permission. - */ + * Indicates the action of a common event that a client has joined the Wi-Fi hotspot of the current device. You can + * register this common event to listen for information about the clients joining your hotspot. + * To subscribe to this common event, your application must have the ohos.permission.GET_WIFI_INFO permission. + */ static const std::string COMMON_EVENT_WIFI_AP_STA_JOIN; /** - * Indicates the action of a common event that a client has dropped connection to the Wi-Fi hotspot of the current - * device. You can register this common event to listen for information about the clients leaving your hotspot. - * To subscribe to this common event, your application must have the ohos.permission.GET_WIFI_INFO permission. - */ + * Indicates the action of a common event that a client has dropped connection to the Wi-Fi hotspot of the current + * device. You can register this common event to listen for information about the clients leaving your hotspot. + * To subscribe to this common event, your application must have the ohos.permission.GET_WIFI_INFO permission. + */ static const std::string COMMON_EVENT_WIFI_AP_STA_LEAVE; /** - * Indicates the action of a common event that the state of MPLink (an enhanced Wi-Fi feature) has changed. - * To subscribe to this common event, your application must have the ohos.permission.MPLINK_CHANGE_STATE permission. - */ + * Indicates the action of a common event that the state of MPLink (an enhanced Wi-Fi feature) has changed. + * To subscribe to this common event, your application must have the ohos.permission.MPLINK_CHANGE_STATE permission. + */ static const std::string COMMON_EVENT_WIFI_MPLINK_STATE_CHANGE; /** - * Indicates the action of a common event that the Wi-Fi P2P connection state has changed. - * To subscribe to this common event, your application must have the ohos.permission.GET_WIFI_INFO and - * ohos.permission.LOCATION permissions. - */ + * Indicates the action of a common event that the Wi-Fi P2P connection state has changed. + * To subscribe to this common event, your application must have the ohos.permission.GET_WIFI_INFO and + * ohos.permission.LOCATION permissions. + */ static const std::string COMMON_EVENT_WIFI_P2P_CONN_STATE; /** - * Indicates the action of a common event about the Wi-Fi P2P state, such as enabled and disabled. - * To subscribe to this common event, your application must have the ohos.permission.GET_WIFI_INFO permission. - */ + * Indicates the action of a common event about the Wi-Fi P2P state, such as enabled and disabled. + * To subscribe to this common event, your application must have the ohos.permission.GET_WIFI_INFO permission. + */ static const std::string COMMON_EVENT_WIFI_P2P_STATE_CHANGED; /** - * Indicates that the Wi-Fi P2P peers state change. - * To subscribe to this common event, your application must have the ohos.permission.GET_WIFI_INFO permission. - */ + * Indicates that the Wi-Fi P2P peers state change. + * To subscribe to this common event, your application must have the ohos.permission.GET_WIFI_INFO permission. + */ static const std::string COMMON_EVENT_WIFI_P2P_PEERS_STATE_CHANGED; /** - * Indicates that the Wi-Fi P2P discovery state change. - * To subscribe to this common event, your application must have the ohos.permission.GET_WIFI_INFO permission. - */ + * Indicates that the Wi-Fi P2P discovery state change. + * To subscribe to this common event, your application must have the ohos.permission.GET_WIFI_INFO permission. + */ static const std::string COMMON_EVENT_WIFI_P2P_PEERS_DISCOVERY_STATE_CHANGED; /** - * Indicates that the Wi-Fi P2P current device state change. - * To subscribe to this common event, your application must have the ohos.permission.GET_WIFI_INFO permission. - */ + * Indicates that the Wi-Fi P2P current device state change. + * To subscribe to this common event, your application must have the ohos.permission.GET_WIFI_INFO permission. + */ static const std::string COMMON_EVENT_WIFI_P2P_CURRENT_DEVICE_STATE_CHANGED; /** - * Indicates that the Wi-Fi P2P group info is changed. - * To subscribe to this common event, your application must have the ohos.permission.GET_WIFI_INFO permission. - */ + * Indicates that the Wi-Fi P2P group info is changed. + * To subscribe to this common event, your application must have the ohos.permission.GET_WIFI_INFO permission. + */ static const std::string COMMON_EVENT_WIFI_P2P_GROUP_STATE_CHANGED; /** - * Indicates that network traffic statistics have been updated. - */ + * Indicates that network traffic statistics have been updated. + */ static const std::string COMMON_EVENT_NETMANAGER_NETSTATES_UPDATED; /** - * Indicates that the network traffic has exceeded the limit. - */ + * Indicates that the network traffic has exceeded the limit. + */ static const std::string COMMON_EVENT_NETMANAGER_NETSTATES_LIMITED; /** - * Indicates the action of a common event about the connection state of Bluetooth handsfree communication. - * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. - */ + * Indicates the action of a common event about the connection state of Bluetooth handsfree communication. + * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. + */ static const std::string COMMON_EVENT_BLUETOOTH_HANDSFREE_AG_CONNECT_STATE_UPDATE; /** - * Indicates the action of a common event that the device connected to the Bluetooth handsfree is active. - * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. - */ + * Indicates the action of a common event that the device connected to the Bluetooth handsfree is active. + * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. + */ static const std::string COMMON_EVENT_BLUETOOTH_HANDSFREE_AG_CURRENT_DEVICE_UPDATE; /** - * Indicates the action of a common event that the connection state of Bluetooth A2DP has changed. - * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. - */ + * Indicates the action of a common event that the connection state of Bluetooth A2DP has changed. + * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. + */ static const std::string COMMON_EVENT_BLUETOOTH_HANDSFREE_AG_AUDIO_STATE_UPDATE; /** - * Indicates the action of a common event about the connection state of Bluetooth A2DP. - * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. - */ + * Indicates the action of a common event about the connection state of Bluetooth A2DP. + * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. + */ static const std::string COMMON_EVENT_BLUETOOTH_A2DPSOURCE_CONNECT_STATE_UPDATE; /** - * Indicates the action of a common event that the device connected using Bluetooth A2DP is active. - * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. - */ + * Indicates the action of a common event that the device connected using Bluetooth A2DP is active. + * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. + */ static const std::string COMMON_EVENT_BLUETOOTH_A2DPSOURCE_CURRENT_DEVICE_UPDATE; /** - * Indicates the action of a common event that the playing state of Bluetooth A2DP has changed. - * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. - */ + * Indicates the action of a common event that the playing state of Bluetooth A2DP has changed. + * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. + */ static const std::string COMMON_EVENT_BLUETOOTH_A2DPSOURCE_PLAYING_STATE_UPDATE; /** - * Indicates the action of a common event that the AVRCP connection state of Bluetooth A2DP has changed. - */ + * Indicates the action of a common event that the AVRCP connection state of Bluetooth A2DP has changed. + */ static const std::string COMMON_EVENT_BLUETOOTH_A2DPSOURCE_AVRCP_CONNECT_STATE_UPDATE; /** - * Indicates the action of a common event that the audio codec state of Bluetooth A2DP has changed. - * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. - */ + * Indicates the action of a common event that the audio codec state of Bluetooth A2DP has changed. + * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. + */ static const std::string COMMON_EVENT_BLUETOOTH_A2DPSOURCE_CODEC_VALUE_UPDATE; /** - * Indicates the action of a common event that a remote Bluetooth device has been discovered. - * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH and - * ohos.permission.LOCATION permissions. - */ + * Indicates the action of a common event that a remote Bluetooth device has been discovered. + * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH and + * ohos.permission.LOCATION permissions. + */ static const std::string COMMON_EVENT_BLUETOOTH_REMOTEDEVICE_DISCOVERED; /** - * Indicates the action of a common event that the Bluetooth class of a remote Bluetooth device has changed. - * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. - */ + * Indicates the action of a common event that the Bluetooth class of a remote Bluetooth device has changed. + * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. + */ static const std::string COMMON_EVENT_BLUETOOTH_REMOTEDEVICE_CLASS_VALUE_UPDATE; /** - * Indicates the action of a common event that a low level (ACL) connection has been established with a remote - * Bluetooth device. - * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. - */ + * Indicates the action of a common event that a low level (ACL) connection has been established with a remote + * Bluetooth device. + * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. + */ static const std::string COMMON_EVENT_BLUETOOTH_REMOTEDEVICE_ACL_CONNECTED; /** - * Indicates the action of a common event that a low level (ACL) connection has been disconnected from a remote - * Bluetooth device. - * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. - */ + * Indicates the action of a common event that a low level (ACL) connection has been disconnected from a remote + * Bluetooth device. + * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. + */ static const std::string COMMON_EVENT_BLUETOOTH_REMOTEDEVICE_ACL_DISCONNECTED; /** - * Indicates the action of a common event that the friendly name of a remote Bluetooth device has been retrieved for - * the first time or has been changed since the last retrieval. - * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. - */ + * Indicates the action of a common event that the friendly name of a remote Bluetooth device has been retrieved for + * the first time or has been changed since the last retrieval. + * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. + */ static const std::string COMMON_EVENT_BLUETOOTH_REMOTEDEVICE_NAME_UPDATE; /** - * Indicates the action of a common event that the connection state of a remote Bluetooth device has changed. - * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. - */ + * Indicates the action of a common event that the connection state of a remote Bluetooth device has changed. + * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. + */ static const std::string COMMON_EVENT_BLUETOOTH_REMOTEDEVICE_PAIR_STATE; /** - * Indicates the action of a common event that the battery level of a remote Bluetooth device has been retrieved - * for the first time or has been changed since the last retrieval. - * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. - */ + * Indicates the action of a common event that the battery level of a remote Bluetooth device has been retrieved + * for the first time or has been changed since the last retrieval. + * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. + */ static const std::string COMMON_EVENT_BLUETOOTH_REMOTEDEVICE_BATTERY_VALUE_UPDATE; /** - * Indicates the action of a common event about the SDP state of a remote Bluetooth device. - */ + * Indicates the action of a common event about the SDP state of a remote Bluetooth device. + */ static const std::string COMMON_EVENT_BLUETOOTH_REMOTEDEVICE_SDP_RESULT; /** - * Indicates the action of a common event about the UUID connection state of a remote Bluetooth device. - * To subscribe to this common event, your application must have the ohos.permission.DISCOVER_BLUETOOTH permission. - */ + * Indicates the action of a common event about the UUID connection state of a remote Bluetooth device. + * To subscribe to this common event, your application must have the ohos.permission.DISCOVER_BLUETOOTH permission. + */ static const std::string COMMON_EVENT_BLUETOOTH_REMOTEDEVICE_UUID_VALUE; /** - * Indicates the action of a common event about the pairing request from a remote Bluetooth device. - * To subscribe to this common event, your application must have the ohos.permission.DISCOVER_BLUETOOTH permission. - */ + * Indicates the action of a common event about the pairing request from a remote Bluetooth device. + * To subscribe to this common event, your application must have the ohos.permission.DISCOVER_BLUETOOTH permission. + */ static const std::string COMMON_EVENT_BLUETOOTH_REMOTEDEVICE_PAIRING_REQ; /** - * Indicates the action of a common event that Bluetooth pairing is canceled. - */ + * Indicates the action of a common event that Bluetooth pairing is canceled. + */ static const std::string COMMON_EVENT_BLUETOOTH_REMOTEDEVICE_PAIRING_CANCEL; /** - * Indicates the action of a common event about the connection request from a remote Bluetooth device. - */ + * Indicates the action of a common event about the connection request from a remote Bluetooth device. + */ static const std::string COMMON_EVENT_BLUETOOTH_REMOTEDEVICE_CONNECT_REQ; /** - * Indicates the action of a common event about the response to the connection request from a remote Bluetooth - * device. - */ + * Indicates the action of a common event about the response to the connection request from a remote Bluetooth + * device. + */ static const std::string COMMON_EVENT_BLUETOOTH_REMOTEDEVICE_CONNECT_REPLY; /** - * Indicates the action of a common event that the connection to a remote Bluetooth device has been canceled. - */ + * Indicates the action of a common event that the connection to a remote Bluetooth device has been canceled. + */ static const std::string COMMON_EVENT_BLUETOOTH_REMOTEDEVICE_CONNECT_CANCEL; /** - * Indicates the action of a common event that the connection state of a Bluetooth handsfree has changed. - */ + * Indicates the action of a common event that the connection state of a Bluetooth handsfree has changed. + */ static const std::string COMMON_EVENT_BLUETOOTH_HANDSFREEUNIT_CONNECT_STATE_UPDATE; /** - * Indicates the action of a common event that the audio state of a Bluetooth handsfree has changed. - */ + * Indicates the action of a common event that the audio state of a Bluetooth handsfree has changed. + */ static const std::string COMMON_EVENT_BLUETOOTH_HANDSFREEUNIT_AUDIO_STATE_UPDATE; /** - * Indicates the action of a common event that the audio gateway state of a Bluetooth handsfree has changed. - */ + * Indicates the action of a common event that the audio gateway state of a Bluetooth handsfree has changed. + */ static const std::string COMMON_EVENT_BLUETOOTH_HANDSFREEUNIT_AG_COMMON_EVENT; /** - * Indicates the action of a common event that the calling state of a Bluetooth handsfree has changed. - */ + * Indicates the action of a common event that the calling state of a Bluetooth handsfree has changed. + */ static const std::string COMMON_EVENT_BLUETOOTH_HANDSFREEUNIT_AG_CALL_STATE_UPDATE; /** - * Indicates the action of a common event that the state of a Bluetooth adapter has been changed, for example, - * Bluetooth has been turned on or off. - * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. - */ + * Indicates the action of a common event that the state of a Bluetooth adapter has been changed, for example, + * Bluetooth has been turned on or off. + * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. + */ static const std::string COMMON_EVENT_BLUETOOTH_HOST_STATE_UPDATE; /** - * Indicates the action of a common event about the requests for the user to allow Bluetooth to be scanned. - */ + * Indicates the action of a common event about the requests for the user to allow Bluetooth to be scanned. + */ static const std::string COMMON_EVENT_BLUETOOTH_HOST_REQ_DISCOVERABLE; /** - * Indicates the action of a common event about the requests for the user to turn on Bluetooth. - * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. - */ + * Indicates the action of a common event about the requests for the user to turn on Bluetooth. + * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. + */ static const std::string COMMON_EVENT_BLUETOOTH_HOST_REQ_ENABLE; /** - * Indicates the action of a common event about the requests for the user to turn off Bluetooth. - * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. - */ + * Indicates the action of a common event about the requests for the user to turn off Bluetooth. + * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. + */ static const std::string COMMON_EVENT_BLUETOOTH_HOST_REQ_DISABLE; /** - * Indicates the action of a common event that the Bluetooth scanning mode of a device has changed. - * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. - */ + * Indicates the action of a common event that the Bluetooth scanning mode of a device has changed. + * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. + */ static const std::string COMMON_EVENT_BLUETOOTH_HOST_SCAN_MODE_UPDATE; /** - * Indicates the action of a common event that the Bluetooth scanning has been started on the device. - * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. - */ + * Indicates the action of a common event that the Bluetooth scanning has been started on the device. + * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. + */ static const std::string COMMON_EVENT_BLUETOOTH_HOST_DISCOVERY_STARTED; /** - * Indicates the action of a common event that the Bluetooth scanning is finished on the device. - * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. - */ + * Indicates the action of a common event that the Bluetooth scanning is finished on the device. + * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. + */ static const std::string COMMON_EVENT_BLUETOOTH_HOST_DISCOVERY_FINISHED; /** - * Indicates the action of a common event that the Bluetooth adapter name of the device has changed. - * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. - */ + * Indicates the action of a common event that the Bluetooth adapter name of the device has changed. + * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. + */ static const std::string COMMON_EVENT_BLUETOOTH_HOST_NAME_UPDATE; /** - * Indicates the action of a common event that the connection state of Bluetooth A2DP Sink has changed. - * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. - */ + * Indicates the action of a common event that the connection state of Bluetooth A2DP Sink has changed. + * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. + */ static const std::string COMMON_EVENT_BLUETOOTH_A2DPSINK_CONNECT_STATE_UPDATE; /** - * Indicates the action of a common event that the playing state of Bluetooth A2DP Sink has changed. - * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. - */ + * Indicates the action of a common event that the playing state of Bluetooth A2DP Sink has changed. + * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. + */ static const std::string COMMON_EVENT_BLUETOOTH_A2DPSINK_PLAYING_STATE_UPDATE; /** - * Indicates the action of a common event that the audio state of Bluetooth A2DP Sink has changed. - * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. - */ + * Indicates the action of a common event that the audio state of Bluetooth A2DP Sink has changed. + * To subscribe to this common event, your application must have the ohos.permission.USE_BLUETOOTH permission. + */ static const std::string COMMON_EVENT_BLUETOOTH_A2DPSINK_AUDIO_STATE_UPDATE; /** - * Indicates the action of a common event that the state of the device NFC adapter has changed. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the status of the Bluetooth device connect status has been changed. + */ + static const std::string COMMON_EVENT_BLUETOOTH_REMOTEDEVICE_CONNECT_STATUS_VALUE; + + /** + * Indicates the action of a common event that the state of the device NFC adapter has changed. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_NFC_ACTION_ADAPTER_STATE_CHANGED; /** - * Indicates the action of a common event that the NFC RF field is detected to be in the enabled state. - * To subscribe to this common event, your application must have the ohos.permission.MANAGE_SECURE_SETTINGS - * permission. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event that the NFC RF field is detected to be in the enabled state. + * To subscribe to this common event, your application must have the ohos.permission.MANAGE_SECURE_SETTINGS + * permission. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_NFC_ACTION_RF_FIELD_ON_DETECTED; /** - * Indicates the action of a common event that the NFC RF field is detected to be in the disabled state. - * To subscribe to this common event, your application must have the ohos.permission.MANAGE_SECURE_SETTINGS - * permission. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event that the NFC RF field is detected to be in the disabled state. + * To subscribe to this common event, your application must have the ohos.permission.MANAGE_SECURE_SETTINGS + * permission. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_NFC_ACTION_RF_FIELD_OFF_DETECTED; /** - * Indicates the action of a common event that the system stops charging the battery. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event that the system stops charging the battery. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_DISCHARGING; /** - * Indicates the action of a common event that the system starts charging the battery. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event that the system starts charging the battery. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_CHARGING; /** - * Indicates the action of a common event that the system idle mode has changed. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event that a charge type has been updated. + * This is a protected common event, which can be sent only by the system. + */ + static const std::string COMMON_EVENT_CHARGE_TYPE_CHANGED; + + /** + * Indicates the action of a common event that the system idle mode has changed. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_DEVICE_IDLE_MODE_CHANGED; /** - * Indicates the action of a common event that the power save mode of the system has changed. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event that the list of exempt applications is updated in the idle mode. + * This is a protected common event, which can be sent only by the system. + */ + static const std::string COMMON_EVENT_DEVICE_IDLE_EXEMPTION_LIST_UPDATED; + + /** + * Indicates the action of a common event that the power save mode of the system has changed. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_POWER_SAVE_MODE_CHANGED; /** - * Indicates the action of a common event that a user has been added to the system. - * To subscribe to this common event, your application must have the ohos.permission.MANAGE_USERS permission. - */ + * Indicates the action of a common event that a user has been added to the system. + * To subscribe to this common event, your application must have the ohos.permission.MANAGE_LOCAL_ACCOUNTS + * permission. + */ static const std::string COMMON_EVENT_USER_ADDED; /** - * Indicates the action of a common event that a user has been removed from the system. - * To subscribe to this common event, your application must have the ohos.permission.MANAGE_USERS permission. - */ + * Indicates the action of a common event that a user has been removed from the system. + * To subscribe to this common event, your application must have the ohos.permission.MANAGE_LOCAL_ACCOUNTS + * permission. + */ static const std::string COMMON_EVENT_USER_REMOVED; /** - * Indicates the action of a common event that an ability has been added. - * To subscribe to this common event, your application must have the ohos.permission.LISTEN_BUNDLE_CHANGE - * permission. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event that an ability has been added. + * To subscribe to this common event, your application must have the ohos.permission.LISTEN_BUNDLE_CHANGE + * permission. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_ABILITY_ADDED; /** - * Indicates the action of a common event that an ability has been removed. - * To subscribe to this common event, your application must have the ohos.permission.LISTEN_BUNDLE_CHANGE - * permission. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event that an ability has been removed. + * To subscribe to this common event, your application must have the ohos.permission.LISTEN_BUNDLE_CHANGE + * permission. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_ABILITY_REMOVED; /** - * Indicates the action of a common event that an ability has been updated. - * To subscribe to this common event, your application must have the ohos.permission.LISTEN_BUNDLE_CHANGE - * permission. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event that an ability has been updated. + * To subscribe to this common event, your application must have the ohos.permission.LISTEN_BUNDLE_CHANGE + * permission. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_ABILITY_UPDATED; /** - * Indicates the action of a common event that the location mode of the system has changed. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event that the location mode of the system has changed. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_LOCATION_MODE_STATE_CHANGED; /** - * Indicates the action of a common event that the in-vehicle infotainment (IVI) system of a vehicle is sleeping. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event that the in-vehicle infotainment (IVI) system of a vehicle is sleeping. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_IVI_SLEEP; /** - * The ivi is slept and notify the app stop playing. - * This is a protected common event that can only be sent by system. - */ + * The ivi is slept and notify the app stop playing. + * This is a protected common event that can only be sent by system. + */ static const std::string COMMON_EVENT_IVI_PAUSE; /** - * Indicates the action of a common event that a third-party application is instructed to pause the current work. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event that a third-party application is instructed to pause the current work. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_IVI_STANDBY; /** - * Indicates the action of a common event that a third-party application is instructed to save its last mode. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event that a third-party application is instructed to save its last mode. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_IVI_LASTMODE_SAVE; /** - * Indicates the action of a common event that the voltage of the vehicle power system is abnormal. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event that the voltage of the vehicle power system is abnormal. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_IVI_VOLTAGE_ABNORMAL; /** - * The ivi temperature is too high. - * This is a protected common event that can only be sent by system. - * This common event will be delete later, please use COMMON_EVENT_IVI_TEMPERATURE_ABNORMAL. - */ + * The ivi temperature is too high. + * This is a protected common event that can only be sent by system. + * This common event will be delete later, please use COMMON_EVENT_IVI_TEMPERATURE_ABNORMAL. + */ static const std::string COMMON_EVENT_IVI_HIGH_TEMPERATURE; /** - * The ivi temperature is extreme high. - * This is a protected common event that can only be sent by system. - * This common event will be delete later, please use COMMON_EVENT_IVI_TEMPERATURE_ABNORMAL. - */ + * The ivi temperature is extreme high. + * This is a protected common event that can only be sent by system. + * This common event will be delete later, please use COMMON_EVENT_IVI_TEMPERATURE_ABNORMAL. + */ static const std::string COMMON_EVENT_IVI_EXTREME_TEMPERATURE; /** - * Indicates the action of a common event that the in-vehicle system has an extreme temperature. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event that the in-vehicle system has an extreme temperature. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_IVI_TEMPERATURE_ABNORMAL; /** - * Indicates the action of a common event that the voltage of the vehicle power system is restored to normal. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event that the voltage of the vehicle power system is restored to normal. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_IVI_VOLTAGE_RECOVERY; /** - * Indicates the action of a common event that the temperature of the in-vehicle system is restored to normal. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event that the temperature of the in-vehicle system is restored to normal. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_IVI_TEMPERATURE_RECOVERY; /** - * Indicates the action of a common event that the battery service is active. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event that the battery service is active. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_IVI_ACTIVE; /** - * The usb state changed. - * This is a protected common event that can only be sent by system. - */ + * The usb state changed. + * This is a protected common event that can only be sent by system. + */ static const std::string COMMON_EVENT_USB_STATE; /** - * The usb port changed. - * This is a protected common event that can only be sent by system. - */ + * The usb port changed. + * This is a protected common event that can only be sent by system. + */ static const std::string COMMON_EVENT_USB_PORT_CHANGED; /** - * Indicates the action of a common event that a USB device has been attached when the user device functions as a - * USB host. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event that a USB device has been attached when the user device functions as a + * USB host. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_USB_DEVICE_ATTACHED; /** - * Indicates the action of a common event that a USB device has been detached when the user device functions as a - * USB host. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event that a USB device has been detached when the user device functions as a + * USB host. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_USB_DEVICE_DETACHED; /** - * Indicates the action of a common event that a USB accessory has been attached. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event that a USB accessory has been attached. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_USB_ACCESSORY_ATTACHED; /** - * Indicates the action of a common event that a USB accessory has been detached. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event that a USB accessory has been detached. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_USB_ACCESSORY_DETACHED; /** - * The storage space is low. - * This is a protected common event that can only be sent by system. - */ + * The storage space is low. + * This is a protected common event that can only be sent by system. + */ static const std::string COMMON_EVENT_DEVICE_STORAGE_LOW; /** - * The storage space is normal. - * This is a protected common event that can only be sent by system. - */ + * The storage space is normal. + * This is a protected common event that can only be sent by system. + */ static const std::string COMMON_EVENT_DEVICE_STORAGE_OK; /** - * The storage space is full. - * This is a protected common event that can only be sent by system. - */ + * The storage space is full. + * This is a protected common event that can only be sent by system. + */ static const std::string COMMON_EVENT_DEVICE_STORAGE_FULL; /** - * The network connection was changed. - * This is a protected common event that can only be sent by system. - */ + * The network connection was changed. + * This is a protected common event that can only be sent by system. + */ static const std::string COMMON_EVENT_CONNECTIVITY_CHANGE; /** - * Indicates the action of a common event that an external storage device was removed. - * To subscribe to this common event, your application must have the ohos.permission.WRITE_USER_STORAGE or - * ohos.permission.READ_USER_STORAGE permission. - * This common event can be published only by system applications. - */ + * The global http proxy was changed. + * This is a protected common event that can only be sent by system. + */ + static const std::string COMMON_EVENT_HTTP_PROXY_CHANGE; + + /** + * Indicates the action of a common event that an external storage device was removed. + * To subscribe to this common event, your application must have the ohos.permission.STORAGE_MANAGER permission. + * This common event can be published only by system applications. + */ static const std::string COMMON_EVENT_DISK_REMOVED; /** - * Indicates the action of a common event that an external storage device was unmounted. - * To subscribe to this common event, your application must have the ohos.permission.WRITE_USER_STORAGE or - * ohos.permission.READ_USER_STORAGE permission. - * This common event can be published only by system applications. - */ + * Indicates the action of a common event that an external storage device was unmounted. + * To subscribe to this common event, your application must have the ohos.permission.STORAGE_MANAGER permission. + * This common event can be published only by system applications. + */ static const std::string COMMON_EVENT_DISK_UNMOUNTED; /** - * Indicates the action of a common event that an external storage device was mounted. - * To subscribe to this common event, your application must have the ohos.permission.WRITE_USER_STORAGE or - * ohos.permission.READ_USER_STORAGE permission. - * This common event can be published only by system applications. - */ + * Indicates the action of a common event that an external storage device was mounted. + * To subscribe to this common event, your application must have the ohos.permission.STORAGE_MANAGER permission. + * This common event can be published only by system applications. + */ static const std::string COMMON_EVENT_DISK_MOUNTED; /** - * Indicates the action of a common event that an external storage device was removed without being unmounted. - * To subscribe to this common event, your application must have the ohos.permission.WRITE_USER_STORAGE or - * ohos.permission.READ_USER_STORAGE permission. - * This common event can be published only by system applications. - */ + * Indicates the action of a common event that an external storage device was removed without being unmounted. + * To subscribe to this common event, your application must have the ohos.permission.STORAGE_MANAGER permission. + * This common event can be published only by system applications. + */ static const std::string COMMON_EVENT_DISK_BAD_REMOVAL; /** - * Indicates the action of a common event that an external storage device becomes unmountable. - * To subscribe to this common event, your application must have the ohos.permission.WRITE_USER_STORAGE or - * ohos.permission.READ_USER_STORAGE permission. - * This common event can be published only by system applications. - */ + * Indicates the action of a common event that an external storage device becomes unmountable. + * To subscribe to this common event, your application must have the ohos.permission.STORAGE_MANAGER permission. + * This common event can be published only by system applications. + */ static const std::string COMMON_EVENT_DISK_UNMOUNTABLE; /** - * Indicates the action of a common event that an external storage device was ejected. - * To subscribe to this common event, your application must have the ohos.permission.WRITE_USER_STORAGE or - * ohos.permission.READ_USER_STORAGE permission. - * This common event can be published only by system applications. - */ + * Indicates the action of a common event that an external storage device was ejected. + * To subscribe to this common event, your application must have the ohos.permission.STORAGE_MANAGER permission. + * This common event can be published only by system applications. + */ static const std::string COMMON_EVENT_DISK_EJECT; /** - * Indicates the action of a common event that an external storage device was removed. - * To subscribe to this common event, your application must have the ohos.permission.WRITE_USER_STORAGE or - * ohos.permission.READ_USER_STORAGE permission. - * This common event can be published only by system applications. - */ + * Indicates the action of a common event that an external storage device was removed. + * To subscribe to this common event, your application must have the ohos.permission.STORAGE_MANAGER permission. + * This common event can be published only by system applications. + */ static const std::string COMMON_EVENT_VOLUME_REMOVED; /** - * Indicates the action of a common event that an external storage device was unmounted. - * To subscribe to this common event, your application must have the ohos.permission.WRITE_USER_STORAGE or - * ohos.permission.READ_USER_STORAGE permission. - * This common event can be published only by system applications. - */ + * Indicates the action of a common event that an external storage device was unmounted. + * To subscribe to this common event, your application must have the ohos.permission.STORAGE_MANAGER permission. + * This common event can be published only by system applications. + */ static const std::string COMMON_EVENT_VOLUME_UNMOUNTED; /** - * Indicates the action of a common event that an external storage device was mounted. - * To subscribe to this common event, your application must have the ohos.permission.WRITE_USER_STORAGE or - * ohos.permission.READ_USER_STORAGE permission. - * This common event can be published only by system applications. - */ + * Indicates the action of a common event that an external storage device was mounted. + * To subscribe to this common event, your application must have the ohos.permission.STORAGE_MANAGER permission. + * This common event can be published only by system applications. + */ static const std::string COMMON_EVENT_VOLUME_MOUNTED; /** - * Indicates the action of a common event that an external storage device was removed without being unmounted. - * To subscribe to this common event, your application must have the ohos.permission.WRITE_USER_STORAGE or - * ohos.permission.READ_USER_STORAGE permission. - * This common event can be published only by system applications. - */ + * Indicates the action of a common event that an external storage device was removed without being unmounted. + * To subscribe to this common event, your application must have the ohos.permission.STORAGE_MANAGER permission. + * This common event can be published only by system applications. + */ static const std::string COMMON_EVENT_VOLUME_BAD_REMOVAL; /** - * Indicates the action of a common event that an external storage device was ejected. - * To subscribe to this common event, your application must have the ohos.permission.WRITE_USER_STORAGE or - * ohos.permission.READ_USER_STORAGE permission. - * This common event can be published only by system applications. - */ + * Indicates the action of a common event that an external storage device was ejected. + * To subscribe to this common event, your application must have the ohos.permission.STORAGE_MANAGER permission. + * This common event can be published only by system applications. + */ static const std::string COMMON_EVENT_VOLUME_EJECT; /** - * Indicates the action of a common event that the account visible changed. - * To subscribe to this common event, your application must have the ohos.permission.GET_APP_ACCOUNTS permission. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event that the account visible changed. + * To subscribe to this common event, your application must have the ohos.permission.GET_APP_ACCOUNTS permission. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_VISIBLE_ACCOUNTS_UPDATED; /** - * Indicates the action of a common event that the account is deleted. - * To subscribe to this common event, your application must have the ohos.permission.INTERACT_ACROSS_LOCAL_ACCOUNTS - * permission. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event that the account is deleted. + * To subscribe to this common event, your application must have the ohos.permission.INTERACT_ACROSS_LOCAL_ACCOUNTS + * permission. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_ACCOUNT_DELETED; /** - * Indicates the action of a common event that the foundation is ready. - * To subscribe to this common event, your application must have the ohos.permission.RECEIVER_STARTUP_COMPLETED - * permission. - * This is a protected common event, which can be sent only by the system. - */ + * Indicates the action of a common event that the foundation is ready. + * To subscribe to this common event, your application must have the ohos.permission.RECEIVER_STARTUP_COMPLETED + * permission. + * This is a protected common event, which can be sent only by the system. + */ static const std::string COMMON_EVENT_FOUNDATION_READY; /** - * Indicates the action of a common event that the phone SIM card state has changed. - * This is a protected common event that can only be sent by system. - */ + * Indicates the action of a common event that the default voice subscription has changed. + * This is a protected common event that can only be sent by system. + */ static const std::string COMMON_EVENT_SIM_CARD_DEFAULT_VOICE_SUBSCRIPTION_CHANGED; /** - * Indicates the action of a common event that the phone SIM card state has changed. - * This is a protected common event that can only be sent by system. - */ + * Indicates the action of a common event that the phone SIM card state has changed. + * This is a protected common event that can only be sent by system. + */ static const std::string COMMON_EVENT_SIM_STATE_CHANGED; /** - * Indicates the action of a common event that the airplane mode of the device has changed. - * This common event can be triggered only by system applications. - */ + * Indicates the action of a common event that the airplane mode of the device has changed. + * This common event can be triggered only by system applications. + */ static const std::string COMMON_EVENT_AIRPLANE_MODE_CHANGED; /** - * Indicates the action of a common event that a new sms bas been received by the device. - * This common event can be triggered only by system. - */ + * Indicates the action of a common event that a new sms bas been received by the device. + * To subscribe to this common event, your application must have the ohos.permission.RECEIVE_SMS permission. + * This common event can be triggered only by system. + */ static const std::string COMMON_EVENT_SMS_RECEIVE_COMPLETED; /** - * Indicates the action of a common event that a new sms emergency cell broadcast bas been received by the device. - * This common event can be triggered only by system. - */ + * Indicates the action of a common event that a new sms emergency cell broadcast bas been received by the device. + * This common event can be triggered only by system. + */ static const std::string COMMON_EVENT_SMS_EMERGENCY_CB_RECEIVE_COMPLETED; /** - * Indicates the action of a common event that a new sms normal cell broadcast bas been received by the device. - * This common event can be triggered only by system. - */ + * Indicates the action of a common event that a new sms normal cell broadcast bas been received by the device. + * This common event can be triggered only by system. + */ static const std::string COMMON_EVENT_SMS_CB_RECEIVE_COMPLETED; /** - * Indicates the action of a common event that a STK command has been received by the device. - * This common event can be triggered only by system. - */ + * Indicates the action of a common event that a STK command has been received by the device. + * This common event can be triggered only by system. + */ static const std::string COMMON_EVENT_STK_COMMAND; /** - * Indicates the action of a common event that STK session end. - * This common event can be triggered only by system. - */ + * Indicates the action of a common event that STK session end. + * This common event can be triggered only by system. + */ static const std::string COMMON_EVENT_STK_SESSION_END; /** - * Indicates the action of a common event that the STK phone card state has changed. - * This common event can be triggered only by system. - */ + * Indicates the action of a common event that the STK phone card state has changed. + * This common event can be triggered only by system. + */ static const std::string COMMON_EVENT_STK_CARD_STATE_CHANGED; /** - * Indicates the action of a common event that an alpha string during call control has been received by the device. - * This common event can be triggered only by system. - */ + * Indicates the action of a common event that an alpha string during call control has been received by the device. + * This common event can be triggered only by system. + */ static const std::string COMMON_EVENT_STK_ALPHA_IDENTIFIER; /** - * Indicates the action of a common event that the spn display information has been updated. - * This common event can be triggered only by system. - */ + * Indicates the action of a common event that the spn display information has been updated. + * This common event can be triggered only by system. + */ static const std::string COMMON_EVENT_SPN_INFO_CHANGED; /** - * Indicates the action of a common event that the NITZ time has been updated. - * This is a protected common event that can only be sent by system. - */ + * Indicates the action of a common event that the NITZ time has been updated. + * This is a protected common event that can only be sent by system. + */ static const std::string COMMON_EVENT_NITZ_TIME_CHANGED; /** - * Indicates the action of a common event that the NITZ time zone has been updated. - * This is a protected common event that can only be sent by system. - */ + * Indicates the action of a common event that the NITZ time zone has been updated. + * This is a protected common event that can only be sent by system. + */ static const std::string COMMON_EVENT_NITZ_TIMEZONE_CHANGED; /** - * Indicates the action of a common event that a new sms wappush has been received by the device. - * This is a protected common event that can only be sent by system. - */ + * Indicates the action of a common event that a new sms wappush has been received by the device. + * This is a protected common event that can only be sent by system. + */ static const std::string COMMON_EVENT_SMS_WAPPUSH_RECEIVE_COMPLETED; /** - * Indicates the action of a common event that the operator config has been updated. - * This is a protected common event that can only be sent by system. - */ + * Indicates the action of a common event that the operator config has been updated. + * This is a protected common event that can only be sent by system. + */ static const std::string COMMON_EVENT_OPERATOR_CONFIG_CHANGED; /** - * Indicates the action of a common event that the notification slot has been updated. - * This is a protected common event that can only be sent by system. - */ + * Indicates the action of a common event that the notification slot has been updated. + * This is a protected common event that can only be sent by system. + */ static const std::string COMMON_EVENT_SLOT_CHANGE; /** - * Only for test case. - */ + * Only for test case. + */ static const std::string COMMON_EVENT_TEST_ACTION1; /** - * Only for test case. - */ + * Only for test case. + */ static const std::string COMMON_EVENT_TEST_ACTION2; + /** + * Indicates the action of a common event that the default SMS subscription has been changed. + * This is a protected common event that can only be sent by system. + */ + static const std::string COMMON_EVENT_SIM_CARD_DEFAULT_SMS_SUBSCRIPTION_CHANGED; + + /** + * Indicates the action of a common event that the default data subscription has been changed. + * This is a protected common event that can only be sent by system. + */ + static const std::string COMMON_EVENT_SIM_CARD_DEFAULT_DATA_SUBSCRIPTION_CHANGED; + + /** + * Indicates the action of a common event that the call state has been changed. + * To subscribe to this protected common event, your application must have the ohos.permission.GET_TELEPHONY_STATE + * permission. + * This is a protected common event that can only be sent by system. + */ + static const std::string COMMON_EVENT_CALL_STATE_CHANGED; + + /** + * Indicates the action of a common event that the default main subscription has been changed. + * This is a protected common event that can only be sent by system. + */ + static const std::string COMMON_EVENT_SIM_CARD_DEFAULT_MAIN_SUBSCRIPTION_CHANGED; + + /** + * Indicates the action of a common event that the status of setting primary slot has been changed. + * This is a protected common event that can only be sent by system. + */ + static const std::string COMMON_EVENT_SET_PRIMARY_SLOT_STATUS; + + /** + * Indicates the action of a common event that the roaming status of main card has been changed. + * This is a protected common event that can only be sent by system. + */ + static const std::string COMMON_EVENT_PRIMARY_SLOT_ROAMING; + + /** + * Indicates the action of a common event that the cellular data state has been changed. + * This is a protected common event that can only be sent by system. + */ + static const std::string COMMON_EVENT_CELLULAR_DATA_STATE_CHANGED; + + /** + * Indicates the action of a common event that the signal info has been changed. + * This is a protected common event that can only be sent by system. + */ + static const std::string COMMON_EVENT_SIGNAL_INFO_CHANGED; + + /** + * Indicates the action of a common event that the network state has been changed. + * This is a protected common event that can only be sent by system. + */ + static const std::string COMMON_EVENT_NETWORK_STATE_CHANGED; + + /** + * Indicates the action of a common event that the incoming call has been missed. + * To subscribe to this protected common event, your application must have the ohos.permission.GET_TELEPHONY_STATE + * permission. + * This is a protected common event that can only be sent by system. + */ + static const std::string COMMON_EVENT_INCOMING_CALL_MISSED; + + /** + * Indicate the result of quick fix apply. + * This common event can be triggered only by system. + */ + static const std::string COMMON_EVENT_QUICK_FIX_APPLY_RESULT; + + /** + * Indicate the result of quick fix revoke. + * This common event can be triggered only by system. + */ + static const std::string COMMON_EVENT_QUICK_FIX_REVOKE_RESULT; + + /** + * Indicates the action of a common event that radio state change. + * To subscribe to this protected common event that can only be sent by system. + */ + static const std::string COMMON_EVENT_RADIO_STATE_CHANGE; + + /** + * Indicates the action of a common event about a login of a distributed account. + * This is a protected common event that can only be sent by system. + */ + static const std::string COMMON_EVENT_DISTRIBUTED_ACCOUNT_LOGIN; + + /** + * Indicates the action of a common event about a logout of a distributed account. + * This is a protected common event that can only be sent by system. + */ + static const std::string COMMON_EVENT_DISTRIBUTED_ACCOUNT_LOGOUT; + + /** + * Indicates the action of a common event that the token of a distributed account is invalid. + * This is a protected common event that can only be sent by system. + */ + static const std::string COMMON_EVENT_DISTRIBUTED_ACCOUNT_TOKEN_INVALID; + + /** + * Indicates the action of a common event about a logoff of a distributed account. + * This is a protected common event that can only be sent by system. + */ + static const std::string COMMON_EVENT_DISTRIBUTED_ACCOUNT_LOGOFF; + + /** + * Indicates the action of a common event that the user information has been updated. + * This is a protected common event that can only be sent by system. + */ + static const std::string COMMON_EVENT_USER_INFO_UPDATED; + + /** + * Indicate the action of a common event that domain account status has been changed. + * This is a protected common event that can only be sent by system. + */ + static const std::string COMMON_EVENT_DOMAIN_ACCOUNT_STATUS_CHANGED; + + /** + * Indicates the action of a common event that the screen lock. + * This is a protected common event that can only be sent by system. + */ + static const std::string COMMON_EVENT_SCREEN_LOCKED; + + /** + * Indicates the action of a common event that the screen unlock. + * This is a protected common event that can only be sent by system. + */ + static const std::string COMMON_EVENT_SCREEN_UNLOCKED; + + /** + * Indicates the action of a common event that the call audio quality information has been updated. + * This is a protected common event that can only be sent by system. + */ + static const std::string COMMON_EVENT_AUDIO_QUALITY_CHANGE; + + /** + * Indicates the action of a common event about special code. + * This is a protected common event that can only be sent by system. + */ + static const std::string COMMON_EVENT_SPECIAL_CODE; + + /** + * Indicates the action of a common event about reminder + * When the user clicks the button and the application (creator) + * is in the foreground, a event is sent. event data is: button type,reminder id + */ + static const std::string COMMON_EVENT_REMINDER_STATUS_CHANGE; + + /** + * Indicates that the privacy status is changed. + * This is a protected common event that can only be sent by system. + */ + static const std::string COMMON_EVENT_PRIVACY_STATE_CHANGED; + + /** + * Indicates that the file access state is changed. + * This is a protected common event that can only be sent by system. + */ + static const std::string COMMON_EVENT_SCREEN_LOCK_FILE_ACCESS_STATE_CHANGED; + + /** + * This common event means that minors mode is enabled. + * This is a protected common event that can only be sent by system. + */ + static const std::string COMMON_EVENT_MINORSMODE_ON; + + /** + * This common event means that minors mode is disabled. + * This is a protected common event that can only be sent by system. + */ + static const std::string COMMON_EVENT_MINORSMODE_OFF; + + /** + * Indicates the action of a common event that the bundle resources have been changed. + * To subscribe to this common event, your application must have the ohos.permission.GET_BUNDLE_RESOURCES + * permission. + * This is a protected common event, which can be sent only by the system. + */ + static const std::string COMMON_EVENT_BUNDLE_RESOURCES_CHANGED; + + /** + * This common event means that datashare is ready. + * This is a protected common event that can only be sent by system. + */ + static const std::string COMMON_EVENT_DATA_SHARE_READY; + public: CommonEventSupport(); virtual ~CommonEventSupport(); /** - * Checks whether the current common event is a system common event. - * @param str Indicates the action of a common event. - * @return Returns whether the current common event is a system common event or not. - */ + * Checks whether the current common event is a system common event. + * @param str Indicates the action of a common event. + * @return Returns whether the current common event is a system common event or not. + */ bool IsSystemEvent(std::string &str); private: @@ -1106,7 +1324,7 @@ private: private: std::vector commonEventSupport_; }; -} // namespace EventFwk -} // namespace OHOS +} // namespace EventFwk +} // namespace OHOS -#endif // FOUNDATION_EVENT_CESFWK_KITS_NATIVE_INCLUDE_COMMON_EVENT_SUPPORT_H \ No newline at end of file +#endif // FOUNDATION_EVENT_CESFWK_KITS_NATIVE_INCLUDE_COMMON_EVENT_SUPPORT_H \ No newline at end of file diff --git a/mock/innerkits/dmsfwk_standard/distributed_event/include/distributed_event_listener.h b/mock/innerkits/dmsfwk_standard/distributed_event/include/distributed_event_listener.h index dacc556a..985fa7bb 100644 --- a/mock/innerkits/dmsfwk_standard/distributed_event/include/distributed_event_listener.h +++ b/mock/innerkits/dmsfwk_standard/distributed_event/include/distributed_event_listener.h @@ -19,19 +19,10 @@ #include #include "iremote_broker.h" +#include "distributed_sched_types.h" namespace OHOS { namespace DistributedSchedule { -class EventNotify { -public: - int32_t eventResult_ = -1; - std::string srcNetworkId_; - std::string dstNetworkId_; - std::string bundleName_; - std::string moduleName_; - std::string abilityName_; -}; - class IDSchedEventListener : public OHOS::IRemoteBroker { public: DECLARE_INTERFACE_DESCRIPTOR(u"ohos.distributedSchedule.dschedeventlistener"); diff --git a/mock/innerkits/dmsfwk_standard/distributed_event/include/distributed_sched_types.h b/mock/innerkits/dmsfwk_standard/distributed_event/include/distributed_sched_types.h new file mode 100644 index 00000000..715cecd9 --- /dev/null +++ b/mock/innerkits/dmsfwk_standard/distributed_event/include/distributed_sched_types.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_SCHED_TYPES_H +#define OHOS_DISTRIBUTED_SCHED_TYPES_H + +#include + +namespace OHOS { +namespace DistributedSchedule { +class ContinueInfo { +public: + std::string srcNetworkId_; + std::string dstNetworkId_; +}; + +enum DSchedEventType { + DMS_UNKNOW = -1, + DMS_CONTINUE = 0, + DMS_COLLABORATION = 1, + DMS_ALL = 2, +}; + +enum DSchedEventState { + DMS_DSCHED_EVENT_INIT = 0, + DMS_DSCHED_EVENT_START = 1, + DMS_DSCHED_EVENT_PROCESSING = 2, + DMS_DSCHED_EVENT_STOP = 3, + DMS_DSCHED_EVENT_FINISH = 4, +}; + +class EventNotify { +public: + int32_t eventResult_ = -1; + std::string srcNetworkId_ = ""; + std::string dstNetworkId_ = ""; + std::string srcBundleName_ = ""; + std::string srcModuleName_ = ""; + std::string srcAbilityName_ = ""; + std::string destBundleName_ = ""; + std::string destModuleName_ = ""; + std::string destAbilityName_ = ""; + DSchedEventType dSchedEventType_ = DMS_UNKNOW; + DSchedEventState state_ = DMS_DSCHED_EVENT_INIT; +}; +} // namespace DistributedSchedule +} // namespace OHOS +#endif // OHOS_DISTRIBUTED_SCHED_TYPES_H \ No newline at end of file diff --git a/mock/innerkits/dmsfwk_standard/distributed_event/include/dms_client.h b/mock/innerkits/dmsfwk_standard/distributed_event/include/dms_client.h index 20c06d8d..12ec4cdf 100644 --- a/mock/innerkits/dmsfwk_standard/distributed_event/include/dms_client.h +++ b/mock/innerkits/dmsfwk_standard/distributed_event/include/dms_client.h @@ -21,15 +21,10 @@ #include "ability_manager_errors.h" #include "distributed_event_listener.h" #include "iremote_broker.h" +#include "distributed_sched_types.h" namespace OHOS { namespace DistributedSchedule { -class ContinueInfo { -public: - std::string srcNetworkId_; - std::string dstNetworkId_; -}; - class DistributedClient { public: int32_t RegisterDSchedEventListener(const std::string& type, const sptr& obj); diff --git a/mock/innerkits/dmsfwk_standard/distributed_event/include/dms_handler.h b/mock/innerkits/dmsfwk_standard/distributed_event/include/dms_handler.h index 6201cf44..bda0a1b8 100644 --- a/mock/innerkits/dmsfwk_standard/distributed_event/include/dms_handler.h +++ b/mock/innerkits/dmsfwk_standard/distributed_event/include/dms_handler.h @@ -24,6 +24,7 @@ #include "distributed_event_listener.h" #include "dms_sa_client.h" +#include "distributed_sched_types.h" namespace OHOS { namespace DistributedSchedule { @@ -33,6 +34,7 @@ public: int32_t RegisterDSchedEventListener(std::string type, sptr &listener); int32_t UnRegisterDSchedEventListener(std::string type, sptr &listener); int32_t GetContinueInfo(ContinueInfo &continueInfo); + int32_t GetDSchedEventInfo(const DSchedEventType &type, std::vector &events); }; } // namespace DistributedSchedule } // namespace OHOS diff --git a/mock/innerkits/dsoftbus/softbus_client/include/lnn/data_level.h b/mock/innerkits/dsoftbus/softbus_client/include/lnn/data_level.h index 2a39569b..7cbba4d5 100644 --- a/mock/innerkits/dsoftbus/softbus_client/include/lnn/data_level.h +++ b/mock/innerkits/dsoftbus/softbus_client/include/lnn/data_level.h @@ -59,7 +59,7 @@ typedef struct { * @since 1.0 * @version 1.0 */ - void (*OnDataLevelChanged)(const char *networkId, const DataLevel dataLevel); + void (*onDataLevelChanged)(const char *networkId, const DataLevel dataLevel); } IDataLevelCb; /** diff --git a/mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/asset/asset_adapter_sa_client.h b/mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/asset/asset_adapter_sa_client.h new file mode 100644 index 00000000..867a1f2b --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/asset/asset_adapter_sa_client.h @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef OHOS_STORAGE_ASSET_ADAPTER_SA_CLIENT_H +#define OHOS_STORAGE_ASSET_ADAPTER_SA_CLIENT_H + +#include +#include +#include "asset/i_asset_recv_callback.h" +#include "refbase.h" +#include "system_ability_status_change_stub.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class AssetAdapterSaClient { +public: + static AssetAdapterSaClient &GetInstance(); + bool SubscribeAssetAdapterSA(); + int32_t AddListener(const sptr &listener); + int32_t RemoveListener(const sptr &listener); + bool CheckSystemAbilityStatus(); + void OnAddSystemAbility(); +private: + AssetAdapterSaClient(); + std::vector> listeners_; + std::mutex eventMutex_; +}; + +class AssetSystemAbilityStatusChange : public SystemAbilityStatusChangeStub { +public: + AssetSystemAbilityStatusChange(); + ~AssetSystemAbilityStatusChange(); + void OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId) override; + void OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId) override; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // OHOS_STORAGE_ASSET_ADAPTER_SA_CLIENT_H diff --git a/mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/asset/asset_callback_interface_code.h b/mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/asset/asset_callback_interface_code.h new file mode 100644 index 00000000..585be717 --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/asset/asset_callback_interface_code.h @@ -0,0 +1,31 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + */ + +#ifndef FILEMANAGEMENT_DFS_SERVICE_SDK_ASSET_CALLBACK_INTERFACE_CODE_H +#define FILEMANAGEMENT_DFS_SERVICE_SDK_ASSET_CALLBACK_INTERFACE_CODE_H + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +enum class AssetCallbackInterfaceCode { + ASSET_CALLBACK_ON_START = 0, + ASSET_CALLBACK_ON_FINISHED, + ASSET_CALLBACK_ON_SEND_RESULT, +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS + +#endif // FILEMANAGEMENT_DFS_SERVICE_SDK_ASSET_CALLBACK_INTERFACE_CODE_H diff --git a/mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/asset/asset_obj.h b/mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/asset/asset_obj.h new file mode 100644 index 00000000..f48cc87c --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/asset/asset_obj.h @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + */ + +#ifndef OHOS_STORAGE_ASSET_OBJ_H +#define OHOS_STORAGE_ASSET_OBJ_H + +#include +#include +#include "parcel.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +struct AssetObj : public Parcelable { +public: + std::string sessionId_; + std::string dstNetworkId_; + std::string srcBundleName_; + std::string dstBundleName_; + std::vector uris_; + bool ReadFromParcel(Parcel &parcel); + bool Marshalling(Parcel &parcel) const override; + static AssetObj *Unmarshalling(Parcel &parcel); + + AssetObj() = default; + AssetObj(const AssetObj &assetObj) + : sessionId_(assetObj.sessionId_), + dstNetworkId_(assetObj.dstNetworkId_), + srcBundleName_(assetObj.srcBundleName_), + dstBundleName_(assetObj.dstBundleName_), + uris_(assetObj.uris_) + { + } +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // OHOS_STORAGE_ASSET_OBJ_H diff --git a/mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/asset/asset_recv_callback_stub.h b/mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/asset/asset_recv_callback_stub.h new file mode 100644 index 00000000..f1317b51 --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/asset/asset_recv_callback_stub.h @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + */ + +#ifndef FILEMANAGEMENT_DFS_SERVICE_SDK_ASSET_RECV_CALLBACK_STUB_H +#define FILEMANAGEMENT_DFS_SERVICE_SDK_ASSET_RECV_CALLBACK_STUB_H + +#include + +#include "asset/i_asset_recv_callback.h" +#include "iremote_stub.h" +#include "message_option.h" +#include "message_parcel.h" +#include "refbase.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class AssetRecvCallbackStub : public IRemoteStub { +public: + AssetRecvCallbackStub(); + virtual ~AssetRecvCallbackStub() = default; + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // FILEMANAGEMENT_DFS_SERVICE_SDK_ASSET_RECV_CALLBACK_STUB_H diff --git a/mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/asset/asset_send_callback_stub.h b/mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/asset/asset_send_callback_stub.h new file mode 100644 index 00000000..2e48a5e3 --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/asset/asset_send_callback_stub.h @@ -0,0 +1,40 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + */ + +#ifndef FILEMANAGEMENT_DFS_SERVICE_SDK_ASSET_SEND_CALLBACK_STUB_H +#define FILEMANAGEMENT_DFS_SERVICE_SDK_ASSET_SEND_CALLBACK_STUB_H + +#include + +#include "asset/i_asset_send_callback.h" +#include "iremote_stub.h" +#include "message_option.h" +#include "message_parcel.h" +#include "refbase.h" + + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class AssetSendCallbackStub : public IRemoteStub { +public: + AssetSendCallbackStub(); + virtual ~AssetSendCallbackStub() = default; + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // FILEMANAGEMENT_DFS_SERVICE_SDK_ASSET_SEND_CALLBACK_STUB_H diff --git a/mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/asset/i_asset_recv_callback.h b/mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/asset/i_asset_recv_callback.h new file mode 100644 index 00000000..0c82df8e --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/asset/i_asset_recv_callback.h @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef OHOS_STORAGE_I_ASSET_RECV_CALLBACK_H +#define OHOS_STORAGE_I_ASSET_RECV_CALLBACK_H + +#include +#include +#include "asset/asset_obj.h" +#include "iremote_broker.h" +#include "refbase.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class IAssetRecvCallback : public IRemoteBroker { +public: + enum { + ASSET_RECV_CALLBACK_SUCCESS = 0, + ASSET_RECV_CALLBACK_DESCRIPTOR_IS_EMPTY, + }; + virtual int32_t OnStart(const std::string &srcNetworkId, + const std::string &dstNetworkId, + const std::string &sessionId, + const std::string &dstBundleName) = 0; + virtual int32_t OnFinished(const std::string &srcNetworkId, + const sptr &assetObj, + int32_t result) = 0; + DECLARE_INTERFACE_DESCRIPTOR(u"ohos.storage.distributedfile.assetrecvcallback") +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // OHOS_STORAGE_I_ASSET_RECV_CALLBACK_H diff --git a/mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/asset/i_asset_send_callback.h b/mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/asset/i_asset_send_callback.h new file mode 100644 index 00000000..3e245964 --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/asset/i_asset_send_callback.h @@ -0,0 +1,40 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef OHOS_STORAGE_I_ASSET_SEND_CALLBACK_H +#define OHOS_STORAGE_I_ASSET_SEND_CALLBACK_H + +#include +#include +#include "asset/asset_obj.h" +#include "iremote_broker.h" +#include "refbase.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class IAssetSendCallback : public IRemoteBroker { +public: + enum { + ASSET_SEND_CALLBACK_SUCCESS = 0, + ASSET_SEND_CALLBACK_DESCRIPTOR_IS_EMPTY, + }; + virtual int32_t OnSendResult(const sptr &assetObj, int32_t result) = 0; + DECLARE_INTERFACE_DESCRIPTOR(u"ohos.storage.distributedfile.assetsendcallback") +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // OHOS_STORAGE_I_ASSET_SEND_CALLBACK_H diff --git a/mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/distributed_file_daemon_manager_impl.h b/mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/distributed_file_daemon_manager_impl.h index 663f89d5..5d0696f4 100644 --- a/mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/distributed_file_daemon_manager_impl.h +++ b/mock/innerkits/filemanagement/dfs_service/frameworks/native/distributed_file_inner/include/distributed_file_daemon_manager_impl.h @@ -1,24 +1,29 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +* Copyright (c) 2023-2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ #ifndef DISTRIBUTED_FILE_DAEMON_MANAGER_IMPL_H #define DISTRIBUTED_FILE_DAEMON_MANAGER_IMPL_H -#include "ipc/distributed_file_daemon_manager.h" +#include "asset/asset_obj.h" +#include "asset/i_asset_recv_callback.h" +#include "asset/i_asset_send_callback.h" #include "dm_device_info.h" +#include "ipc/distributed_file_daemon_manager.h" +#include "ipc/i_file_dfs_listener.h" #include "nocopyable.h" +#include "refbase.h" namespace OHOS { namespace Storage { @@ -29,14 +34,19 @@ public: int32_t OpenP2PConnection(const DistributedHardware::DmDeviceInfo &deviceInfo) override; int32_t CloseP2PConnection(const DistributedHardware::DmDeviceInfo &deviceInfo) override; - int32_t PrepareSession(const std::string &srcUri, - const std::string &dstUri, - const std::string &srcDeviceId, - const sptr &listener) override; - int32_t RequestSendFile(const std::string &srcUri, - const std::string &dstPath, - const std::string &remoteDeviceId, - const std::string &sessionName); + int32_t OpenP2PConnectionEx(const std::string &networkId, sptr remoteReverseObj) override; + int32_t CloseP2PConnectionEx(const std::string &networkId) override; + int32_t PrepareSession(const std::string &srcUri, const std::string &dstUri, const std::string &srcDeviceId, + const sptr &listener, HmdfsInfo &info) override; + int32_t CancelCopyTask(const std::string &sessionName) override; + int32_t RequestSendFile(const std::string &srcUri, const std::string &dstPath, const std::string &remoteDeviceId, + const std::string &sessionName); + int32_t GetRemoteCopyInfo(const std::string &srcUri, bool &isFile, bool &isDir); + + int32_t PushAsset(int32_t userId, const sptr &assetObj, + const sptr &sendCallback) override; + int32_t RegisterAssetCallback(const sptr &recvCallback) override; + int32_t UnRegisterAssetCallback(const sptr &recvCallback) override; private: DistributedFileDaemonManagerImpl() = default; diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/device/device_info.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/device/device_info.h new file mode 100644 index 00000000..0abd9452 --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/device/device_info.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef DEVICE_INFO_H +#define DEVICE_INFO_H + +#include +#include + +#include "device_manager.h" +#include "dm_device_info.h" +#include "ipc/i_daemon.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class DeviceInfo final { +public: + DeviceInfo() = default; + ~DeviceInfo() = default; + explicit DeviceInfo(const DistributedHardware::DmDeviceInfo &nodeInfo); + DeviceInfo(const DeviceInfo &nodeInfo); + DeviceInfo &operator=(const DistributedHardware::DmDeviceInfo &nodeInfo); + + void SetCid(const std::string &cid); + + const std::string &GetCid() const; + const std::string &GetExtraData() const; + const std::string &GetDeviceId() const; + +private: + friend class DeviceManagerAgent; + std::atomic initCidFlag_ { false }; + std::string cid_; + std::string udid_; + std::string extraData_; + std::string deviceId_; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // DEVICE_INFO_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/device/device_manager_agent.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/device/device_manager_agent.h new file mode 100644 index 00000000..0e70dd9a --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/device/device_manager_agent.h @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef DEVICE_MANAGER_AGENT_H +#define DEVICE_MANAGER_AGENT_H + +#include +#include +#include +#include +#include +#include +#include "device_auth.h" +#include "device_info.h" +#include "device_manager.h" +#include "dfsu_actor.h" +#include "dfsu_singleton.h" +#include "dfsu_startable.h" +#include "i_file_dfs_listener.h" +#include "mountpoint/mount_point.h" +#include "network/network_agent_template.h" +#include "nlohmann/json.hpp" +#include "storage_manager_proxy.h" +#include "utils_directory.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +const int32_t ON_STATUS_OFFLINE = 13900046; +struct GroupInfo { + std::string groupName; + std::string groupId; + std::string groupOwner; + int32_t groupType; + GroupInfo() : groupType(0) {} + GroupInfo(std::string name, std::string id, std::string owner, int32_t type) + : groupName(name), groupId(id), groupOwner(owner), groupType(type) + { + } +}; + +void from_json(const nlohmann::json &jsonObject, GroupInfo &groupInfo); + +class DeviceManagerAgent final : public DistributedHardware::DmInitCallback, + public DistributedHardware::DeviceStateCallback, + public std::enable_shared_from_this, + public DfsuStartable, + public DfsuActor, + public Utils::DfsuSingleton { + DECLARE_SINGLETON(DeviceManagerAgent); + +public: + enum P2PErrCode:int32_t { + P2P_SUCCESS, + P2P_FAILED, + }; + void Start() override; + void Stop() override; + void JoinGroup(std::weak_ptr mp); + void QuitGroup(std::weak_ptr mp); + + void InitDeviceInfos(); + int32_t IsSupportedDevice(const DistributedHardware::DmDeviceInfo &deviceInfo); + + void OnDeviceReady(const DistributedHardware::DmDeviceInfo &deviceInfo) override; + void OnDeviceOffline(const DistributedHardware::DmDeviceInfo &deviceInfo) override; + void OnDeviceChanged(const DistributedHardware::DmDeviceInfo &deviceInfo) override; + void OnDeviceOnline(const DistributedHardware::DmDeviceInfo &deviceInfo) override {} + + int32_t OnDeviceP2POnline(const DistributedHardware::DmDeviceInfo &deviceInfo); + int32_t OnDeviceP2POffline(const DistributedHardware::DmDeviceInfo &deviceInfo); + int32_t AddRemoteReverseObj(uint32_t callingTokenId, sptr remoteReverseObj); + int32_t RemoveRemoteReverseObj(bool clear, uint32_t callingTokenId); + void NotifyRemoteReverseObj(const std::string &networkId, int32_t status); + int32_t FindListenerByObject(const wptr &remote, uint32_t &tokenId, + sptr& listener); + std::string GetDeviceIdByNetworkId(const std::string &networkId); + void MountDfsDocs(const std::string &networkId, const std::string &deviceId); + int32_t UMountDfsDocs(const std::string &networkId, const std::string &deviceId, bool needClear); + void AddNetworkId(uint32_t tokenId, const std::string &networkId); + void RemoveNetworkId(uint32_t tokenId); + void RemoveNetworkIdByOne(uint32_t tokenId, const std::string &networkId); + void RemoveNetworkIdForAllToken(const std::string &networkId); + void ClearNetworkId(); + std::unordered_set GetNetworkIds(uint32_t tokenId); + + void OfflineAllDevice(); + void ReconnectOnlineDevices(); + void OnRemoteDied() override; + + DeviceInfo &GetLocalDeviceInfo(); + std::vector GetRemoteDevicesInfo(); + std::mutex appCallConnectMutex_; + std::unordered_map> appCallConnect_; + +private: + void StartInstance() override; + void StopInstance() override; + void InitLocalNodeInfo(); + + void RegisterToExternalDm(); + void UnregisterFromExternalDm(); + + int32_t GetNetworkType(const std::string &cid); + bool IsWifiNetworkType(int32_t networkType); + + void QueryRelatedGroups(const std::string &udid, const std::string &networkId); + bool CheckIsAccountless(const GroupInfo &group); + std::shared_ptr FindNetworkBaseTrustRelation(bool isAccountless); + // We use a mutex instead of a shared_mutex to serialize online/offline procedures + std::mutex mpToNetworksMutex_; + std::map> mpToNetworks_; + DeviceInfo localDeviceInfo_; + + // cid-->same_account/accoutless's network + std::unordered_map> cidNetTypeRecord_; + std::unordered_map cidNetworkType_; + bool MountDfsCountOnly(const std::string &deviceId); + bool UMountDfsCountOnly(const std::string &deviceId, bool needClear); + int32_t GetCurrentUserId(); + void GetStorageManager(); + sptr storageMgrProxy_; + std::unordered_map mountDfsCount_; + std::mutex networkIdMapMutex_; + std::unordered_map> networkIdMap_; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // DEVICE_MANAGER_AGENT_H diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/asset_callback_manager.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/asset_callback_manager.h new file mode 100644 index 00000000..3feb7fc1 --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/asset_callback_manager.h @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + */ + +#ifndef FILEMANAGEMENT_DFS_SERVICE_SDK_ASSET_CALLBACK_MANAGER_H +#define FILEMANAGEMENT_DFS_SERVICE_SDK_ASSET_CALLBACK_MANAGER_H + +#include +#include +#include + +#include "asset/i_asset_recv_callback.h" +#include "asset/i_asset_send_callback.h" +#include "refbase.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { + +class AssetCallbackManager { +public: + static AssetCallbackManager &GetInstance(); + + void AddRecvCallback(const sptr &recvCallback); + void RemoveRecvCallback(const sptr &recvCallback); + void AddSendCallback(const std::string &taskId, const sptr &sendCallback); + void RemoveSendCallback(const std::string &taskId); + + void NotifyAssetRecvStart(const std::string &srcNetworkId, + const std::string &dstNetworkId, + const std::string &sessionId, + const std::string &dstBundleName); + void NotifyAssetRecvFinished(const std::string &srcNetworkId, + const sptr &assetObj, + int32_t result); + void NotifyAssetSendResult(const std::string &taskId, + const sptr &assetObj, + int32_t result); + +private: + std::mutex recvCallbackListMutex_; + std::vector> recvCallbackList_; + std::mutex sendCallbackMapMutex_; + std::map> sendCallbackMap_; +}; + +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS + +#endif // FILEMANAGEMENT_DFS_SERVICE_SDK_ASSET_CALLBACK_MANAGER_H diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/asset_recv_callback_proxy.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/asset_recv_callback_proxy.h new file mode 100644 index 00000000..92f25060 --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/asset_recv_callback_proxy.h @@ -0,0 +1,45 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef ASSET_RECV_CALLBACK_PROXY_H +#define ASSET_RECV_CALLBACK_PROXY_H + +#include +#include "asset/asset_obj.h" +#include "asset/i_asset_recv_callback.h" +#include "iremote_proxy.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class AssetRecvCallbackProxy : public IRemoteProxy { +public: + explicit AssetRecvCallbackProxy(const sptr &object) : IRemoteProxy(object) {} + ~AssetRecvCallbackProxy() override = default; + int32_t OnStart(const std::string &srcNetworkId, + const std::string &destNetworkId, + const std::string &sessionId, + const std::string &destBundleName) override; + int32_t OnFinished(const std::string &srcNetworkId, + const sptr &assetObj, + int32_t result) override; +private: + static inline BrokerDelegator delegator_; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS + +#endif // ASSET_RECV_CALLBACK_PROXY_H diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/asset_send_callback_proxy.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/asset_send_callback_proxy.h new file mode 100644 index 00000000..25b37f4f --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/asset_send_callback_proxy.h @@ -0,0 +1,40 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + */ + +#ifndef ASSET_SEND_CALLBACK_PROXY_H +#define ASSET_SEND_CALLBACK_PROXY_H + +#include "asset/asset_obj.h" +#include "asset/i_asset_send_callback.h" +#include "iremote_proxy.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class AssetSendCallbackProxy : public IRemoteProxy { +public: + explicit AssetSendCallbackProxy(const sptr &object) : IRemoteProxy(object) {} + ~AssetSendCallbackProxy() override = default; + + int32_t OnSendResult(const sptr &assetObj, int32_t result) override; + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS + +#endif // ASSET_SEND_CALLBACK_PROXY_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/connection_detector.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/connection_detector.h new file mode 100644 index 00000000..4869d461 --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/connection_detector.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FILEMANAGEMENT_DFS_SERVICE_CONNECTION_DETECTOR_H +#define FILEMANAGEMENT_DFS_SERVICE_CONNECTION_DETECTOR_H + +#include "os_account_manager.h" + +#include +#include + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +using namespace std; +const std::string HMDFS_PATH = "/mnt/hmdfs//account"; +const std::string SYS_HMDFS_PATH = "/sys/fs/hmdfs/"; +const std::string CONNECTION_STATUS_FILE_NAME = "status"; +const std::string CURRENT_USER_ID_FLAG = ""; +constexpr int32_t MAX_RETRY = 25; +constexpr int32_t CHECK_SESSION_DELAY_TIME = 200000; +constexpr int32_t NO_ERROR = 0; +constexpr int32_t INVALID_USER_ID = -1; +constexpr int DISMATCH = 0; +constexpr int MATCH = 1; +class ConnectionDetector { +public: + static bool GetConnectionStatus(const std::string &targetDir, const std::string &networkId); + static int32_t RepeatGetConnectionStatus(const std::string &targetDir, const std::string &networkId); + static std::string ParseHmdfsPath(); + static uint64_t MocklispHash(const string &str); + +private: + static std::string GetCellByIndex(const std::string &str, int targetIndex); + static bool MatchConnectionStatus(ifstream &inputFile); + static bool MatchConnectionGroup(const std::string &fileName, const string &networkId); + static bool CheckValidDir(const std::string &path); + static int32_t GetCurrentUserId(); +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // FILEMANAGEMENT_DFS_SERVICE_CONNECTION_DETECTOR_H diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/daemon.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/daemon.h new file mode 100644 index 00000000..f9f0c810 --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/daemon.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DAEMON_H +#define DAEMON_H + +#include +#include +#include + +#include "accesstoken_kit.h" +#include "daemon_event.h" +#include "daemon_eventhandler.h" +#include "daemon_execute.h" +#include "daemon_stub.h" +#include "dm_device_info.h" +#include "file_trans_listener_proxy.h" +#include "hmdfs_info.h" +#include "ipc/i_daemon.h" +#include "iremote_stub.h" +#include "multiuser/os_account_observer.h" +#include "nocopyable.h" +#include "refbase.h" +#include "system_ability.h" +#include "accesstoken_kit.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +using HapTokenInfo = OHOS::Security::AccessToken::HapTokenInfo; +enum class ServiceRunningState { STATE_NOT_START, STATE_RUNNING }; + +class Daemon final : public SystemAbility, public DaemonStub, protected NoCopyable { + DECLARE_SYSTEM_ABILITY(Daemon); + +public: + explicit Daemon(int32_t saID, bool runOnCreate = true) : SystemAbility(saID, runOnCreate) {}; + virtual ~Daemon() = default; + + void OnStart() override; + void OnStop() override; + void OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId) override; + void OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId) override; + ServiceRunningState QueryServiceState() const + { + return state_; + } + + int32_t OpenP2PConnection(const DistributedHardware::DmDeviceInfo &deviceInfo) override; + int32_t CloseP2PConnection(const DistributedHardware::DmDeviceInfo &deviceInfo) override; + int32_t OpenP2PConnectionEx(const std::string &networkId, sptr remoteReverseObj) override; + int32_t CloseP2PConnectionEx(const std::string &networkId) override; + int32_t ConnectionCount(const DistributedHardware::DmDeviceInfo &deviceInfo); + int32_t PrepareSession(const std::string &srcUri, + const std::string &dstUri, + const std::string &srcDeviceId, + const sptr &listener, + HmdfsInfo &info) override; + int32_t CancelCopyTask(const std::string &sessionName) override; + int32_t RequestSendFile(const std::string &srcUri, + const std::string &dstPath, + const std::string &dstDeviceId, + const std::string &sessionName) override; + int32_t GetRemoteCopyInfo(const std::string &srcUri, bool &isFile, bool &isDir) override; + + int32_t PushAsset(int32_t userId, + const sptr &assetObj, + const sptr &sendCallback) override; + int32_t RegisterAssetCallback(const sptr &recvCallback) override; + int32_t UnRegisterAssetCallback(const sptr &recvCallback) override; + +private: + Daemon(); + ServiceRunningState state_ { ServiceRunningState::STATE_NOT_START }; + static sptr instance_; + static std::mutex instanceLock_; + bool registerToService_ { false }; + std::shared_ptr subScriber_; + void PublishSA(); + void RegisterOsAccount(); + sptr GetRemoteSA(const std::string &remoteDeviceId); + void StoreSessionAndListener(const std::string &physicalPath, + const std::string &sessionName, + const sptr &listener); + int32_t GetRealPath(const std::string &srcUri, + const std::string &dstUri, + std::string &physicalPath, + HmdfsInfo &info, + const sptr &daemon); + int32_t CheckCopyRule(std::string &physicalPath, + const std::string &dstUri, + HapTokenInfo &hapTokenInfo, + const bool &isSrcFile, + HmdfsInfo &info); + int32_t Copy(const std::string &srcUri, + const std::string &dstPath, + const sptr &daemon, + const std::string &sessionName); + void DeleteSessionAndListener(const std::string &sessionName); + + class DfsListenerDeathRecipient : public IRemoteObject::DeathRecipient { + public: + DfsListenerDeathRecipient(){}; + ~DfsListenerDeathRecipient() = default; + void OnRemoteDied(const wptr &remote) override; + }; + static inline sptr dfsListenerDeathRecipient_; +private: + std::mutex eventHandlerMutex_; + std::shared_ptr eventHandler_; + std::shared_ptr daemonExecute_; + void StartEventHandler(); +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // DAEMON_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/daemon_event.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/daemon_event.h new file mode 100644 index 00000000..6c1e1e1a --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/daemon_event.h @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + */ +#ifndef FILEMANAGEMENT_DFS_SERVICE_EVENTHANDLE_DAEMON_EVENT_H +#define FILEMANAGEMENT_DFS_SERVICE_EVENTHANDLE_DAEMON_EVENT_H + +#include "asset/asset_obj.h" +#include "asset/i_asset_send_callback.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +typedef enum { + DEAMON_EXECUTE_PUSH_ASSET = 1, +} DaemonEventType; + +struct PushAssetData { + PushAssetData(int32_t userId, const sptr &assetObj) + : userId_(userId), assetObj_(assetObj) + { + } + + int32_t userId_; + const sptr assetObj_; +}; + +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS + +#endif // FILEMANAGEMENT_DFS_SERVICE_EVENTHANDLE_DAEMON_EVENT_H diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/daemon_eventhandler.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/daemon_eventhandler.h new file mode 100644 index 00000000..af523541 --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/daemon_eventhandler.h @@ -0,0 +1,40 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef FILEMANAGEMENT_DFS_SERVICE_EVENTHANDLE_DAEMON_EVENTHANDLE_H +#define FILEMANAGEMENT_DFS_SERVICE_EVENTHANDLE_DAEMON_EVENTHANDLE_H + +#include + +#include "event_handler.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class DaemonExecute; +class DaemonEventHandler : public AppExecFwk::EventHandler { +public: + explicit DaemonEventHandler(const std::shared_ptr& runner, + const std::shared_ptr& daemonExecute); + ~DaemonEventHandler() override; + + void ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event) override; +private: + std::weak_ptr daemonExecute_; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // FILEMANAGEMENT_DFS_SERVICE_EVENTHANDLE_DAEMON_EVENTHANDLE_H diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/daemon_execute.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/daemon_execute.h new file mode 100644 index 00000000..c69cfb71 --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/daemon_execute.h @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + */ + +#ifndef FILEMANAGEMENT_DFS_SERVICE_EVENTHANDLE_DAEMON_EXECUTE_H +#define FILEMANAGEMENT_DFS_SERVICE_EVENTHANDLE_DAEMON_EXECUTE_H + +#include +#include +#include +#include +#include + +#include "daemon_event.h" +#include "daemon_eventhandler.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class DaemonExecute { +public: + explicit DaemonExecute(); + void ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event); + +private: + void ExecutePushAsset(const AppExecFwk::InnerEvent::Pointer &event); + std::vector GetFileList(const std::vector &uris, + int32_t userId, + const std::string &srcBundleName); + int32_t HandleZip(const std::vector &fileList, + const std::string &srcBundleName, + std::string &sendFileName, + bool &isSingleFile); + void HandlePushAssetFail(int32_t socketId, const sptr &assetObj); + + using ExecuteFunc = void (DaemonExecute::*)(const AppExecFwk::InnerEvent::Pointer &event); + std::mutex executeFuncMapMutex_; + std::map executeFuncMap_; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // FILEMANAGEMENT_DFS_SERVICE_EVENTHANDLE_DAEMON_EXECUTE_H diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/daemon_stub.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/daemon_stub.h new file mode 100644 index 00000000..242ba338 --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/daemon_stub.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef DAEMON_STUB_H +#define DAEMON_STUB_H + +#include + +#include "dm_device_info.h" +#include "i_daemon.h" +#include "iremote_stub.h" +#include "message_option.h" +#include "message_parcel.h" +#include "refbase.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class DaemonStub : public IRemoteStub { +public: + DaemonStub(); + virtual ~DaemonStub() = default; + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + +private: + using DaemonInterface = int32_t (DaemonStub::*)(MessageParcel &data, MessageParcel &reply); + std::map opToInterfaceMap_; + + int32_t HandleOpenP2PConnection(MessageParcel &data, MessageParcel &reply); + int32_t HandleCloseP2PConnection(MessageParcel &data, MessageParcel &reply); + int32_t HandleOpenP2PConnectionEx(MessageParcel &data, MessageParcel &reply); + int32_t HandleCloseP2PConnectionEx(MessageParcel &data, MessageParcel &reply); + int32_t HandlePrepareSession(MessageParcel &data, MessageParcel &reply); + int32_t HandleCancelCopyTask(MessageParcel &data, MessageParcel &reply); + int32_t HandleRequestSendFile(MessageParcel &data, MessageParcel &reply); + int32_t HandleGetRemoteCopyInfo(MessageParcel &data, MessageParcel &reply); + + int32_t HandlePushAsset(MessageParcel &data, MessageParcel &reply); + int32_t HandleRegisterRecvCallback(MessageParcel &data, MessageParcel &reply); + int32_t HandleUnRegisterRecvCallback(MessageParcel &data, MessageParcel &reply); +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // DAEMON_STUB_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/distributed_file_daemon_ipc_interface_code.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/distributed_file_daemon_ipc_interface_code.h new file mode 100644 index 00000000..0a332591 --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/distributed_file_daemon_ipc_interface_code.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef IPC_DISTRIBUTED_FILE_DAEMON_IPC_INTERFACE_CODE_H +#define IPC_DISTRIBUTED_FILE_DAEMON_IPC_INTERFACE_CODE_H + +/* SAID:5201 */ +namespace OHOS { +namespace Storage { +namespace DistributedFile { + enum class DistributedFileDaemonInterfaceCode { + DISTRIBUTED_FILE_OPEN_P2P_CONNECTION = 0, + DISTRIBUTED_FILE_CLOSE_P2P_CONNECTION, + DISTRIBUTED_FILE_PREPARE_SESSION, + DISTRIBUTED_FILE_REQUEST_SEND_FILE, + DISTRIBUTED_FILE_GET_REMOTE_COPY_INFO, + DISTRIBUTED_FILE_CANCEL_COPY_TASK, + DISTRIBUTED_FILE_OPEN_P2P_CONNECTION_EX, + DISTRIBUTED_FILE_CLOSE_P2P_CONNECTION_EX, + DISTRIBUTED_FILE_REGISTER_ASSET_CALLBACK, + DISTRIBUTED_FILE_UN_REGISTER_ASSET_CALLBACK, + DISTRIBUTED_FILE_PUSH_ASSET, + }; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif \ No newline at end of file diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/distributed_file_daemon_manager.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/distributed_file_daemon_manager.h new file mode 100644 index 00000000..d8beddf1 --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/distributed_file_daemon_manager.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DISTRIBUTED_FILE_DAEMON_MANAGER_H +#define DISTRIBUTED_FILE_DAEMON_MANAGER_H + +#include + +#include "asset/asset_obj.h" +#include "asset/i_asset_recv_callback.h" +#include "asset/i_asset_send_callback.h" +#include "dm_device_info.h" +#include "hmdfs_info.h" +#include "i_file_dfs_listener.h" +#include "i_file_trans_listener.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class DistributedFileDaemonManager { +public: + static DistributedFileDaemonManager &GetInstance(); + + virtual int32_t OpenP2PConnection(const DistributedHardware::DmDeviceInfo &deviceInfo) = 0; + virtual int32_t CloseP2PConnection(const DistributedHardware::DmDeviceInfo &deviceInfo) = 0; + virtual int32_t OpenP2PConnectionEx(const std::string &networkId, sptr remoteReverseObj) = 0; + virtual int32_t CloseP2PConnectionEx(const std::string &networkId) = 0; + virtual int32_t PrepareSession(const std::string &srcUri, + const std::string &dstUri, + const std::string &srcDeviceId, + const sptr &listener, + HmdfsInfo &info) = 0; + virtual int32_t CancelCopyTask(const std::string &sessionName) = 0; + + virtual int32_t PushAsset(int32_t userId, + const sptr &assetObj, + const sptr &sendCallback) = 0; + virtual int32_t RegisterAssetCallback(const sptr &recvCallback) = 0; + virtual int32_t UnRegisterAssetCallback(const sptr &recvCallback) =0; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS + +#endif // DISTRIBUTED_FILE_DAEMON_MANAGER_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/file_dfs_listener_interface_code.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/file_dfs_listener_interface_code.h new file mode 100644 index 00000000..5602c959 --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/file_dfs_listener_interface_code.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OHOS_STORAGE_FILE_DFS_LISTENER_INTERFACE_CODE_H +#define OHOS_STORAGE_FILE_DFS_LISTENER_INTERFACE_CODE_H +namespace OHOS { +namespace Storage { +namespace DistributedFile { +enum class FileDfsListenerInterfaceCode { + FILE_DFS_LISTENER_ON_STATUS = 0, +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS + +#endif //OHOS_STORAGE_FILE_DFS_LISTENER_INTERFACE_CODE_H diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/file_dfs_listener_proxy.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/file_dfs_listener_proxy.h new file mode 100644 index 00000000..41ca4fdf --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/file_dfs_listener_proxy.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FILE_DFS_LISTENER_PROXY_H +#define FILE_DFS_LISTENER_PROXY_H + +#include + +#include "dm_device_info.h" +#include "i_file_dfs_listener.h" +#include "iremote_proxy.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class FileDfsListenerProxy : public IRemoteProxy { +public: + explicit FileDfsListenerProxy(const sptr &object) : IRemoteProxy(object) {} + ~FileDfsListenerProxy() override {} + void OnStatus(const std::string &networkId, int32_t status) override; + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS + +#endif // FILE_DFS_LISTENER_PROXY_H diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/file_trans_listener_proxy.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/file_trans_listener_proxy.h new file mode 100644 index 00000000..b647cb4b --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/file_trans_listener_proxy.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FILE_TRANS_LISTENER_PROXY_H +#define FILE_TRANS_LISTENER_PROXY_H + +#include + +#include "dm_device_info.h" +#include "i_file_trans_listener.h" +#include "iremote_proxy.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class FileTransListenerProxy : public IRemoteProxy { +public: + explicit FileTransListenerProxy(const sptr &object) : IRemoteProxy(object) {} + ~FileTransListenerProxy() override {} + int32_t OnFileReceive(uint64_t totalBytes, uint64_t processedBytes) override; + int32_t OnFailed(const std::string &sessionName, int32_t errorCode) override; + int32_t OnFinished(const std::string &sessionName) override; + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS + +#endif // FILE_TRANS_LISTENER_PROXY_H diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/hmdfs_info.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/hmdfs_info.h new file mode 100644 index 00000000..666e260f --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/hmdfs_info.h @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef FILEMANAGEMENT_DFS_SERVICE_HMDFS_INFO_H +#define FILEMANAGEMENT_DFS_SERVICE_HMDFS_INFO_H + +#include + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +struct HmdfsInfo { + std::string copyPath; + bool dirExistFlag = false; + std::string authority; + std::string sandboxPath; + std::string sessionName; +}; +} +} +} +#endif // FILEMANAGEMENT_DFS_SERVICE_HMDFS_INFO_H diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/i_daemon.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/i_daemon.h new file mode 100644 index 00000000..0c7b3acd --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/i_daemon.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef I_DAEMON_H +#define I_DAEMON_H + +#include "asset/asset_obj.h" +#include "asset/i_asset_recv_callback.h" +#include "asset/i_asset_send_callback.h" +#include "dm_device_info.h" +#include "hmdfs_info.h" +#include "iremote_broker.h" +#include "i_file_dfs_listener.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class IDaemon : public IRemoteBroker { +public: + enum { + DFS_DAEMON_SUCCESS = 0, + DFS_DAEMON_DESCRIPTOR_IS_EMPTY, + }; + virtual int32_t OpenP2PConnection(const DistributedHardware::DmDeviceInfo &deviceInfo) = 0; + virtual int32_t CloseP2PConnection(const DistributedHardware::DmDeviceInfo &deviceInfo) = 0; + virtual int32_t OpenP2PConnectionEx(const std::string &networkId, sptr remoteReverseObj) = 0; + virtual int32_t CloseP2PConnectionEx(const std::string &networkId) = 0; + virtual int32_t PrepareSession(const std::string &srcUri, + const std::string &dstUri, + const std::string &srcDeviceId, + const sptr &listener, + HmdfsInfo &info) = 0; + virtual int32_t CancelCopyTask(const std::string &sessionName) = 0; + virtual int32_t RequestSendFile(const std::string &srcUri, + const std::string &dstPath, + const std::string &remoteDeviceId, + const std::string &sessionName) = 0; + static inline const std::string SERVICE_NAME { "ohos.storage.distributedfile.daemon" }; + virtual int32_t GetRemoteCopyInfo(const std::string &srcUri, bool &isFile, bool &isDir) = 0; + + virtual int32_t PushAsset(int32_t userId, + const sptr &assetObj, + const sptr &sendCallback) = 0; + virtual int32_t RegisterAssetCallback(const sptr &recvCallback) = 0; + virtual int32_t UnRegisterAssetCallback(const sptr &recvCallback) =0; + + DECLARE_INTERFACE_DESCRIPTOR(u"ohos.storage.distributedfile.daemon") +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // I_DAEMON_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/i_file_dfs_listener.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/i_file_dfs_listener.h new file mode 100644 index 00000000..2ceaf2f4 --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/i_file_dfs_listener.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_STORAGE_I_FILE_DFS_LISTENER_H +#define OHOS_STORAGE_I_FILE_DFS_LISTENER_H +#include +#include "iremote_broker.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { + +class IFileDfsListener : public OHOS::IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"ohos.storage.distributedfile.filedfslistener"); + + virtual void OnStatus(const std::string &networkId, int32_t status) = 0; + + enum { + FILE_DFS_LISTENER_SUCCESS = 0, + FILE_DFS_LISTENER_DESCRIPTOR_IS_EMPTY, + }; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS + +#endif // OHOS_STORAGE_I_FILE_DFS_LISTENER_H diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/trans_mananger.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/trans_mananger.h new file mode 100644 index 00000000..15756dbc --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/ipc/trans_mananger.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef TRANS_MANANGER_H +#define TRANS_MANANGER_H + +#include +#include +#include +#include + +#include "i_file_trans_listener.h" +#include "refbase.h" +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class TransManager { +public: + static TransManager &GetInstance(); + + void AddTransTask(const std::string &sessionName, const sptr &listener); + void NotifyFileProgress(const std::string &sessionName, uint64_t total, uint64_t processed); + void NotifyFileFailed(const std::string &sessionName, int32_t errorCode); + void NotifyFileFinished(const std::string &sessionName); + void DeleteTransTask(const std::string &sessionName); + +private: + std::mutex sessionTransMapMutex_; + std::map> sessionTransMap_; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // TRANS_MANANGER_H diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/mountpoint/mount_manager.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/mountpoint/mount_manager.h new file mode 100644 index 00000000..82ce01a8 --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/mountpoint/mount_manager.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MOUNT_MANAGER_H +#define MOUNT_MANAGER_H + +#include +#include + +#include "dfsu_singleton.h" +#include "mount_point.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class MountManager final : public Utils::DfsuSingleton { +public: + void Mount(std::unique_ptr mp); + void Umount(std::weak_ptr wmp); + void Umount(const std::string &groupId); + DECLARE_SINGLETON(MountManager); + +private: + void StartInstance() override {} + void StopInstance() override {} +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // MOUNT_MANAGER_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/mountpoint/mount_point.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/mountpoint/mount_point.h new file mode 100644 index 00000000..c2a274b8 --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/mountpoint/mount_point.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MOUNT_POINT_H +#define MOUNT_POINT_H + +#include +#include + +#include "dfsu_mount_argument_descriptors.h" +#include "nocopyable.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class MountPoint final : public NoCopyable { +public: + MountPoint(const Utils::MountArgument &mountArg); + ~MountPoint() = default; + + uint32_t GetID() const + { + return id_; + }; + + bool isAccountLess() const + { + return mountArg_.accountless_; + }; + + std::string ToString() const; + Utils::MountArgument GetMountArgument() const; + bool operator==(const MountPoint &rop) const; + +private: + friend class OsAccountObserver; + Utils::MountArgument mountArg_; + void Mount() const; + void Umount() const; + static std::atomic idGen_; + uint32_t id_ {0}; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // MOUNT_POINT_H \ No newline at end of file diff --git a/relational_store/frameworks/native/rdb/include/rdb_statement.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/multiuser/os_account_observer.h similarity index 32% rename from relational_store/frameworks/native/rdb/include/rdb_statement.h rename to mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/multiuser/os_account_observer.h index 14b80bbd..aabb010e 100644 --- a/relational_store/frameworks/native/rdb/include/rdb_statement.h +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/multiuser/os_account_observer.h @@ -13,46 +13,37 @@ * limitations under the License. */ -#ifndef NATIVE_RDB_STATEMENT_H -#define NATIVE_RDB_STATEMENT_H +#ifndef ACCOUNT_CHANGE_OBSERVER_H +#define ACCOUNT_CHANGE_OBSERVER_H #include +#include #include -#include "value_object.h" + +#include "common_event_subscribe_info.h" +#include "common_event_subscriber.h" +#include "mountpoint/mount_point.h" namespace OHOS { -namespace NativeRdb { +namespace Storage { +namespace DistributedFile { +static constexpr int MOUNT_POINT_NUM = 2; +class OsAccountObserver final : public EventFwk::CommonEventSubscriber { +public: + OsAccountObserver() = default; + ~OsAccountObserver(); + explicit OsAccountObserver(const EventFwk::CommonEventSubscribeInfo &subscribeInfo); -using Asset = ValueObject::Asset; -using Assets = ValueObject::Assets; -using FloatVector = ValueObject::FloatVector; + virtual void OnReceiveEvent(const EventFwk::CommonEventData &eventData) override; +private: + void RemoveMPInfo(const int id); + void AddMPInfo(const int id, const std::string &relativePath); -class RdbStatement { -public: - RdbStatement(); - virtual ~RdbStatement(); - virtual int PrepareStmt(const std::string &sql); - virtual int Finalize(); - virtual int BindArguments(const std::vector &bindArgs) const; - virtual int ResetStatementAndClearBindings() const; - virtual int Step() const; - virtual int GetColumnCount(int &count) const; - virtual int GetColumnName(int index, std::string &columnName) const; - virtual int GetColumnType(int index, int &columnType) const; - virtual int GetColumnBlob(int index, std::vector &value) const; - virtual int GetColumnString(int index, std::string &value) const; - virtual int GetFloat32Array(int index, std::vector &vecs) const; - virtual int GetColumnLong(int index, int64_t &value) const; - virtual int GetColumnDouble(int index, double &value) const; - virtual int GetSize(int index, size_t &size) const; - virtual int GetColumn(int index, ValueObject &value) const; - virtual bool IsReadOnly() const; - virtual bool SupportSharedBlock() const; -protected: - // Setting Data Precision - static constexpr int SET_DATA_PRECISION = 15; + std::mutex serializer_; + std::unordered_map>> mountPoints_; + int curUsrId { -1 }; }; - -} // namespace NativeRdb +} // namespace DistributedFile +} // namespace Storage } // namespace OHOS -#endif // NATIVE_RDB_STATEMENT_H +#endif // ACCOUNT_CHANGE_OBSERVER_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/base_session.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/base_session.h new file mode 100644 index 00000000..89a3f3e3 --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/base_session.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BASE_SESSION_H +#define BASE_SESSION_H + +#include +#include + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +constexpr int KEY_SIZE_MAX = 32; + +class BaseSession { +public: + virtual ~BaseSession() = default; + virtual bool IsFromServer() const = 0; + virtual std::string GetCid() const = 0; + virtual int32_t GetHandle() const = 0; + virtual int GetSessionId() const = 0; + virtual std::array GetKey() const = 0; + virtual void Release() const = 0; + virtual void DisableSessionListener() const = 0; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // BASE_SESSION_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/devsl_dispatcher.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/devsl_dispatcher.h new file mode 100644 index 00000000..a7895173 --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/devsl_dispatcher.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DEVSL_DISPATCHER_H +#define DEVSL_DISPATCHER_H + +#include +#include +#include +#include +#include +#include "dev_slinfo_mgr.h" +#include "device/device_manager_agent.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class DevslDispatcher final { +public: + DevslDispatcher() = delete; + ~DevslDispatcher() = delete; + static int Start(); + static void Stop(); + static void DevslGottonCallback(DEVSLQueryParams *queryParams, int32_t result, uint32_t levelInfo); + static uint32_t DevslGetRegister(const std::string &cid, std::weak_ptr); +private: + static DEVSLQueryParams MakeDevslQueryParams(const std::string &cid); + static void DevslGottonCallbackAsync(const std::string udid, uint32_t devsl); + static std::map>> talkersMap_; + static std::map idMap_; + static std::mutex mutex; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // DSL_DISPATCHER_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/kernel_talker.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/kernel_talker.h new file mode 100644 index 00000000..bca60883 --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/kernel_talker.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef KERNEL_TALKER_H +#define KERNEL_TALKER_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mountpoint/mount_point.h" +#include "network/base_session.h" +#include "utils_log.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +constexpr int CID_MAX_LEN = 64; +struct NotifyParam { + int32_t notify; + int32_t fd; + char remoteCid[CID_MAX_LEN]; +} __attribute__((packed)); + +class KernelTalker final : protected NoCopyable, public std::enable_shared_from_this { +public: + explicit KernelTalker(std::weak_ptr mountPoint, + std::function getSessionCallback, + std::function closeSessionCallback) + : mountPoint_(mountPoint), GetSessionCallback_(getSessionCallback), CloseSessionCallback_(closeSessionCallback) + { + } + KernelTalker() = default; + ~KernelTalker() = default; + + void SinkSessionTokernel(std::shared_ptr session, const std::string backStage); + void SinkDevslTokernel(const std::string &cid, uint32_t devsl); + void SinkOfflineCmdToKernel(std::string cid); + + void CreatePollThread(); + void WaitForPollThreadExited(); + +private: + template + void SetCmd(T &cmd) + { + auto spt = mountPoint_.lock(); + if (spt == nullptr) { + LOGE("mountPoint is not exist! bad weak_ptr"); + return; + } + std::string ctrlPath = spt->GetMountArgument().GetCtrlPath(); + LOGI("cmd path:%{public}s", ctrlPath.c_str()); + std::lock_guard lock(cmdMutex_); + char resolvedPath[PATH_MAX] = {'\0'}; + char *realPath = realpath(ctrlPath.c_str(), resolvedPath); + if (realPath == nullptr) { + return; + } + + int file = open(realPath, O_RDWR); + if (file < 0) { + LOGE("Open node file error. %{public}d", errno); + return; + } + int err = write(file, &cmd, sizeof(T)); + if (err < 0) { + LOGE("write return err. %{public}d", errno); + } + close(file); + } + + void PollRun(); + void HandleAllNotify(int fd); + void NotifyHandler(NotifyParam ¶m); + + std::weak_ptr mountPoint_; + std::mutex cmdMutex_; + std::atomic isRunning_ {true}; + std::unique_ptr pollThread_ {nullptr}; + std::function GetSessionCallback_ {nullptr}; + std::function CloseSessionCallback_ {nullptr}; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // KERNEL_TALKER_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/network_agent_template.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/network_agent_template.h new file mode 100644 index 00000000..76e108cd --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/network_agent_template.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NETWORK_AGENT_TEMPLATE_H +#define NETWORK_AGENT_TEMPLATE_H + +#include +#include +#include +#include +#include + +#include "device/device_info.h" +#include "dfsu_actor.h" +#include "dfsu_startable.h" +#include "dfsu_thread.h" +#include "mountpoint/mount_point.h" +#include "network/kernel_talker.h" +#include "network/session_pool.h" +#include "network/softbus/softbus_session_dispatcher.h" +#include "nlohmann/json.hpp" +#include "utils_directory.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +constexpr uint8_t LINK_TYPE_AP = 1; +constexpr uint8_t LINK_TYPE_P2P = 2; +constexpr std::string_view GROUP_TYPE_AP = "hmdfs_WifiGroup"; +constexpr std::string_view GROUP_TYPE_P2P = "hmdfs_P2PGroup"; + +class NetworkAgentTemplate : public DfsuStartable, public DfsuActor { +public: + explicit NetworkAgentTemplate(std::weak_ptr mountPoint) + : DfsuActor(this), + mountPoint_(mountPoint), + kernerlTalker_(std::make_shared( + mountPoint, + [&](NotifyParam ¶m) { GetSessionProcess(param); }, + [&](int32_t fd) { CloseSessionForOneDevice(fd); })), + sessionPool_(kernerlTalker_) + { + } + virtual ~NetworkAgentTemplate() {} + void Start(); + void Stop(); + void ConnectOnlineDevices(); + void DisconnectAllDevices(); + void ConnectDeviceAsync(const DeviceInfo info); + void DisconnectDevice(const DeviceInfo info); + void DisconnectDeviceByP2P(const DeviceInfo info); + void DisconnectDeviceByP2PHmdfs(const DeviceInfo info); + void OccupySession(int32_t sessionId, uint8_t linkType); + bool FindSession(int32_t sessionId); + void AcceptSession(std::shared_ptr session, const std::string backStage); + void ConnectDeviceByP2PAsync(const DeviceInfo info); + std::shared_ptr GetMountPoint() + { + return mountPoint_.lock(); + }; +protected: + virtual void JoinDomain() = 0; + virtual void QuitDomain() = 0; + virtual void StopTopHalf() = 0; + virtual void StopBottomHalf() = 0; + virtual int32_t OpenSession(const DeviceInfo &info, const uint8_t &linkType) = 0; + virtual void OpenApSession(const DeviceInfo &info, const uint8_t &linkType) = 0; + virtual void CloseSession(std::shared_ptr session) = 0; + + std::weak_ptr mountPoint_; + +private: + void HandleAllNotify(int fd); + void NotifyHandler(NotifyParam ¶m); + void GetSessionProcess(NotifyParam ¶m); + void GetSession(const std::string &cid, uint8_t linkType); + void CloseSessionForOneDevice(int32_t fd); + void AcceptSessionInner(std::shared_ptr session, const std::string backStage); + void GetSessionProcessInner(NotifyParam param); + + std::mutex taskMut_; + std::list tasks_; + std::shared_ptr kernerlTalker_; + SessionPool sessionPool_; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // NETWORK_AGENT_TEMPLATE_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/session_pool.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/session_pool.h new file mode 100644 index 00000000..877f0def --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/session_pool.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SESSION_POOL_H +#define SESSION_POOL_H + +#include +#include +#include +#include +#include + +#include "network/base_session.h" +#include "network/kernel_talker.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class SessionPool final : protected NoCopyable { +public: + explicit SessionPool(std::shared_ptr &talker) : talker_(talker) {} + ~SessionPool() = default; + void OccupySession(int32_t sessionId, uint8_t linkType); + bool FindSession(int32_t sessionId); + void HoldSession(std::shared_ptr session, const std::string backStage); + uint8_t ReleaseSession(const int32_t fd); + void ReleaseSession(const std::string &cid, const uint8_t linkType); + void ReleaseAllSession(); + bool DeviceConnectCountOnly(std::shared_ptr session); + bool DeviceDisconnectCountOnly(const std::string &cid, const uint8_t linkType, bool needErase); + +private: + std::recursive_mutex sessionPoolLock_; + std::list> usrSpaceSessionPool_; + std::shared_ptr &talker_; + std::map occupySession_; + std::unordered_map deviceConnectCount_; + std::unordered_map deviceIdByCid_; + + void AddSessionToPool(std::shared_ptr session); + std::string GetDeviceIdByCid(const std::string &cid); +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // SESSION_POOL_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_agent.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_agent.h new file mode 100644 index 00000000..69e9ed08 --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_agent.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_AGENT_H +#define SOFTBUS_AGENT_H + +#include +#include + +#include "inner_socket.h" +#include "network/network_agent_template.h" +#include "transport/socket.h" +#include "transport/trans_type.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class SoftbusAgent final : public NetworkAgentTemplate, public std::enable_shared_from_this { +public: + explicit SoftbusAgent(std::weak_ptr mountPoint); + ~SoftbusAgent() = default; + void OnSessionOpened(const int32_t sessionId, PeerSocketInfo info); + void OnSessionClosed(int32_t sessionId, const std::string peerDeviceId); + static bool IsSameAccount(const std::string &networkId); + int32_t JudgeNetworkTypeIsWifi(const DeviceInfo &info); +protected: + void JoinDomain() override; + void QuitDomain() override; + void StopTopHalf() override; + void StopBottomHalf() override; + int32_t OpenSession(const DeviceInfo &info, const uint8_t &linkType) override; + void OpenApSession(const DeviceInfo &info, const uint8_t &linkType) override; + void CloseSession(std::shared_ptr session) override; + +private: + std::mutex serverIdMapMutex_; + std::map serverIdMap_; + bool IsContinueRetry(const std::string &cid); + std::map OpenSessionRetriedTimesMap_; + + std::string sessionName_; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // SOFTBUS_AGENT_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_asset_recv_listener.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_asset_recv_listener.h new file mode 100644 index 00000000..7fe419e6 --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_asset_recv_listener.h @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + */ + +#ifndef FILEMANAGEMENT_DFS_SERVICE_SOFTBUS_ASSET_RECV_LISTENER_H +#define FILEMANAGEMENT_DFS_SERVICE_SOFTBUS_ASSET_RECV_LISTENER_H + +#include +#include +#include +#include + +#include "asset/asset_obj.h" +#include "transport/socket.h" +#include "transport/trans_type.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class SoftbusAssetRecvListener { +public: + static void OnFile(int32_t socket, FileEvent *event); + static const char* GetRecvPath(); + + static void OnRecvAssetStart(int32_t socketId, const char **fileList, int32_t fileCnt); + static void OnRecvAssetFinished(int32_t socketId, const char **fileList, int32_t fileCnt); + static void OnRecvAssetError(int32_t socketId, int32_t errorCode); + + static void OnAssetRecvBind(int32_t sessionId, PeerSocketInfo info); + +private: + static int32_t HandleSingleFile(int32_t socketId, const std::string &filePath, const sptr &assetObj); + static int32_t HandleZipFile(int32_t socketId, const std::string &filePath, const sptr &assetObj); + static bool JudgeSingleFile(const std::string &filePath); + + static int32_t GetCurrentUserId(); + static bool MoveAsset(const std::vector &fileList, bool isSingleFile); + static bool RemoveAsset(const std::string &file); + static inline const std::string SERVICE_NAME{"ohos.storage.distributedfile.daemon"}; + static inline std::string path_; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // FILEMANAGEMENT_DFS_SERVICE_SOFTBUS_ASSET_RECV_LISTENER_H diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_asset_send_listener.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_asset_send_listener.h new file mode 100644 index 00000000..a4f3efee --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_asset_send_listener.h @@ -0,0 +1,40 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef FILEMANAGEMENT_DFS_SERVICE_SOFTBUS_ASSET_SEND_LISTENER_H +#define FILEMANAGEMENT_DFS_SERVICE_SOFTBUS_ASSET_SEND_LISTENER_H + +#include +#include + +#include "transport/socket.h" +#include "transport/trans_type.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class SoftBusAssetSendListener { +public: + static void OnFile(int32_t socket, FileEvent *event); + static void OnSendAssetFinished(int32_t socketId, const char **fileList, int32_t fileCnt); + static void OnSendAssetError(int32_t socketId, const char **fileList, int32_t fileCnt, int32_t errorCode); + static bool isSingleFile_; +private: + static inline const std::string SERVICE_NAME{"ohos.storage.distributedfile.daemon"}; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // FILEMANAGEMENT_DFS_SERVICE_SOFTBUS_ASSET_SEND_LISTENER_H diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_file_receive_listener.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_file_receive_listener.h new file mode 100644 index 00000000..409738c3 --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_file_receive_listener.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FILEMANAGEMENT_DFS_SERVICE_SOFTBUS_FILE_RECEIVE_LISTENER_H +#define FILEMANAGEMENT_DFS_SERVICE_SOFTBUS_FILE_RECEIVE_LISTENER_H + +#include "network/softbus/softbus_session_pool.h" +#include +#include "transport/socket.h" +#include "transport/trans_type.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class SoftBusFileReceiveListener { +public: + static void OnFile(int32_t socket, FileEvent *event); + static void OnReceiveFileStarted(int32_t sessionId, int32_t fileCnt); + static void OnReceiveFileProcess(int32_t sessionId, uint64_t bytesUpload, uint64_t bytesTotal); + static void OnReceiveFileFinished(int32_t sessionId, int32_t fileCnt); + static void OnFileTransError(int32_t sessionId, int32_t errorCode); + static void OnReceiveFileReport(int32_t sessionId, FileStatusList statusList, int32_t errorCode); + static std::string GetLocalSessionName(int32_t socket); + static void SetRecvPath(const std::string &physicalPath); + static const char* GetRecvPath(); + +private: + static inline const std::string SERVICE_NAME{"ohos.storage.distributedfile.daemon"}; + static std::string path_; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // FILEMANAGEMENT_DFS_SERVICE_SOFTBUS_FILE_RECEIVE_LISTENER_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_file_send_listener.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_file_send_listener.h new file mode 100644 index 00000000..fdc89368 --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_file_send_listener.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FILEMANAGEMENT_DFS_SERVICE_SOFTBUS_FILE_SEND_LISTENER_H +#define FILEMANAGEMENT_DFS_SERVICE_SOFTBUS_FILE_SEND_LISTENER_H + +#include +#include +#include "transport/socket.h" +#include "transport/trans_type.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class SoftBusFileSendListener { +public: + static void OnFile(int32_t socket, FileEvent *event); + static void OnSendFileProcess(int32_t sessionId, uint64_t bytesUpload, uint64_t bytesTotal); + static void OnSendFileFinished(int32_t sessionId); + static void OnFileTransError(int32_t sessionId, int32_t errorCode); + static void OnSendFileReport(int32_t sessionId, FileStatusList statusList, int32_t errorCode); + static std::string GetLocalSessionName(int32_t sessionId); + +private: + static inline const std::string SERVICE_NAME{"ohos.storage.distributedfile.daemon"}; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // FILEMANAGEMENT_DFS_SERVICE_SOFTBUS_FILE_SEND_LISTENER_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_handler.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_handler.h new file mode 100644 index 00000000..2fa6fed6 --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_handler.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FILEMANAGEMENT_DFS_SERVICE_SOFTBUS_HANDLER_H +#define FILEMANAGEMENT_DFS_SERVICE_SOFTBUS_HANDLER_H + +#include "transport/socket.h" +#include "transport/trans_type.h" +#include +#include +#include + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +typedef enum { + DFS_CHANNLE_ROLE_SOURCE = 0, + DFS_CHANNLE_ROLE_SINK = 1, +} DFS_CHANNEL_ROLE; +class SoftBusHandler { +public: + SoftBusHandler(); + ~SoftBusHandler(); + static SoftBusHandler &GetInstance(); + int32_t CreateSessionServer(const std::string &packageName, const std::string &sessionName, + DFS_CHANNEL_ROLE role, const std::string physicalPath); + int32_t OpenSession(const std::string &mySessionName, const std::string &peerSessionName, + const std::string &peerDevId, DFS_CHANNEL_ROLE role); + void ChangeOwnerIfNeeded(int32_t sessionId, const std::string sessionName); + void CloseSession(int32_t sessionId, const std::string sessionName); + void CloseSessionWithSessionName(const std::string sessionName); + static std::string GetSessionName(int32_t sessionId); + static void OnSinkSessionOpened(int32_t sessionId, PeerSocketInfo info); + static bool IsSameAccount(const std::string &networkId); + +private: + static std::mutex clientSessNameMapMutex_; + static std::map clientSessNameMap_; + static std::mutex serverIdMapMutex_; + static std::map serverIdMap_; + static inline const std::string SERVICE_NAME{"ohos.storage.distributedfile.daemon"}; + std::map sessionListener_; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS + +#endif // FILEMANAGEMENT_DFS_SERVICE_SOFTBUS_HANDLER_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_handler_asset.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_handler_asset.h new file mode 100644 index 00000000..4668fa18 --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_handler_asset.h @@ -0,0 +1,100 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef FILEMANAGEMENT_DFS_SERVICE_SOFTBUS_HANDLER_ASSET_H +#define FILEMANAGEMENT_DFS_SERVICE_SOFTBUS_HANDLER_ASSET_H + +#include +#include +#include +#include +#include +#include +#include + +#include "asset/asset_obj.h" +#include "third_party/zlib/contrib/minizip/unzip.h" +#include "third_party/zlib/contrib/minizip/zip.h" +#include "transport/socket.h" +#include "transport/trans_type.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +typedef enum { + DFS_ASSET_ROLE_SEND = 0, + DFS_ASSET_ROLE_RECV = 1, +} DFS_ASSET_ROLE; + +class SoftBusHandlerAsset { +public: + SoftBusHandlerAsset(); + ~SoftBusHandlerAsset(); + static SoftBusHandlerAsset &GetInstance(); + void CreateAssetLocalSessionServer(); + void DeleteAssetLocalSessionServer(); + + int32_t AssetBind(const std::string &dstNetworkId, int32_t &socketId); + int32_t AssetSendFile(int32_t socketId, const std::string& sendFile, bool isSingleFile); + void closeAssetBind(int32_t socketId); + void OnAssetRecvBind(int32_t socketId, const std::string &srcNetWorkId); + + std::string GetClientInfo(int32_t socketId); + void RemoveClientInfo(int32_t socketId); + void AddAssetObj(int32_t socketId, const sptr &assetObj); + sptr GetAssetObj(int32_t socketId); + void RemoveAssetObj(int32_t socketId); + + int32_t GenerateAssetObjInfo(int32_t socketId, + const std::string &fileName, + const sptr &assetObj); + std::vector GenerateUris(const std::vector &fileList, + const std::string &dstBundleName, + bool isSingleFile); + int32_t CompressFile(const std::vector &fileList, + const std::string &relativePath, + const std::string &zipFileName); + std::vector DecompressFile(const std::string &unZipFileName, const std::string &relativePath); + bool MkDirRecurse(const std::string& path, mode_t mode); + + void RemoveFile(const std::string &path, bool isRemove = true); +private: + static bool IsSameAccount(const std::string &networkId); + std::string GetDstFile(const std::string &file, + const std::string &srcBundleName, + const std::string &dstBundleName, + const std::string &sessionId, + bool isSingleFile); + std::string GetLocalNetworkId(); + int32_t MkDir(const std::string &path, mode_t mode); + + bool IsDir(const std::string &path); + std::string ExtractFile(unzFile unZipFile, const std::string &dir); + std::mutex clientInfoMutex_; + std::map clientInfoMap_; + std::mutex serverIdMapMutex_; + std::map serverIdMap_; + std::mutex assetObjMapMutex_; + std::map> assetObjMap_; + std::map sessionListener_; + static inline const std::string SERVICE_NAME {"ohos.storage.distributedfile.daemon"}; + static inline const std::string ASSET_LOCAL_SESSION_NAME {"DistributedFileService_assetListener"}; +}; + +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS + +#endif // FILEMANAGEMENT_DFS_SERVICE_SOFTBUS_HANDLER_ASSET_H diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_session.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_session.h new file mode 100644 index 00000000..f5ba899f --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_session.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_SESSION_H +#define SOFTBUS_SESSION_H + +#include +#include +#include +#include "transport/socket.h" +#include "transport/trans_type.h" +#include "network/base_session.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +constexpr int32_t INVALID_SOCKET_FD = -1; +class SoftbusSession final : public BaseSession { +public: + explicit SoftbusSession(int32_t sessionId, std::string peerDeviceId); + ~SoftbusSession() = default; + bool IsFromServer() const override; + std::string GetCid() const override; + int32_t GetHandle() const override; + int GetSessionId() const override; + std::array GetKey() const override; + void Release() const override; + void DisableSessionListener() const override; + +private: + int32_t sessionId_; + std::string cid_; + int32_t socketFd_ {INVALID_SOCKET_FD}; + std::array key_; + bool IsServerSide_ = false; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // SOFTBUS_SESSION_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_session_dispatcher.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_session_dispatcher.h new file mode 100644 index 00000000..bc0dd483 --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_session_dispatcher.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_SESSION_DISPATCHER_H +#define SOFTBUS_SESSION_DISPATCHER_H + +#include +#include +#include +#include +#include +#include "transport/socket.h" +#include "transport/trans_type.h" + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class SoftbusAgent; +class SoftbusSessionDispatcher final { +public: + SoftbusSessionDispatcher() = delete; + ~SoftbusSessionDispatcher() = delete; + static void RegisterSessionListener(const std::string busName, std::weak_ptr); + static void UnregisterSessionListener(const std::string busName); + static std::weak_ptr GetAgent(int32_t sessionId, std::string peerSessionName); + static void OnSessionOpened(int32_t sessionId, PeerSocketInfo info); + static void OnSessionClosed(int32_t sessionId, ShutdownReason reason); + +private: + static std::mutex idMapMutex_; + static std::map> idMap_; + static std::mutex softbusAgentMutex_; + static std::map> busNameToAgent_; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // SOFTBUS_SESSION_DISPATCHER_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_session_listener.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_session_listener.h new file mode 100644 index 00000000..793cda59 --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_session_listener.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef FILEMANAGEMENT_DFS_SERVICE_SOFTBUS_SESSION_LISTENER_H +#define FILEMANAGEMENT_DFS_SERVICE_SOFTBUS_SESSION_LISTENER_H + +#include "softbus_handler.h" +#include "transport/socket.h" +#include "transport/trans_type.h" +#include + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class SoftBusSessionListener { +public: + static void OnSessionOpened(int32_t sessionId, PeerSocketInfo info); + static void OnSessionClosed(int32_t sessionId, ShutdownReason reason); + static std::string GetBundleName(const std::string &uri); + static std::string GetRealPath(const std::string &srcUri); +private: + static int32_t QueryActiveUserId(); + static std::vector GetFileName(const std::vector &fileList, const std::string &path); + static std::string GetSandboxPath(const std::string &uri); + static std::string GetLocalUri(const std::string &uri); +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // FILEMANAGEMENT_DFS_SERVICE_SOFTBUS_SESSION_LISTENER_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_session_name.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_session_name.h new file mode 100644 index 00000000..87d3b4de --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_session_name.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_SESSION_NAME_H +#define SOFTBUS_SESSION_NAME_H + +#include + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class SoftbusSessionName final { +public: + explicit SoftbusSessionName(std::string path) : path_(path) {} + ~SoftbusSessionName() = default; + std::string ToString() + { + return prefix + path_; + } + +private: + const std::string prefix = "DistributedFileService"; + std::string path_; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // SOFTBUS_SESSION_NAME_H \ No newline at end of file diff --git a/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_session_pool.h b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_session_pool.h new file mode 100644 index 00000000..7a814811 --- /dev/null +++ b/mock/innerkits/filemanagement/dfs_service/services/distributedfiledaemon/include/network/softbus/softbus_session_pool.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef FILEMANAGEMENT_DFS_SERVICE_SOFTBUS_SESSION_POOL_H +#define FILEMANAGEMENT_DFS_SERVICE_SOFTBUS_SESSION_POOL_H + +#include +#include +#include +#include + +namespace OHOS { +namespace Storage { +namespace DistributedFile { +class SoftBusSessionPool { +public: + struct SessionInfo { + int sessionId{}; + std::string srcUri; + std::string dstPath; + int uid{}; + }; + + static SoftBusSessionPool &GetInstance(); + std::string GenerateSessionName(); + void AddSessionInfo(const std::string &sessionName, const SessionInfo &sessionInfo); + void DeleteSessionInfo(const std::string &sessionName); + bool GetSessionInfo(const std::string &sessionName, SessionInfo &sessionInfo); + +private: + const std::string SESSION_NAME_PREFIX = "DistributedFileService"; + std::map sessionMap_; + std::mutex sessionMutex_; +}; +} // namespace DistributedFile +} // namespace Storage +} // namespace OHOS +#endif // FILEMANAGEMENT_DFS_SERVICE_SOFTBUS_SESSION_POOL_H \ No newline at end of file diff --git a/mock/innerkits/hisysevent_native/libhisysevent/include/hisysevent_c.h b/mock/innerkits/hisysevent_native/libhisysevent/include/hisysevent_c.h index 94d478f0..62871138 100644 --- a/mock/innerkits/hisysevent_native/libhisysevent/include/hisysevent_c.h +++ b/mock/innerkits/hisysevent_native/libhisysevent/include/hisysevent_c.h @@ -29,31 +29,31 @@ extern "C" { * @brief Define the type of the param. */ enum HiSysEventParamType { - HISYSEVENT_INVALID = 0, - HISYSEVENT_BOOL = 1, - HISYSEVENT_INT8 = 2, - HISYSEVENT_UINT8 = 3, - HISYSEVENT_INT16 = 4, - HISYSEVENT_UINT16 = 5, - HISYSEVENT_INT32 = 6, - HISYSEVENT_UINT32 = 7, - HISYSEVENT_INT64 = 8, - HISYSEVENT_UINT64 = 9, - HISYSEVENT_FLOAT = 10, - HISYSEVENT_DOUBLE = 11, - HISYSEVENT_STRING = 12, - HISYSEVENT_BOOL_ARRAY = 13, - HISYSEVENT_INT8_ARRAY = 14, - HISYSEVENT_UINT8_ARRAY = 15, - HISYSEVENT_INT16_ARRAY = 16, - HISYSEVENT_UINT16_ARRAY = 17, - HISYSEVENT_INT32_ARRAY = 18, - HISYSEVENT_UINT32_ARRAY = 19, - HISYSEVENT_INT64_ARRAY = 20, - HISYSEVENT_UINT64_ARRAY = 21, - HISYSEVENT_FLOAT_ARRAY = 22, - HISYSEVENT_DOUBLE_ARRAY = 23, - HISYSEVENT_STRING_ARRAY = 24 + HISYSEVENT_INVALID = 0, + HISYSEVENT_BOOL = 1, + HISYSEVENT_INT8 = 2, + HISYSEVENT_UINT8 = 3, + HISYSEVENT_INT16 = 4, + HISYSEVENT_UINT16 = 5, + HISYSEVENT_INT32 = 6, + HISYSEVENT_UINT32 = 7, + HISYSEVENT_INT64 = 8, + HISYSEVENT_UINT64 = 9, + HISYSEVENT_FLOAT = 10, + HISYSEVENT_DOUBLE = 11, + HISYSEVENT_STRING = 12, + HISYSEVENT_BOOL_ARRAY = 13, + HISYSEVENT_INT8_ARRAY = 14, + HISYSEVENT_UINT8_ARRAY = 15, + HISYSEVENT_INT16_ARRAY = 16, + HISYSEVENT_UINT16_ARRAY = 17, + HISYSEVENT_INT32_ARRAY = 18, + HISYSEVENT_UINT32_ARRAY = 19, + HISYSEVENT_INT64_ARRAY = 20, + HISYSEVENT_UINT64_ARRAY = 21, + HISYSEVENT_FLOAT_ARRAY = 22, + HISYSEVENT_DOUBLE_ARRAY = 23, + HISYSEVENT_STRING_ARRAY = 24 }; typedef enum HiSysEventParamType HiSysEventParamType; @@ -61,19 +61,19 @@ typedef enum HiSysEventParamType HiSysEventParamType; * @brief Define the value of the param. */ union HiSysEventParamValue { - bool b; - int8_t i8; - uint8_t ui8; - int16_t i16; - uint16_t ui16; - int32_t i32; - uint32_t ui32; - int64_t i64; - uint64_t ui64; - float f; - double d; - char *s; - void *array; + bool b; + int8_t i8; + uint8_t ui8; + int16_t i16; + uint16_t ui16; + int32_t i32; + uint32_t ui32; + int64_t i64; + uint64_t ui64; + float f; + double d; + char *s; + void *array; }; typedef union HiSysEventParamValue HiSysEventParamValue; @@ -81,10 +81,10 @@ typedef union HiSysEventParamValue HiSysEventParamValue; * @brief Define param struct. */ struct HiSysEventParam { - char name[MAX_LENGTH_OF_PARAM_NAME]; - HiSysEventParamType t; - HiSysEventParamValue v; - size_t arraySize; + char name[MAX_LENGTH_OF_PARAM_NAME]; + HiSysEventParamType t; + HiSysEventParamValue v; + size_t arraySize; }; typedef struct HiSysEventParam HiSysEventParam; @@ -92,10 +92,10 @@ typedef struct HiSysEventParam HiSysEventParam; * @brief Event type. */ enum HiSysEventEventType { - HISYSEVENT_FAULT = 1, - HISYSEVENT_STATISTIC = 2, - HISYSEVENT_SECURITY = 3, - HISYSEVENT_BEHAVIOR = 4 + HISYSEVENT_FAULT = 1, + HISYSEVENT_STATISTIC = 2, + HISYSEVENT_SECURITY = 3, + HISYSEVENT_BEHAVIOR = 4 }; typedef enum HiSysEventEventType HiSysEventEventType; diff --git a/mock/innerkits/memmgr/memmgrclient/include/bundle_priority.h b/mock/innerkits/memmgr/memmgrclient/include/bundle_priority.h new file mode 100644 index 00000000..d997f6e1 --- /dev/null +++ b/mock/innerkits/memmgr/memmgrclient/include/bundle_priority.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_MEMORY_MEMMGR_INNERKITS_BUNDLE_INFO_H +#define OHOS_MEMORY_MEMMGR_INNERKITS_BUNDLE_INFO_H + +#include + +#include "parcel.h" + +namespace OHOS { +namespace Memory { +class BundlePriority { +public: + BundlePriority(); + BundlePriority(int32_t uid, std::string name, int32_t priority, int32_t accountId) : uid_(uid), name_(name), + priority_(priority), accountId_(accountId) {}; + int32_t uid_ {0}; + std::string name_ {""}; + int32_t priority_ {0}; + int32_t accountId_ {0}; +}; +} // namespace Memory +} // namespace OHOS +#endif // OHOS_MEMORY_MEMMGR_INNERKITS_BUNDLE_INFO_H diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/include/auto_sync_timer.h b/mock/innerkits/memmgr/memmgrclient/include/bundle_priority_list.h similarity index 35% rename from kv_store/frameworks/innerkitsimpl/kvdb/include/auto_sync_timer.h rename to mock/innerkits/memmgr/memmgrclient/include/bundle_priority_list.h index 89924b2b..4acf5b20 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/include/auto_sync_timer.h +++ b/mock/innerkits/memmgr/memmgrclient/include/bundle_priority_list.h @@ -12,37 +12,38 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef SDB_AUTO_SYNC_TIMER_H -#define SDB_AUTO_SYNC_TIMER_H -#include -#include -#include "concurrent_map.h" -#include "kvdb_service.h" -#include "task_executor.h" -namespace OHOS::DistributedKv { -class AutoSyncTimer { +#ifndef OHOS_MEMORY_MEMMGR_INNERKITS_BUNDLE_PRIORITY_LIST_H +#define OHOS_MEMORY_MEMMGR_INNERKITS_BUNDLE_PRIORITY_LIST_H + +#include "bundle_priority.h" +#include "parcel.h" + +namespace OHOS { +namespace Memory { +class BundlePriorityList : public Parcelable { public: - static constexpr uint32_t FORCE_SYNC_INTERVAL = 200; - static constexpr uint32_t AUTO_SYNC_INTERVAL = 50; - static AutoSyncTimer &GetInstance(); - void DoAutoSync(const std::string &appId, std::set storeIds); + /** + * @brief Marshals a purpose into a parcel. + * + * @param parcel Indicates the parcel object for marshalling. + * @return True if success, else false. + */ + bool Marshalling(Parcel &parcel) const; + static BundlePriorityList *Unmarshalling(Parcel &parcel); + int32_t GetCount() const; + void SetCount(int32_t count); + const std::vector& GetList(); + int32_t Size() const; + void AddBundleInfo(BundlePriority &bundleInfo); + void Show() const; private: - static constexpr size_t TIME_TASK_NUM = 5; - static constexpr size_t SYNC_STORE_NUM = 10; - AutoSyncTimer() = default; - ~AutoSyncTimer() = default; - std::map> GetStoreIds(); - std::function ProcessTask() __attribute__((no_sanitize("cfi"))); - void StartTimer(); - void StopTimer(); - void AddSyncStores(const std::string &appId, std::set storeIds); - bool HasSyncStores(); - ConcurrentMap> stores_; - TaskExecutor::TaskId delaySyncTaskId_; - TaskExecutor::TaskId forceSyncTaskId_; - std::mutex mutex_; + bool ReadFromParcel(Parcel &parcel); + + int32_t count_ {0}; + std::vector list_; }; -} // namespace OHOS::DistributedKv -#endif // SDB_AUTO_SYNC_TIMER_H +} // namespace Memory +} // namespace OHOS +#endif // OHOS_MEMORY_MEMMGR_INNERKITS_BUNDLE_PRIORITY_LIST_H diff --git a/mock/innerkits/memmgr/memmgrclient/include/i_mem_mgr.h b/mock/innerkits/memmgr/memmgrclient/include/i_mem_mgr.h index e37a4004..4388f569 100644 --- a/mock/innerkits/memmgr/memmgrclient/include/i_mem_mgr.h +++ b/mock/innerkits/memmgr/memmgrclient/include/i_mem_mgr.h @@ -1,40 +1,52 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +* Copyright (c) 2022 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ #ifndef OHOS_MEMORY_MEMMGR_INTERFACES_INNERKITS_INCLUDE_MEM_MGR_INTERFACE_H #define OHOS_MEMORY_MEMMGR_INTERFACES_INNERKITS_INCLUDE_MEM_MGR_INTERFACE_H #include + +#include "bundle_priority_list.h" #include "iremote_broker.h" #include "iremote_object.h" -#include "bundle_priority_list.h" +#include "iremote_proxy.h" +#include "mem_mgr_process_state_info.h" +#include "mem_mgr_window_info.h" +//#include "memmgrservice_ipc_interface_code.h" +#ifdef USE_PURGEABLE_MEMORY +#include "iapp_state_subscriber.h" +#endif namespace OHOS { namespace Memory { class IMemMgr : public IRemoteBroker { public: - DECLARE_INTERFACE_DESCRIPTOR(u"ohos.memory.MemMgr"); + DECLARE_INTERFACE_DESCRIPTOR(u"ohos.memory.MemMgr"); + + virtual int32_t GetBundlePriorityList(BundlePriorityList &bundlePrioList) = 0; - virtual int32_t GetBundlePriorityList(BundlePriorityList &bundlePrioList) = 0; + virtual int32_t NotifyDistDevStatus(int32_t pid, int32_t uid, const std::string &name, bool connected) = 0; - virtual int32_t NotifyDistDevStatus(int32_t pid, int32_t uid, const std::string &name, bool connected) = 0; + virtual int32_t GetKillLevelOfLmkd(int32_t &killLevel) = 0; - enum { - MEM_MGR_GET_BUNDLE_PRIORITY_LIST = 1, - MEM_MGR_NOTIFY_DIST_DEV_STATUS = 2, - }; + virtual int32_t OnWindowVisibilityChanged(const std::vector> &MemMgrWindowInfo) = 0; + virtual int32_t GetReclaimPriorityByPid(int32_t pid, int32_t &priority) = 0; + virtual int32_t NotifyProcessStateChangedSync(const MemMgrProcessStateInfo &processStateInfo) = 0; + virtual int32_t NotifyProcessStateChangedAsync(const MemMgrProcessStateInfo &processStateInfo) = 0; + virtual int32_t NotifyProcessStatus(int32_t pid, int32_t type, int32_t status, int saId = -1) = 0; + virtual int32_t SetCritical(int32_t pid, bool critical, int32_t saId = -1) = 0; }; } // namespace Memory } // namespace OHOS diff --git a/mock/innerkits/memmgr/memmgrclient/include/mem_mgr_client.h b/mock/innerkits/memmgr/memmgrclient/include/mem_mgr_client.h index b45ee6f3..2e221478 100644 --- a/mock/innerkits/memmgr/memmgrclient/include/mem_mgr_client.h +++ b/mock/innerkits/memmgr/memmgrclient/include/mem_mgr_client.h @@ -1,24 +1,30 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +* Copyright (c) 2022 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ #ifndef OHOS_MEMORY_MEMMGR_INTERFACES_INNERKITS_INCLUDE_MEM_MGR_CLIENT_H #define OHOS_MEMORY_MEMMGR_INTERFACES_INNERKITS_INCLUDE_MEM_MGR_CLIENT_H +//#include "app_state_subscriber.h" #include "i_mem_mgr.h" #include "single_instance.h" +extern "C" { +int32_t notify_process_status(int32_t pid, int32_t type, int32_t status, int saId = -1); +int32_t set_critical(int32_t pid, bool critical, int32_t saId = -1); +} + namespace OHOS { namespace Memory { class MemMgrClient { @@ -27,6 +33,19 @@ class MemMgrClient { public: int32_t GetBundlePriorityList(BundlePriorityList &bundlePrioList); int32_t NotifyDistDevStatus(int32_t pid, int32_t uid, const std::string &name, bool connected); + int32_t GetKillLevelOfLmkd(int32_t &killLevel); + int32_t RegisterActiveApps(int32_t pid, int32_t uid); + int32_t DeregisterActiveApps(int32_t pid, int32_t uid); + int32_t GetAvailableMemory(int32_t &memSize); + int32_t GetTotalMemory(int32_t &memSize); + int32_t GetAvailableMemory(); + int32_t GetTotalMemory(); + int32_t OnWindowVisibilityChanged(const std::vector> &MemMgrWindowInfo); + int32_t GetReclaimPriorityByPid(int32_t pid, int32_t &priority); + int32_t NotifyProcessStateChangedSync(const MemMgrProcessStateInfo &processStateInfo); + int32_t NotifyProcessStateChangedAsync(const MemMgrProcessStateInfo &processStateInfo); + int32_t NotifyProcessStatus(int32_t pid, int32_t type, int32_t status, int saId = -1); + int32_t SetCritical(int32_t pid, bool critical, int32_t saId = -1); private: sptr GetMemMgrService(); diff --git a/mock/innerkits/memmgr/memmgrclient/include/mem_mgr_process_state_info.h b/mock/innerkits/memmgr/memmgrclient/include/mem_mgr_process_state_info.h new file mode 100644 index 00000000..ab8ceb51 --- /dev/null +++ b/mock/innerkits/memmgr/memmgrclient/include/mem_mgr_process_state_info.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_MEMORY_MEMMGR_INNERKITS_MEM_MGR_PROCESS_STATE_INFO_H +#define OHOS_MEMORY_MEMMGR_INNERKITS_MEM_MGR_PROCESS_STATE_INFO_H + +#include +namespace OHOS { +namespace Memory { +enum class ProcPriorityUpdateReason : uint32_t { + START_ABILITY = 0, + UNKNOWN, +}; + +/** + * @class MemMgrProcessStateInfo + * + * @brief State info of process. + */ +class MemMgrProcessStateInfo : public Parcelable { +public: + /** + * @brief Default construct of MemMgrProcessStateInfo. + */ + MemMgrProcessStateInfo() = default; + /** + * @brief Construct of MemMgrProcessStateInfo. + * + * @param callerPid Process id of caller process. + * @param callerUid User id of caller process. + * @param pid Process id. + * @param uid User id. + * @param reason Reason of update process priority. + */ + MemMgrProcessStateInfo(int32_t callerPid, int32_t callerUid, int32_t pid, int32_t uid, + ProcPriorityUpdateReason reason) + : callerPid_(callerPid), callerUid_(callerUid), pid_(pid), uid_(uid), reason_(reason) {}; + /** + * @brief Deconstruct of MemMgrProcessStateInfo. + */ + ~MemMgrProcessStateInfo() = default; + + /** + * @brief Marshalling MemMgrProcessStateInfo. + * + * @param parcel Package of MemMgrProcessStateInfo. + * @return True means marshall success, false means marshall failed. + */ + virtual bool Marshalling(Parcel &parcel) const override; + /** + * @brief Unmarshalling MemMgrProcessStateInfo. + * + * @param parcel Package of MemMgrProcessStateInfo. + * @return MemMgrProcessStateInfo object. + */ + static MemMgrProcessStateInfo* Unmarshalling(Parcel &parcel); + + int32_t callerPid_ {0}; + int32_t callerUid_ {0}; + int32_t pid_ {0}; + int32_t uid_ {0}; + ProcPriorityUpdateReason reason_ = ProcPriorityUpdateReason::UNKNOWN; +}; +} // namespace Memory +} // namespace OHOS +#endif // OHOS_MEMORY_MEMMGR_INNERKITS_MEM_MGR_PROCESS_STATE_INFO_H \ No newline at end of file diff --git a/mock/innerkits/memmgr/memmgrclient/include/mem_mgr_proxy.h b/mock/innerkits/memmgr/memmgrclient/include/mem_mgr_proxy.h index e31b9500..aa337448 100644 --- a/mock/innerkits/memmgr/memmgrclient/include/mem_mgr_proxy.h +++ b/mock/innerkits/memmgr/memmgrclient/include/mem_mgr_proxy.h @@ -26,8 +26,12 @@ public: ~MemMgrProxy() = default; int32_t GetBundlePriorityList(BundlePriorityList &bundlePrioList) override; int32_t NotifyDistDevStatus(int32_t pid, int32_t uid, const std::string &name, bool connected) override; -private: - static inline BrokerDelegator delegator_; + int32_t GetKillLevelOfLmkd(int32_t &killLevel) override; + int32_t GetReclaimPriorityByPid(int32_t pid, int32_t &priority) override; + int32_t NotifyProcessStateChangedSync(const MemMgrProcessStateInfo &processStateInfo) override; + int32_t NotifyProcessStateChangedAsync(const MemMgrProcessStateInfo &processStateInfo) override; + int32_t NotifyProcessStatus(int32_t pid, int32_t type, int32_t status, int saId) override; + int32_t SetCritical(int32_t pid, bool critical, int32_t saId) override; }; } // namespace Memory } // namespace OHOS diff --git a/mock/innerkits/memmgr/memmgrclient/include/mem_mgr_window_info.h b/mock/innerkits/memmgr/memmgrclient/include/mem_mgr_window_info.h new file mode 100644 index 00000000..ce9aaf66 --- /dev/null +++ b/mock/innerkits/memmgr/memmgrclient/include/mem_mgr_window_info.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_MEMORY_MEMMGR_INNERKITS_MEM_MGR_WINDOW_INFO_H +#define OHOS_MEMORY_MEMMGR_INNERKITS_MEM_MGR_WINDOW_INFO_H + +#include +namespace OHOS { +namespace Memory { +constexpr int INVALID_WINDOW_ID = 0; +/** + * @class MemMgrWindowInfo + * + * @brief Visibility info of window. + */ +class MemMgrWindowInfo : public Parcelable { +public: + /** + * @brief Default construct of MemMgrWindowInfo. + */ + MemMgrWindowInfo() = default; + /** + * @brief Construct of MemMgrWindowInfo. + * + * @param winId Window id. + * @param pid Process id. + * @param uid User id. + * @param visibility True means window is visible, false means the opposite. + */ + MemMgrWindowInfo(uint32_t winId, int32_t pid, int32_t uid, bool visibility) + : windowId_(winId), pid_(pid), uid_(uid), isVisible_(visibility) {}; + /** + * @brief Deconstruct of MemMgrWindowInfo. + */ + ~MemMgrWindowInfo() = default; + + /** + * @brief Marshalling MemMgrWindowInfo. + * + * @param parcel Package of MemMgrWindowInfo. + * @return True means marshall success, false means marshall failed. + */ + virtual bool Marshalling(Parcel &parcel) const override; + /** + * @brief Unmarshalling MemMgrWindowInfo. + * + * @param parcel Package of MemMgrWindowInfo. + * @return MemMgrWindowInfo object. + */ + static MemMgrWindowInfo* Unmarshalling(Parcel &parcel); + + uint32_t windowId_ {INVALID_WINDOW_ID}; + int32_t pid_ {0}; + int32_t uid_ {0}; + bool isVisible_ {false}; +}; +} // namespace Memory +} // namespace OHOS +#endif // OHOS_MEMORY_MEMMGR_INNERKITS_MEM_MGR_WINDOW_INFO_H \ No newline at end of file diff --git a/mock/innerkits/memmgr/memmgrclient/include/single_instance.h b/mock/innerkits/memmgr/memmgrclient/include/single_instance.h new file mode 100644 index 00000000..c0395d1c --- /dev/null +++ b/mock/innerkits/memmgr/memmgrclient/include/single_instance.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_MEMORY_MEMMGR_COMMON_INCLUDE_SINGLE_INSTANCE_H +#define OHOS_MEMORY_MEMMGR_COMMON_INCLUDE_SINGLE_INSTANCE_H + +namespace OHOS { +namespace MemMgr { +#define DECLARE_SINGLE_INSTANCE_BASE(className) \ +public: \ + static className& GetInstance(); \ +private: \ + className(const className&) = delete; \ + className& operator= (const className&) = delete; \ + className(className&&) = delete; \ + className& operator= (className&&) = delete; \ + +#define DECLARE_SINGLE_INSTANCE(className) \ + DECLARE_SINGLE_INSTANCE_BASE(className) \ +private: \ + className() = default; \ + ~className() = default; \ + +#define IMPLEMENT_SINGLE_INSTANCE(className) \ +className& className::GetInstance() \ +{ \ + static auto instance = new className(); \ + return *instance; \ +} +} // namespace MemMgr +} // namespace OHOS +#endif // OHOS_MEMORY_MEMMGR_COMMON_INCLUDE_SINGLE_INSTANCE_H diff --git a/mock/innerkits/os_account/libaccountkits/include/account_info.h b/mock/innerkits/os_account/libaccountkits/include/account_info.h index bebf1dc2..ed9db837 100644 --- a/mock/innerkits/os_account/libaccountkits/include/account_info.h +++ b/mock/innerkits/os_account/libaccountkits/include/account_info.h @@ -75,6 +75,10 @@ public: { status_ = ACCOUNT_STATE_UNBOUND; } + std::string GetRawUid() + { + return uid_; + } ~OhosAccountInfo() {}; }; diff --git a/mock/innerkits/os_account/libaccountkits/include/ohos_account_kits.h b/mock/innerkits/os_account/libaccountkits/include/ohos_account_kits.h index 40e292b8..0922f847 100644 --- a/mock/innerkits/os_account/libaccountkits/include/ohos_account_kits.h +++ b/mock/innerkits/os_account/libaccountkits/include/ohos_account_kits.h @@ -1,84 +1,164 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +* Copyright (c) 2021-2023 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** +* @addtogroup OhosAccount +* @{ +* +* @brief Provides ohos account management. +* +* Provides the capability to manage ohos accounts. +* +* @since 7.0 +* @version 7.0 +*/ + +/** +* @file ohos_account_kits.h +* +* @brief Declares ohos account interfaces. +* +* @since 7.0 +* @version 7.0 +*/ #ifndef BASE_ACCOUNT_OHOS_ACCOUNT_KITS_H #define BASE_ACCOUNT_OHOS_ACCOUNT_KITS_H +#include "account_info.h" +//#include "distributed_account_subscribe_callback.h" #include "nocopyable.h" -#include "iaccount.h" namespace OHOS { namespace AccountSA { /** - * Interfaces for ohos account subsystem. - */ +* Interfaces for ohos account subsystem. +*/ class OhosAccountKits { public: virtual ~OhosAccountKits() = default; DISALLOW_COPY_AND_MOVE(OhosAccountKits); /** - * Get instance of ohos account manager. - * - * @return Instance of ohos account manager. - */ - static OhosAccountKits& GetInstance(); + * Get instance of ohos account manager. + * + * @return Instance of ohos account manager. + */ + static OhosAccountKits &GetInstance(); /** - * Query OHOS Account Info. - * - * @param VOID. - * @return Return a pair of operation result and ohos account info. - */ + * Query OHOS Account Info. + * + * @param VOID. + * @return Return a pair of operation result and ohos account info. + */ virtual std::pair QueryOhosAccountInfo() = 0; /** - * Query OHOS Account Info By user ID. - * - * @param userId. target local user id - * @return Return a pair of operation result and ohos account info. - */ + * Query OHOS Account Info. + * + * @param OhosAccountInfo. ohos account info + * @return Return error code. + */ + virtual int32_t GetOhosAccountInfo(OhosAccountInfo &accountInfo) = 0; + + /** + * Get OHOS account info by user id. + * + * @param OhosAccountInfo. ohos account info + * @return Return error code. + */ + virtual int32_t GetOhosAccountInfoByUserId(int32_t userId, OhosAccountInfo &accountInfo) = 0; + + /** + * Query OHOS Account Info By user ID. + * + * @param userId. target local user id + * @return Return a pair of operation result and ohos account info. + */ virtual std::pair QueryOhosAccountInfoByUserId(std::int32_t userId) = 0; /** - * Update OHOS Account Info. - * - * @param accountName Indicates the name of the OS account used for a distributed system. - * @param uid Uniquely identifies the OS account used for a distributed system. - * @param eventStr Indicates the event of the OS account used for a distributed system. - * @return Returns {@code true} if the distributed information of the account is updated; - * returns {@code false} otherwise. - */ - virtual bool UpdateOhosAccountInfo(const std::string& accountName, const std::string& uid, - const std::string& eventStr) = 0; + * Update OHOS Account Info. + * + * @param accountName Indicates the name of the OS account used for a distributed system. + * @param uid Uniquely identifies the OS account used for a distributed system. + * @param eventStr Indicates the event of the OS account used for a distributed system. + * @return Returns {@code true} if the distributed information of the account is updated; + * returns {@code false} otherwise. + */ + virtual bool UpdateOhosAccountInfo(const std::string &accountName, const std::string &uid, + const std::string &eventStr) = 0; /** - * Query Device Account Id. - * - * @param device account id. - * @return if succeed, return ERR_OK and device account Id. - */ - virtual ErrCode QueryDeviceAccountId(std::int32_t& accountId) = 0; + * Update OHOS Account Info. + * + * @param ohosAccountInfo Indicates the information of the distributed account. + * Update OHOS Account Info. + * @param eventStr Indicates the event of the OS account used for a distributed system. + * @return Returns {@code true} if the distributed information of the account is updated; + * returns {@code false} otherwise. + */ + virtual std::int32_t SetOhosAccountInfo(const OhosAccountInfo &ohosAccountInfo, const std::string &eventStr) = 0; /** - * Transform uid to device account id. - * - * @param process calling uid. - * @return transformed device account Id - */ - virtual std::int32_t GetDeviceAccountIdByUID(std::int32_t& uid) = 0; + * Sets OHOS Account Info. + * + * @param userId target local account id. + * @param ohosAccountInfo Indicates the information of the distributed account. + * Update OHOS Account Info. + * @param eventStr Indicates the event of the OS account used for a distributed system. + * @return Returns {@code true} if the distributed information of the account is updated; + * returns {@code false} otherwise. + */ + virtual int32_t SetOhosAccountInfoByUserId(const int32_t userId, const OhosAccountInfo &ohosAccountInfo, + const std::string &eventStr) = 0; + + /** + * Query Device Account Id. + * + * @param device account id. + * @return if succeed, return ERR_OK and device account Id. + */ + virtual int32_t QueryDeviceAccountId(std::int32_t &accountId) = 0; + + /** + * Transform uid to device account id. + * + * @param process calling uid. + * @return transformed device account Id + */ + virtual std::int32_t GetDeviceAccountIdByUID(std::int32_t &uid) = 0; + +// /** +// * @brief Subscribes the event of a distributed account by type and callback. +// * @param type subscribe type +// * @param callback subscribe callback +// * @return error code, see account_error_no.h +// */ +// virtual int32_t SubscribeDistributedAccountEvent(const DISTRIBUTED_ACCOUNT_SUBSCRIBE_TYPE type, +// const std::shared_ptr &callback) = 0; +// +// /** +// * @brief Unsubscribes the event of a distributed account by type and callback. +// * @param type subscribe type +// * @param callback subscribe callback +// * @return error code, see account_error_no.h +// */ +// virtual int32_t UnsubscribeDistributedAccountEvent(const DISTRIBUTED_ACCOUNT_SUBSCRIBE_TYPE type, +// const std::shared_ptr &callback) = 0; + protected: OhosAccountKits() = default; }; diff --git a/mock/src/mock_access_token.cpp b/mock/src/mock_access_token.cpp index 45998cdf..88e283f4 100644 --- a/mock/src/mock_access_token.cpp +++ b/mock/src/mock_access_token.cpp @@ -15,26 +15,11 @@ #include "accesstoken_kit.h" #include "nativetoken_kit.h" #include "token_setproc.h" -static constexpr const char *BundleNames[6] = { - "invalid", - "com.huawei.ohos.toteweather", - "com.ohos.kvdatamanager.test", - "ohos.test.demo", - "ohos.test.demo1", - "ohos.test.demo2" -}; -static constexpr const char *AppId[4] = { - "invalid", - "com.huawei.toteweather_adfasdflaskdfasdf", - "", - "ohos.test.demo_ABSEED" -}; -static constexpr const char *NativeName[4] = { - "invalid", - "foundation", - "distributed_test", - "msdp_sa" -}; +static constexpr const char *BundleNames[6] = { "invalid", "com.huawei.ohos.toteweather", + "com.ohos.kvdatamanager.test", "ohos.test.demo", "ohos.test.demo1", "ohos.test.demo2" }; +static constexpr const char *AppId[4] = { "invalid", "com.huawei.toteweather_adfasdflaskdfasdf", "", + "ohos.test.demo_ABSEED" }; +static constexpr const char *NativeName[4] = { "invalid", "foundation", "distributed_test", "msdp_sa" }; namespace OHOS::Security::AccessToken { ATokenTypeEnum AccessTokenKit::GetTokenTypeFlag(AccessTokenID tokenID) { @@ -47,7 +32,7 @@ int AccessTokenKit::VerifyAccessToken(AccessTokenID tokenID, const std::string & return PERMISSION_GRANTED; } -int AccessTokenKit::GetNativeTokenInfo(AccessTokenID tokenID, NativeTokenInfo& nativeTokenInfoRes) +int AccessTokenKit::GetNativeTokenInfo(AccessTokenID tokenID, NativeTokenInfo &nativeTokenInfoRes) { AccessTokenIDInner *inner = (AccessTokenIDInner *)&tokenID; nativeTokenInfoRes.tokenID = tokenID; @@ -55,7 +40,7 @@ int AccessTokenKit::GetNativeTokenInfo(AccessTokenID tokenID, NativeTokenInfo& n return 0; } -AccessTokenID AccessTokenKit::GetNativeTokenId(const std::string& processName) +AccessTokenID AccessTokenKit::GetNativeTokenId(const std::string &processName) { uint32_t tokenId = 0; auto *inner = (AccessTokenIDInner *)&tokenId; @@ -83,13 +68,13 @@ int AccessTokenKit::GetHapTokenInfo(AccessTokenID tokenID, HapTokenInfo &hapToke inner->tokenUniqueID >= sizeof(AppId) / sizeof(AppId[0])) { return -1; } - hapTokenInfoRes.bundleName = BundleNames[inner->tokenUniqueID % sizeof(BundleNames)/sizeof(BundleNames[0])]; - hapTokenInfoRes.appID = AppId[inner->tokenUniqueID % sizeof(AppId)/sizeof(AppId[0])]; + hapTokenInfoRes.bundleName = BundleNames[inner->tokenUniqueID % sizeof(BundleNames) / sizeof(BundleNames[0])]; + hapTokenInfoRes.appID = AppId[inner->tokenUniqueID % sizeof(AppId) / sizeof(AppId[0])]; } return 0; } -AccessTokenID AccessTokenKit::GetHapTokenID(int userID, const std::string& bundleName, int instIndex) +AccessTokenID AccessTokenKit::GetHapTokenID(int userID, const std::string &bundleName, int instIndex) { uint32_t tokenId = 0; auto *inner = (AccessTokenIDInner *)&tokenId; @@ -136,7 +121,7 @@ AccessTokenIDEx AccessTokenKit::GetHapTokenIDEx(int32_t userID, const std::strin AccessTokenIDEx result; return result; } -} +} // namespace OHOS::Security::AccessToken uint64_t GetAccessTokenId(NativeTokenInfoParams *params) { @@ -157,6 +142,10 @@ uint64_t GetAccessTokenId(NativeTokenInfoParams *params) } int SetSelfTokenID(uint64_t tokenID) +{ + return 0; +} +uint64_t GetSelfTokenID() { return 0; } \ No newline at end of file diff --git a/mock/src/mock_account.cpp b/mock/src/mock_account.cpp index 374cf208..89c8f8cb 100644 --- a/mock/src/mock_account.cpp +++ b/mock/src/mock_account.cpp @@ -14,16 +14,23 @@ */ #include "ohos_account_kits.h" #include "os_account_manager.h" +#include "account_info.h" +namespace OHOS::AccountSA { class OhosAccountKitsImpl : public OHOS::AccountSA::OhosAccountKits { public: std::pair QueryOhosAccountInfo() override; bool UpdateOhosAccountInfo(const std::string& accountName, const std::string& uid, const std::string& eventStr) override; - OHOS::ErrCode QueryDeviceAccountId(int32_t& accountId) override; + int32_t QueryDeviceAccountId(std::int32_t &accountId) override; int32_t GetDeviceAccountIdByUID(int32_t& uid) override; + int32_t GetOhosAccountInfoByUserId(int32_t userId, OhosAccountInfo &accountInfo) override; std::pair QueryOhosAccountInfoByUserId(std::int32_t userId) override; + ~OhosAccountKitsImpl() override = default; + int32_t GetOhosAccountInfo(OhosAccountInfo &accountInfo) override; + int32_t SetOhosAccountInfo(const OhosAccountInfo &ohosAccountInfo, const std::string &eventStr) override; + int32_t SetOhosAccountInfoByUserId(const int32_t userId, const OhosAccountInfo &ohosAccountInfo, + const std::string &eventStr) override; }; -namespace OHOS::AccountSA { OhosAccountKits& OhosAccountKits::GetInstance() { static OhosAccountKitsImpl instance; @@ -56,7 +63,10 @@ ErrCode OsAccountManager::GetForegroundOsAccounts(std::vector OhosAccountKitsImpl::QueryOhosAccountInfo() { return std::pair(); @@ -66,16 +76,34 @@ bool OhosAccountKitsImpl::UpdateOhosAccountInfo(const std::string& accountName, { return false; } -OHOS::ErrCode OhosAccountKitsImpl::QueryDeviceAccountId(int32_t& accountId) -{ - return 0; -} int32_t OhosAccountKitsImpl::GetDeviceAccountIdByUID(int32_t& uid) { return 0; } -std::pair OhosAccountKitsImpl::QueryOhosAccountInfoByUserId(std::int32_t userId) +std::pair OhosAccountKitsImpl::QueryOhosAccountInfoByUserId(std::int32_t userId) { return std::pair(); } +ErrCode OhosAccountKitsImpl::GetOhosAccountInfo(OhosAccountInfo &accountInfo) +{ + return 0; +} +int32_t OhosAccountKitsImpl::SetOhosAccountInfo(const OhosAccountInfo &ohosAccountInfo, const std::string &eventStr) +{ + return 0; +} +ErrCode OhosAccountKitsImpl::SetOhosAccountInfoByUserId(const int32_t userId, const OhosAccountInfo &ohosAccountInfo, + const std::string &eventStr) +{ + return 0; +} +int32_t OhosAccountKitsImpl::QueryDeviceAccountId(int32_t &accountId) +{ + return 0; +} +int32_t OhosAccountKitsImpl::GetOhosAccountInfoByUserId(int32_t userId, OhosAccountInfo &accountInfo) +{ + return 0; +} +} // namespace OHOS::AccountSA diff --git a/mock/src/mock_dms.cpp b/mock/src/mock_dms.cpp index 39426184..2d4350c8 100644 --- a/mock/src/mock_dms.cpp +++ b/mock/src/mock_dms.cpp @@ -40,5 +40,10 @@ int32_t DmsHandler::GetContinueInfo(ContinueInfo &continueInfo) { return 0; } + +int32_t DmsHandler::GetDSchedEventInfo(const DSchedEventType &type, std::vector &events) +{ + return 0; +} } // namespace DistributedSchedule } // namespace OHOS \ No newline at end of file diff --git a/mock/src/mock_filemanagement.cpp b/mock/src/mock_filemanagement.cpp index c92ead90..8d26d86b 100644 --- a/mock/src/mock_filemanagement.cpp +++ b/mock/src/mock_filemanagement.cpp @@ -1,22 +1,112 @@ +#include "distributed_file_daemon_manager.h" +#include "distributed_file_daemon_manager_impl.h" #include "remote_file_share.h" +#include "asset/asset_recv_callback_stub.h" +#include "asset/asset_send_callback_stub.h" +#include "asset/asset_obj.h" namespace OHOS { namespace AppFileService { namespace ModuleRemoteFileShare { -int RemoteFileShare::CreateSharePath(const int& fd, std::string& sharePath, const int& userId, - const std::string& deviceId) +int RemoteFileShare::CreateSharePath(const int &fd, std::string &sharePath, const int &userId, + const std::string &deviceId) { return 0; } -int32_t RemoteFileShare::GetDfsUriFromLocal(const std::string& uriStr, const int32_t& userId, HmdfsUriInfo& hui) +int32_t RemoteFileShare::GetDfsUriFromLocal(const std::string &uriStr, const int32_t &userId, HmdfsUriInfo &hui) { return 0; } -int32_t RemoteFileShare::GetDfsUrisFromLocal(const std::vector& uriList, const int32_t& userId, - std::unordered_map& uriToDfsUriMaps) +int32_t RemoteFileShare::GetDfsUrisFromLocal(const std::vector &uriList, const int32_t &userId, + std::unordered_map &uriToDfsUriMaps) { return 0; } } // namespace ModuleRemoteFileShare } // namespace AppFileService +namespace Storage { +namespace DistributedFile { + +int32_t AssetRecvCallbackStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) +{ + return 0; +} +AssetRecvCallbackStub::AssetRecvCallbackStub() {} +int32_t AssetSendCallbackStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) +{ + return 0; +} +AssetSendCallbackStub::AssetSendCallbackStub() {} +int32_t DistributedFileDaemonManagerImpl::CloseP2PConnection(const DistributedHardware::DmDeviceInfo &deviceInfo) +{ + return 0; +} +DistributedFileDaemonManagerImpl &DistributedFileDaemonManagerImpl::GetInstance() +{ + static DistributedFileDaemonManagerImpl manager; + return manager; +} +int32_t DistributedFileDaemonManagerImpl::OpenP2PConnection(const DistributedHardware::DmDeviceInfo &deviceInfo) +{ + return 0; +} +int32_t DistributedFileDaemonManagerImpl::RequestSendFile(const std::string &srcUri, const std::string &dstPath, + const std::string &remoteDeviceId, const std::string &sessionName) +{ + return 0; +} +int32_t DistributedFileDaemonManagerImpl::OpenP2PConnectionEx(const std::string &networkId, + sptr remoteReverseObj) +{ + return 0; +} +int32_t DistributedFileDaemonManagerImpl::CloseP2PConnectionEx(const std::string &networkId) +{ + return 0; +} +int32_t DistributedFileDaemonManagerImpl::PrepareSession(const std::string &srcUri, const std::string &dstUri, + const std::string &srcDeviceId, const sptr &listener, HmdfsInfo &info) +{ + return 0; +} +int32_t DistributedFileDaemonManagerImpl::CancelCopyTask(const std::string &sessionName) +{ + return 0; +} +int32_t DistributedFileDaemonManagerImpl::GetRemoteCopyInfo(const std::string &srcUri, bool &isFile, bool &isDir) +{ + return 0; +} +int32_t DistributedFileDaemonManagerImpl::PushAsset(int32_t userId, const sptr &assetObj, + const sptr &sendCallback) +{ + return 0; +} +int32_t DistributedFileDaemonManagerImpl::RegisterAssetCallback(const sptr &recvCallback) +{ + return 0; +} +int32_t DistributedFileDaemonManagerImpl::UnRegisterAssetCallback(const sptr &recvCallback) +{ + return 0; +} + +DistributedFileDaemonManager &DistributedFileDaemonManager::GetInstance() +{ + return DistributedFileDaemonManagerImpl::GetInstance(); +} +bool AssetObj::Marshalling(Parcel &parcel) const +{ + return true; +} +bool AssetObj::ReadFromParcel(Parcel &parcel) +{ + return true; +} +AssetObj *AssetObj::Unmarshalling(Parcel &parcel) +{ + return nullptr; +} +} // namespace DistributedFile +} // namespace Storage } // namespace OHOS \ No newline at end of file diff --git a/mock/src/mock_hisysevent.cpp b/mock/src/mock_hisysevent.cpp new file mode 100644 index 00000000..c0ae8be7 --- /dev/null +++ b/mock/src/mock_hisysevent.cpp @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "hisysevent_c.h" +int OH_HiSysEvent_Write(const char *domain, const char *name, HiSysEventEventType type, HiSysEventParam params[], + size_t size) +{ + return 0; +} \ No newline at end of file diff --git a/mock/src/mock_mem_mgr.cpp b/mock/src/mock_mem_mgr.cpp new file mode 100644 index 00000000..0afd6acf --- /dev/null +++ b/mock/src/mock_mem_mgr.cpp @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "mock_mem_mgr" +#include "bundle_priority_list.h" +#include "mem_mgr_client.h" +#include "mem_mgr_process_state_info.h" +#include "mem_mgr_proxy.h" +#include "mem_mgr_window_info.h" + +namespace OHOS::Memory { +int32_t BundlePriorityList::GetCount() const +{ + return 0; +} +bool BundlePriorityList::Marshalling(Parcel &parcel) const +{ + return false; +} +BundlePriorityList *BundlePriorityList::Unmarshalling(Parcel &parcel) +{ + return nullptr; +} +void BundlePriorityList::SetCount(int32_t count) {} +const std::vector &BundlePriorityList::GetList() +{ + return {}; +} +int32_t BundlePriorityList::Size() const +{ + return 0; +} +void BundlePriorityList::AddBundleInfo(BundlePriority &bundleInfo) {} +void BundlePriorityList::Show() const {} +bool BundlePriorityList::ReadFromParcel(Parcel &parcel) +{ + return false; +} +int32_t MemMgrClient::GetBundlePriorityList(BundlePriorityList &bundlePrioList) +{ + return 0; +} +int32_t MemMgrClient::NotifyDistDevStatus(int32_t pid, int32_t uid, const std::string &name, bool connected) +{ + return 0; +} +bool MemMgrProcessStateInfo::Marshalling(Parcel &parcel) const +{ + return 0; +} +MemMgrProcessStateInfo *MemMgrProcessStateInfo::Unmarshalling(Parcel &parcel) +{ + return nullptr; +} +MemMgrClient &MemMgrClient::GetInstance(){ + static MemMgrClient memMgrClient; + return memMgrClient; +} +int32_t MemMgrClient::RegisterActiveApps(int32_t pid, int32_t uid) +{ + return 0; +} +int32_t MemMgrClient::GetKillLevelOfLmkd(int32_t &killLevel) +{ + return 0; +} +int32_t MemMgrClient::DeregisterActiveApps(int32_t pid, int32_t uid) +{ + return 0; +} +int32_t MemMgrClient::GetAvailableMemory(int32_t &memSize) +{ + return 0; +} +int32_t MemMgrClient::GetTotalMemory(int32_t &memSize) +{ + return 0; +} +int32_t MemMgrClient::GetAvailableMemory() +{ + return 0; +} +int32_t MemMgrClient::GetTotalMemory() +{ + return 0; +} +int32_t MemMgrClient::OnWindowVisibilityChanged(const std::vector> &MemMgrWindowInfo) +{ + return 0; +} +int32_t MemMgrClient::GetReclaimPriorityByPid(int32_t pid, int32_t &priority) +{ + return 0; +} +int32_t MemMgrClient::NotifyProcessStateChangedSync(const MemMgrProcessStateInfo &processStateInfo) +{ + return 0; +} +int32_t MemMgrClient::NotifyProcessStateChangedAsync(const MemMgrProcessStateInfo &processStateInfo) +{ + return 0; +} +int32_t MemMgrClient::NotifyProcessStatus(int32_t pid, int32_t type, int32_t status, int saId) +{ + return 0; +} +int32_t MemMgrClient::SetCritical(int32_t pid, bool critical, int32_t saId) +{ + return 0; +} +sptr MemMgrClient::GetMemMgrService() +{ + return sptr(); +} +int32_t MemMgrProxy::GetBundlePriorityList(BundlePriorityList &bundlePrioList) +{ + return 0; +} +int32_t MemMgrProxy::NotifyDistDevStatus(int32_t pid, int32_t uid, const std::string &name, bool connected) +{ + return 0; +} +int32_t MemMgrProxy::GetKillLevelOfLmkd(int32_t &killLevel) +{ + return 0; +} +int32_t MemMgrProxy::GetReclaimPriorityByPid(int32_t pid, int32_t &priority) +{ + return 0; +} +int32_t MemMgrProxy::NotifyProcessStateChangedSync(const MemMgrProcessStateInfo &processStateInfo) +{ + return 0; +} +int32_t MemMgrProxy::NotifyProcessStateChangedAsync(const MemMgrProcessStateInfo &processStateInfo) +{ + return 0; +} +int32_t MemMgrProxy::NotifyProcessStatus(int32_t pid, int32_t type, int32_t status, int saId) +{ + return 0; +} +int32_t MemMgrProxy::SetCritical(int32_t pid, bool critical, int32_t saId) +{ + return 0; +} +} // namespace OHOS::Memory \ No newline at end of file diff --git a/mock/src/mock_notification.cpp b/mock/src/mock_notification.cpp index e2391d31..3d70b809 100644 --- a/mock/src/mock_notification.cpp +++ b/mock/src/mock_notification.cpp @@ -212,6 +212,8 @@ const std::string CommonEventSupport::COMMON_EVENT_TIME_TICK = "COMMON_EVENT_TIM const std::string CommonEventSupport::COMMON_EVENT_TIME_CHANGED = "COMMON_EVENT_TIME_CHANGED"; const std::string CommonEventSupport::COMMON_EVENT_DATE_CHANGED = "COMMON_EVENT_DATE_CHANGED"; const std::string CommonEventSupport::COMMON_EVENT_TIMEZONE_CHANGED = "COMMON_EVENT_TIMEZONE_CHANGED"; +const std::string CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED = "COMMON_EVENT_SCREEN_UNLOCKED"; +const std::string CommonEventSupport::COMMON_EVENT_BUNDLE_SCAN_FINISHED = "COMMON_EVENT_BUNDLE_SCAN_FINISHED"; bool CommonEventSubscribeInfo::Marshalling(OHOS::Parcel &) const { return true; } CommonEventSubscribeInfo::CommonEventSubscribeInfo(const CommonEventSubscribeInfo &commonEventSubscribeInfo) {} void CommonEventSubscribeInfo::SetPriority(const int32_t &priority) {} diff --git a/mock/src/mock_uri_permission_manager.cpp b/mock/src/mock_uri_permission_manager.cpp index 3c214129..66fbfa6e 100644 --- a/mock/src/mock_uri_permission_manager.cpp +++ b/mock/src/mock_uri_permission_manager.cpp @@ -32,11 +32,6 @@ int UriPermissionManagerClient::GrantUriPermission(const std::vector& uriVe void UriPermissionManagerClient::RevokeUriPermission(const Security::AccessToken::AccessTokenID tokenId) {} -int UriPermissionManagerClient::RevokeUriPermissionManually(const Uri& uri, const std::string bundleName) -{ - return 0; -} - sptr UriPermissionManagerClient::ConnectUriPermService() { return nullptr; @@ -92,6 +87,12 @@ bool UriPermissionManagerClient::IsAuthorizationUriAllowed(uint32_t fromTokenId) return false; } +int UriPermissionManagerClient::RevokeUriPermissionManually(const Uri &uri, const std::string bundleName, + int32_t instance) +{ + return 0; +} + void UriPermissionManagerClient::UpmsDeathRecipient::OnRemoteDied([[maybe_unused]] const wptr& remote) { } diff --git a/mock/src/mock_xcollie.cpp b/mock/src/mock_xcollie.cpp new file mode 100644 index 00000000..7f27c70d --- /dev/null +++ b/mock/src/mock_xcollie.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "xcollie.h" + +namespace OHOS::HiviewDFX { +XCollie::XCollie() {} +XCollie::~XCollie() {} +void XCollie::CancelTimer(int id) {} +void XCollie::RegisterXCollieChecker(const sptr &checker, unsigned int type) {} +int XCollie::SetTimer(const std::string &name, unsigned int timeout, std::function func, void *arg, + unsigned int flag) +{ + return 0; +} +bool XCollie::UpdateTimer(int id, unsigned int timeout) +{ + return false; +} +} // namespace OHOS::HiviewDFX \ No newline at end of file diff --git a/preferences/README_zh.md b/preferences/README_zh.md index 4c0b4dfb..0529f600 100644 --- a/preferences/README_zh.md +++ b/preferences/README_zh.md @@ -44,9 +44,9 @@ ``` ## 约束 -- Key键为String类型,要求非空且长度不超过80个字符。 +- Key键为String类型,要求非空且长度不超过1024个字符。 -- 如果Value值为String类型,可以为空但是长度不超过8192个字符。 +- 如果Value值为String类型,可以为空但是长度不超过16 * 1024 * 1024个字符。 - 存储的数据量应该是轻量级的,建议存储的数据不超过一万条,否则会在内存方面产生较大的开销。 diff --git a/preferences/bundle.json b/preferences/bundle.json index 54d9c7f8..3739d88e 100644 --- a/preferences/bundle.json +++ b/preferences/bundle.json @@ -56,16 +56,17 @@ "ability_base", "common_event_service", "hitrace", - "ipc" - ], - "third_party": [ + "ipc", "libxml2" ] }, "build": { "sub_component": [ "//foundation/distributeddatamgr/preferences/interfaces/inner_api:native_preferences", + "//foundation/distributeddatamgr/preferences/frameworks/cj:cj_preferences_ffi", + "//foundation/distributeddatamgr/preferences/frameworks/js/napi/common:preferences_jscommon", "//foundation/distributeddatamgr/preferences/frameworks/js/napi/preferences:preferences", + "//foundation/distributeddatamgr/preferences/frameworks/js/napi/sendable_preferences:sendablepreferences", "//foundation/distributeddatamgr/preferences/frameworks/js/napi/storage:storage", "//foundation/distributeddatamgr/preferences/frameworks/js/napi/system_storage:storage_napi" ], diff --git a/preferences/frameworks/cj/BUILD.gn b/preferences/frameworks/cj/BUILD.gn new file mode 100644 index 00000000..b2748c90 --- /dev/null +++ b/preferences/frameworks/cj/BUILD.gn @@ -0,0 +1,52 @@ +# Copyright (c) 2024 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//build/ohos/ace/ace.gni") +import("//foundation/distributeddatamgr/preferences/preferences.gni") + +base_include = [ "${preferences_base_path}/frameworks/common/include" ] + +base_sources = [ + "${preferences_cj_path}/preferences_ffi.cpp", + "${preferences_cj_path}/preferences_impl.cpp", + "${preferences_cj_path}/preferences_utils.cpp", +] + +ohos_shared_library("cj_preferences_ffi") { + include_dirs = base_include + sources = base_sources + sanitize = { + boundary_sanitize = true + ubsan = true + cfi = true + cfi_cross_dso = true + debug = false + } + + deps = [ "${preferences_base_path}/interfaces/inner_api:native_preferences" ] + + external_deps = [ + "ability_runtime:abilitykit_native", + "ability_runtime:napi_base_context", + "c_utils:utils", + "hilog:libhilog", + "napi:ace_napi", + "napi:cj_bind_ffi", + "napi:cj_bind_native", + ] + + subsystem_name = "distributeddatamgr" + part_name = "preferences" + innerapi_tags = [ "platformsdk" ] +} diff --git a/preferences/frameworks/cj/src/preferences_ffi.cpp b/preferences/frameworks/cj/src/preferences_ffi.cpp new file mode 100644 index 00000000..45040af1 --- /dev/null +++ b/preferences/frameworks/cj/src/preferences_ffi.cpp @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "preferences_ffi.h" +#include "preferences_impl.h" +#include "preferences_log.h" +#include "cj_lambda.h" + +using namespace OHOS::FFI; +using namespace OHOS::Preferences; + +namespace OHOS { +namespace Preferences { +extern "C" { +int64_t FfiOHOSPreferencesGetPreferences(OHOS::AbilityRuntime::Context* context, const char* name, + const char* dataGroupId, int32_t* errCode) +{ + auto nativePreferences = FFIData::Create(context, name, dataGroupId, errCode); + return nativePreferences->GetID(); +} + +int32_t FfiOHOSPreferencesDeletePreferences(OHOS::AbilityRuntime::Context* context, const char* name, + const char* dataGroupId) +{ + return PreferencesImpl::DeletePreferences(context, name, dataGroupId); +} + +int32_t FfiOHOSPreferencesRemovePreferencesFromCache(OHOS::AbilityRuntime::Context* context, const char* name, + const char* dataGroupId) +{ + return PreferencesImpl::RemovePreferencesFromCache(context, name, dataGroupId); +} + +ValueType FfiOHOSPreferencesGet(int64_t id, const char* key, ValueType defValue) +{ + auto instance = FFIData::GetData(id); + if (!instance) { + LOGE("[Preferences] instance not exist. %{public}" PRId64, id); + return ValueType{0}; + } + return instance->Get(key, defValue); +} + +int32_t FfiOHOSPreferencesPut(int64_t id, const char* key, ValueType value) +{ + auto instance = FFIData::GetData(id); + if (!instance) { + LOGE("[Preferences] instance not exist. %{public}" PRId64, id); + return ERR_INVALID_INSTANCE_CODE; + } + return instance->Put(key, value); +} + +ValueTypes FfiOHOSPreferencesGetAll(int64_t id) +{ + auto instance = FFIData::GetData(id); + if (!instance) { + LOGE("[Preferences] instance not exist. %{public}" PRId64, id); + return ValueTypes{0}; + } + return instance->GetAll(); +} + +void FfiOHOSPreferencesFlush(int64_t id) +{ + auto instance = FFIData::GetData(id); + if (!instance) { + LOGE("[Preferences] instance not exist. %{public}" PRId64, id); + return; + } + instance->Flush(); + return; +} + +void FfiOHOSPreferencesClear(int64_t id) +{ + auto instance = FFIData::GetData(id); + if (!instance) { + LOGE("[Preferences] instance not exist. %{public}" PRId64, id); + return; + } + instance->Clear(); + return; +} + +bool FfiOHOSPreferencesHas(int64_t id, const char* key) +{ + auto instance = FFIData::GetData(id); + if (!instance) { + LOGE("[Preferences] instance not exist. %{public}" PRId64, id); + return false; + } + return instance->HasKey(key); +} + +int32_t FfiOHOSPreferencesDelete(int64_t id, const char* key) +{ + auto instance = FFIData::GetData(id); + if (!instance) { + LOGE("[Preferences] instance not exist. %{public}" PRId64, id); + return ERR_INVALID_INSTANCE_CODE; + } + return instance->Delete(key); +} + +int32_t FfiOHOSPreferencesOn(int64_t id, const char* mode, + void (*callback)(const char* value), void (*callbackRef)(const char* valueRef)) +{ + auto instance = FFIData::GetData(id); + if (!instance) { + LOGE("[Preferences] instance not exist. %{public}" PRId64, id); + return ERR_INVALID_INSTANCE_CODE; + } + auto onChange = [lambda = CJLambda::Create(callbackRef)](const std::string& valueRef) -> + void { lambda(valueRef.c_str()); }; + return instance->RegisterObserver(mode, (std::function*)(callback), onChange); +} + +int32_t FfiOHOSPreferencesOff(int64_t id, const char* mode, void (*callback)(const char* value)) +{ + auto instance = FFIData::GetData(id); + if (!instance) { + LOGE("[Preferences] instance not exist. %{public}" PRId64, id); + return ERR_INVALID_INSTANCE_CODE; + } + auto onChange = [lambda = CJLambda::Create(callback)](const std::string& value) -> void { lambda(value.c_str()); }; + return instance->UnRegisterObserver(mode, (std::function*)(callback)); +} + +int32_t FfiOHOSPreferencesOffAll(int64_t id, const char* mode) +{ + auto instance = FFIData::GetData(id); + if (!instance) { + LOGE("[Preferences] instance not exist. %{public}" PRId64, id); + return ERR_INVALID_INSTANCE_CODE; + } + return instance->UnRegisteredAllObservers(mode); +} +} +} +} \ No newline at end of file diff --git a/preferences/frameworks/cj/src/preferences_ffi.h b/preferences/frameworks/cj/src/preferences_ffi.h new file mode 100644 index 00000000..a669808a --- /dev/null +++ b/preferences/frameworks/cj/src/preferences_ffi.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef PREFERENCES_FFI_H +#define PREFERENCES_FFI_H + +#include + +#include "napi_base_context.h" +#include "ffi_remote_data.h" +#include "cj_common_ffi.h" +#include "preferences_interface.h" + +namespace OHOS { +namespace Preferences { + +extern "C" { + FFI_EXPORT int64_t FfiOHOSPreferencesGetPreferences(OHOS::AbilityRuntime::Context* context, const char* name, + const char* dataGroupId, int32_t* errCode); + + FFI_EXPORT int32_t FfiOHOSPreferencesDeletePreferences(OHOS::AbilityRuntime::Context* context, const char* name, + const char* dataGroupId); + + FFI_EXPORT int32_t FfiOHOSPreferencesRemovePreferencesFromCache(OHOS::AbilityRuntime::Context* context, + const char* name, const char* dataGroupId); + + FFI_EXPORT int32_t FfiOHOSPreferencesDelete(int64_t id, const char* key); + + FFI_EXPORT bool FfiOHOSPreferencesHas(int64_t id, const char* key); + + FFI_EXPORT int32_t FfiOHOSPreferencesOn(int64_t id, const char* mode, void (*callback)(const char* value), + void (*callbackRef)(const char* valueRef)); + + FFI_EXPORT int32_t FfiOHOSPreferencesOff(int64_t id, const char* mode, void (*callback)(const char* value)); + + FFI_EXPORT int32_t FfiOHOSPreferencesOffAll(int64_t id, const char* mode); + + FFI_EXPORT ValueType FfiOHOSPreferencesGet(int64_t id, const char* key, ValueType defValue); + + FFI_EXPORT int32_t FfiOHOSPreferencesPut(int64_t id, const char* key, ValueType value); + + FFI_EXPORT ValueTypes FfiOHOSPreferencesGetAll(int64_t id); + + FFI_EXPORT void FfiOHOSPreferencesFlush(int64_t id); + + FFI_EXPORT void FfiOHOSPreferencesClear(int64_t id); +} + +} // namespace Preferences +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/preferences/frameworks/cj/src/preferences_impl.cpp b/preferences/frameworks/cj/src/preferences_impl.cpp new file mode 100644 index 00000000..9c92936d --- /dev/null +++ b/preferences/frameworks/cj/src/preferences_impl.cpp @@ -0,0 +1,496 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "preferences_helper.h" + +#include +#include +#include +#include + +#include "ffi_remote_data.h" +#include "securec.h" +#include "preferences.h" +#include "preferences_errno.h" +#include "preferences_impl.h" +#include "preferences_value.h" +#include "preferences_utils.h" +#include "preferences_errno.h" +#include "preferences_log.h" + +using namespace OHOS::Preferences; +using namespace OHOS::FFI; +using namespace OHOS::NativePreferences; + +namespace OHOS::Preferences { +std::tuple GetInstancePath(OHOS::AbilityRuntime::Context* context, const std::string &name, + const std::string &dataGroupId) +{ + std::string path; + if (context == nullptr) { + LOGE("The context is nullptr."); + return {E_ERROR, path}; + } + int32_t errcode = 0; + auto tempContext = std::make_shared(); + tempContext->bundleName = context->GetBundleName(); + tempContext->name = name; + std::string preferencesDir; + errcode = context->GetSystemPreferencesDir(dataGroupId, false, preferencesDir); + if (errcode != 0) { + return {errcode, path}; + } + tempContext->path = preferencesDir.append("/").append(tempContext->name); + return {E_OK, tempContext->path}; +} + +PreferencesImpl::PreferencesImpl(OHOS::AbilityRuntime::Context* context, + const std::string& name, const std::string& dataGroupId, int32_t* errCode) +{ + if (context == nullptr) { + LOGE("Failed to get native context instance"); + *errCode = -1; + return; + } + auto [code, path] = GetInstancePath(context, name, dataGroupId); + if (code != E_OK) { + *errCode = code; + return; + } + NativePreferences::Options options(path, context->GetBundleName(), dataGroupId); + int err; + auto proxy = PreferencesHelper::GetPreferences(options, err); + *errCode = err; + if (err != E_OK) { + LOGE("Failed to get underlying preferences instance."); + return; + } + preferences = proxy; + if (preferences == nullptr) { + LOGE("The preferences is nullptr."); + return; + } +} + +int32_t PreferencesImpl::DeletePreferences(OHOS::AbilityRuntime::Context* context, const std::string &name, + const std::string &dataGroupId) +{ + auto [code, path] = GetInstancePath(context, name, dataGroupId); + if (code != E_OK) { + return code; + } + int errCode = PreferencesHelper::DeletePreferences(path); + if (errCode != E_OK) { + return errCode; + } + return 0; +} + +int32_t PreferencesImpl::RemovePreferencesFromCache(OHOS::AbilityRuntime::Context* context, const std::string &name, + const std::string &dataGroupId) +{ + auto [code, path] = GetInstancePath(context, name, dataGroupId); + if (code != 0) { + return code; + } + int errCode = PreferencesHelper::RemovePreferencesFromCache(path); + if (errCode != E_OK) { + return errCode; + } + return E_OK; +} + +void PreferencesImpl::Flush() +{ + if (preferences == nullptr) { + LOGE("The preferences is nullptr."); + return; + } + preferences->FlushSync(); + return; +} + +void PreferencesImpl::Clear() +{ + if (preferences == nullptr) { + LOGE("The preferences is nullptr."); + return; + } + preferences->Clear(); + return; +} + +int32_t PreferencesImpl::Delete(const std::string &key) +{ + if (preferences == nullptr) { + LOGE("The preferences is nullptr."); + return E_ERROR; + } + int errCode = preferences->Delete(key); + return errCode; +} + +bool PreferencesImpl::HasKey(const std::string &key) +{ + if (preferences == nullptr) { + LOGE("The preferences is nullptr."); + return false; + } + bool result = preferences->HasKey(key); + return result; +} + +OHOS::FFI::RuntimeType* PreferencesImpl::GetRuntimeType() +{ + return GetClassType(); +} + +OHOS::FFI::RuntimeType* PreferencesImpl::GetClassType() +{ + static OHOS::FFI::RuntimeType runtimeType = + OHOS::FFI::RuntimeType::Create("PreferencesImpl"); + return &runtimeType; +} + +bool isSameFunction(const std::function *f1, const std::function *f2) +{ + return f1 == f2; +} + +bool PreferencesImpl::HasRegisteredObserver(std::function *callback, RegisterMode mode) +{ + const auto &observers = (mode == RegisterMode::LOCAL_CHANGE) ? localObservers_ : multiProcessObservers_; + return std::any_of(observers.begin(), observers.end(), [callback](const auto& it) { + return isSameFunction(callback, it->m_callback); + }); +} + +RegisterMode PreferencesImpl::ConvertToRegisterMode(const std::string &mode) +{ + return (mode == strChange) ? RegisterMode::LOCAL_CHANGE : RegisterMode::MULTI_PRECESS_CHANGE; +} + +PreferencesValue ValueTypeToPreferencesValue(const ValueType &value) +{ + NativePreferences::PreferencesValue preferencesValue = NativePreferences::PreferencesValue(-1); + switch (value.tag) { + case TYPE_INT: { + preferencesValue = NativePreferences::PreferencesValue(value.integer); + break; + } + case TYPE_DOU: { + preferencesValue = NativePreferences::PreferencesValue(value.float64); + break; + } + case TYPE_STR: { + preferencesValue = NativePreferences::PreferencesValue(std::string(value.string)); + break; + } + case TYPE_BOOL: { + preferencesValue = NativePreferences::PreferencesValue(value.boolean); + break; + } + case TYPE_BOOLARR: { + std::vector bools = std::vector(); + for (int64_t i = 0; i < value.boolArray.size; i++) { + bools.push_back(value.boolArray.head[i]); + } + preferencesValue = NativePreferences::PreferencesValue(bools); + break; + } + case TYPE_DOUARR: { + std::vector doubles = std::vector(); + for (int64_t i = 0; i < value.doubleArray.size; i++) { + doubles.push_back(value.doubleArray.head[i]); + } + preferencesValue = NativePreferences::PreferencesValue(doubles); + break; + } + case TYPE_STRARR: { + std::vector strings = std::vector(); + for (int64_t i = 0; i < value.stringArray.size; i++) { + strings.push_back(value.stringArray.head[i]); + } + preferencesValue = NativePreferences::PreferencesValue(strings); + break; + } + default: + preferencesValue = NativePreferences::PreferencesValue(-1); + break; + } + return preferencesValue; +} + +void freeValueType(ValueType v) +{ + switch (v.tag) { + case TYPE_STR: { + free(v.string); + break; + } + case TYPE_BOOLARR: { + free(v.boolArray.head); + break; + } + case TYPE_DOUARR: { + free(v.doubleArray.head); + break; + } + case TYPE_STRARR: { + for (int64_t i = 0; i < v.stringArray.size; i++) { + free(v.stringArray.head[i]); + } + free(v.stringArray.head); + break; + } + default: + break; + } +} + +CArrDouble vectorToDoubleArray(const std::vector &doubles) +{ + double* head = static_cast(malloc(doubles.size() * sizeof(double))); + if (head == nullptr) { + return CArrDouble{0}; + } + for (unsigned long i = 0; i < doubles.size(); i++) { + head[i] = doubles[i]; + } + CArrDouble doubleArray = { head, doubles.size() }; + return doubleArray; +} + +CArrBool vectorToBoolArray(std::vector bools) +{ + bool* head = static_cast(malloc(bools.size() * sizeof(bool))); + if (head == nullptr) { + return CArrBool{0}; + } + for (unsigned long i = 0; i < bools.size(); i++) { + head[i] = bools[i]; + } + CArrBool boolArray = { head, bools.size() }; + return boolArray; +} + +CArrStr vectorToStringArray(std::vector strings) +{ + CArrStr strArray; + strArray.size = static_cast(strings.size()); + strArray.head = static_cast(malloc(strArray.size * sizeof(char*))); + if (strArray.head == nullptr) { + return strArray; + } + for (int64_t i = 0; i < strArray.size; i++) { + strArray.head[i] = static_cast(malloc((strings[i].length() + 1) * sizeof(char))); + if (strArray.head[i] == nullptr) { + return strArray; + } + errno_t ret = strcpy_s(strArray.head[i], (strings[i].length() + 1) * sizeof(char), strings[i].c_str()); + if (ret != EOK) { + return strArray; + } + } + return strArray; +} + +ValueType PreferencesValueToValueType(const PreferencesValue &pValue) +{ + ValueType v = {0}; + if (pValue.IsInt()) { + v.integer = (int64_t)std::get(pValue.value_); + v.tag = TYPE_INT; + } else if (pValue.IsLong()) { + v.integer = std::get(pValue.value_); + v.tag = TYPE_INT; + } else if (pValue.IsFloat()) { + v.float64 = (double)std::get(pValue.value_); + v.tag = TYPE_DOU; + } else if (pValue.IsDouble()) { + v.float64 = std::get(pValue.value_); + v.tag = TYPE_DOU; + } else if (pValue.IsString()) { + auto pValueStr = std::get(pValue.value_); + char* pValueChar = MallocCString(pValueStr); + v.string = pValueChar; + v.tag = TYPE_STR; + } else if (pValue.IsBool()) { + v.boolean = std::get(pValue.value_); + v.tag = TYPE_BOOL; + } else if (pValue.IsBoolArray()) { + auto boolVector = std::get>(pValue.value_); + v.boolArray = vectorToBoolArray(boolVector); + v.tag = TYPE_BOOLARR; + } else if (pValue.IsDoubleArray()) { + auto doubleVector = std::get>(pValue.value_); + v.doubleArray = vectorToDoubleArray(doubleVector); + v.tag = TYPE_DOUARR; + } else if (pValue.IsStringArray()) { + auto stringVector = std::get>(pValue.value_); + v.stringArray = vectorToStringArray(stringVector); + v.tag = TYPE_STRARR; + } else { + v.tag = -1; + } + return v; +} + +ValueTypes PreferencesValuesToValueTypes(const std::map &objects) +{ + ValueTypes valueTypes = {0}; + valueTypes.size = static_cast(objects.size()); + valueTypes.key = static_cast(malloc(valueTypes.size * sizeof(char*))); + if (valueTypes.key == nullptr) { + return valueTypes; + } + valueTypes.head = static_cast(malloc(valueTypes.size * sizeof(ValueType))); + if (valueTypes.head == nullptr) { + free(valueTypes.key); + return valueTypes; + } + int i = 0; + for (auto const& [key, value] : objects) { + // 将键转换成 char* + valueTypes.key[i] = static_cast(malloc((key.length() + 1) * sizeof(char))); + if (valueTypes.key[i] == nullptr) { + for (int j = i - 1; j >= 0; j--) { + free(valueTypes.key[j]); + freeValueType(valueTypes.head[i]); + } + return valueTypes; + } + errno_t ret = strcpy_s(valueTypes.key[i], (key.length() + 1) * sizeof(char), key.c_str()); + if (ret != EOK) { + for (int j = i - 1; j >= 0; j--) { + free(valueTypes.key[j]); + freeValueType(valueTypes.head[i]); + } + return valueTypes; + } + // 将值转换成 ValueType + valueTypes.head[i] = PreferencesValueToValueType(value); + i++; + } + return valueTypes; +} + +ValueType PreferencesImpl::Get(const std::string &key, const ValueType &defValue) +{ + if (preferences == nullptr) { + LOGE("The preferences is nullptr."); + return ValueType{0}; + } + return PreferencesValueToValueType(preferences->Get(key, ValueTypeToPreferencesValue(defValue))); +} + +int32_t PreferencesImpl::Put(const std::string &key, const ValueType &value) +{ + if (preferences == nullptr) { + LOGE("The preferences is nullptr."); + return E_ERROR; + } + return preferences->Put(key, ValueTypeToPreferencesValue(value)); +} + +ValueTypes PreferencesImpl::GetAll() +{ + if (preferences == nullptr) { + LOGE("The preferences is nullptr."); + return ValueTypes{0}; + } + return PreferencesValuesToValueTypes(preferences->GetAll()); +} + +int32_t PreferencesImpl::RegisterObserver(const std::string &mode, std::function *callback, + const std::function& callbackRef) +{ + std::lock_guard lck(listMutex_); + if (!HasRegisteredObserver(callback, ConvertToRegisterMode(mode))) { + auto observer = std::make_shared(callback, callbackRef); + if (preferences == nullptr) { + LOGE("The preferences is nullptr."); + return E_ERROR; + } + int errCode = preferences->RegisterObserver(observer, ConvertToRegisterMode(mode)); + if (errCode != E_OK) { + return errCode; + } + auto &observers = (ConvertToRegisterMode(mode) == RegisterMode::LOCAL_CHANGE) ? + localObservers_ : multiProcessObservers_; + observers.push_back(observer); + } + return E_OK; +} + +int32_t PreferencesImpl::UnRegisterObserver(const std::string &mode, std::function *callback) +{ + std::lock_guard lck(listMutex_); + auto &observers = (ConvertToRegisterMode(mode) == RegisterMode::LOCAL_CHANGE) ? + localObservers_ : multiProcessObservers_; + auto it = observers.begin(); + if (preferences == nullptr) { + LOGE("The preferences is nullptr."); + return E_ERROR; + } + while (it != observers.end()) { + if (isSameFunction(callback, (*it)->m_callback)) { + int errCode = preferences->UnRegisterObserver(*it, ConvertToRegisterMode(mode)); + if (errCode != E_OK) { + return errCode; + } + it = observers.erase(it); + break; // specified observer is current iterator + } + ++it; + } + return E_OK; +} + +int32_t PreferencesImpl::UnRegisteredAllObservers(const std::string &mode) +{ + std::lock_guard lck(listMutex_); + auto &observers = (ConvertToRegisterMode(mode) == RegisterMode::LOCAL_CHANGE) ? + localObservers_ : multiProcessObservers_; + bool hasFailed = false; + int errCode; + if (preferences == nullptr) { + LOGE("The preferences is nullptr."); + return E_ERROR; + } + for (auto &observer : observers) { + errCode = preferences->UnRegisterObserver(observer, ConvertToRegisterMode(mode)); + if (errCode != E_OK) { + hasFailed = true; + } + } + observers.clear(); + return hasFailed ? E_ERROR : E_OK; +} + +CJPreferencesObserver::CJPreferencesObserver(std::function *callback, + const std::function& callbackRef) +{ + if (callback == nullptr) { + LOGI("WARNING: nullptr"); + } + m_callback = callback; + m_callbackRef = callbackRef; +} + +void CJPreferencesObserver::OnChange(const std::string &key) +{ + m_callbackRef(key); +} +} diff --git a/preferences/frameworks/cj/src/preferences_impl.h b/preferences/frameworks/cj/src/preferences_impl.h new file mode 100644 index 00000000..f514f45e --- /dev/null +++ b/preferences/frameworks/cj/src/preferences_impl.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef PREFERENCES_IMPL_H +#define PREFERENCES_IMPL_H + +#include + +#include "preferences.h" +#include "preferences_interface.h" +#include "ffi_remote_data.h" +#include "ability_context.h" +#include "preferences_observer.h" + +namespace OHOS { +namespace Preferences { +using RegisterMode = NativePreferences::PreferencesObserver::RegisterMode; + +class CJPreferencesObserver : public OHOS::NativePreferences::PreferencesObserver { +public: + CJPreferencesObserver(std::function *callback, + const std::function& callbackRef); + void OnChange(const std::string &key) override; + std::function *m_callback; + std::function m_callbackRef; +}; + +class PreferencesImpl : public OHOS::FFI::FFIData { +public: + explicit PreferencesImpl(OHOS::AbilityRuntime::Context* context, + const std::string& name, const std::string& dataGroupId, int32_t* errCode); + + static int32_t DeletePreferences(OHOS::AbilityRuntime::Context* context, const std::string &name, + const std::string &dataGroupId); + + static int32_t RemovePreferencesFromCache(OHOS::AbilityRuntime::Context* context, const std::string &name, + const std::string &dataGroupId); + + int32_t Delete(const std::string &key); + + bool HasKey(const std::string &key); + + bool HasRegisteredObserver(std::function *callback, RegisterMode mode); + + int32_t RegisterObserver(const std::string &mode, std::function *callback, + const std::function& callbackRef); + + int32_t UnRegisterObserver(const std::string &mode, std::function *callback); + + int32_t UnRegisteredAllObservers(const std::string &mode); + + RegisterMode ConvertToRegisterMode(const std::string &mode); + + ValueType Get(const std::string &key, const ValueType &defValue); + + int32_t Put(const std::string &key, const ValueType &value); + + ValueTypes GetAll(); + + void Flush(); + + void Clear(); + + OHOS::FFI::RuntimeType* GetRuntimeType() override; + +private: + friend class OHOS::FFI::TypeBase; + friend class OHOS::FFI::RuntimeType; + static OHOS::FFI::RuntimeType* GetClassType(); + static constexpr char strChange[] = "change"; + static constexpr char strMultiProcessChange[] = "multiProcessChange"; + std::shared_ptr preferences; + std::mutex listMutex_ {}; + std::list> localObservers_; + std::list> multiProcessObservers_; +}; +} +} // namespace OHOS::Preferences + +#endif // PREFERENCES_IMPL_h \ No newline at end of file diff --git a/preferences/frameworks/cj/src/preferences_interface.h b/preferences/frameworks/cj/src/preferences_interface.h new file mode 100644 index 00000000..5d4a0a92 --- /dev/null +++ b/preferences/frameworks/cj/src/preferences_interface.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef PREFERENCES_INTERFACE_H +#define PREFERENCES_INTERFACE_H + +#include +#include + +#include "preferences.h" + +namespace OHOS { +namespace Preferences { + +struct CArrBool { + bool* head; + int64_t size; +}; + +struct CArrStr { + char** head; + int64_t size; +}; + +struct CArrDouble { + double* head; + int64_t size; +}; + +struct ValueType { + int64_t integer; + double float64; + char* string; + bool boolean; + CArrBool boolArray; + CArrDouble doubleArray; + CArrStr stringArray; + uint8_t tag; +}; + +struct ValueTypes { + char** key; + ValueType* head; + int64_t size; +}; + +struct HelperAysncContext { + std::string path; + std::string name; + std::string bundleName; + std::string dataGroupId; + std::shared_ptr proxy; + + HelperAysncContext() + { + } + virtual ~HelperAysncContext(){}; +}; + +} // namespace Preferences +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/preferences/frameworks/cj/src/preferences_log.h b/preferences/frameworks/cj/src/preferences_log.h new file mode 100644 index 00000000..a866da04 --- /dev/null +++ b/preferences/frameworks/cj/src/preferences_log.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef PREFERENCES_LOG_H +#define PREFERENCES_LOG_H + +#include "hilog/log.h" + +#undef LOG_DOMAIN +#undef LOG_TAG +#define LOG_DOMAIN 0xD002B25 +#define LOG_TAG "PreferencesCffi" + +#define LOGI(...) \ +if (HiLogIsLoggable(LOG_DOMAIN, LOG_TAG, LOG_INFO)) { \ + HILOG_INFO(LOG_CORE, ##__VA_ARGS__); \ +} + +#define LOGE(...) \ +if (HiLogIsLoggable(LOG_DOMAIN, LOG_TAG, LOG_ERROR)) { \ + HILOG_ERROR(LOG_CORE, __VA_ARGS__); \ +} + +#endif diff --git a/preferences/frameworks/cj/src/preferences_mock.cpp b/preferences/frameworks/cj/src/preferences_mock.cpp new file mode 100644 index 00000000..c360e2a7 --- /dev/null +++ b/preferences/frameworks/cj/src/preferences_mock.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cj_common_ffi.h" + +extern "C" { +FFI_EXPORT int FfiOHOSPreferencesGetPreferences = 0; +FFI_EXPORT int FfiOHOSPreferencesDeletePreferences = 0; +FFI_EXPORT int FfiOHOSPreferencesRemovePreferencesFromCache = 0; +FFI_EXPORT int FfiOHOSPreferencesDelete = 0; +FFI_EXPORT int FfiOHOSPreferencesHas = 0; +FFI_EXPORT int FfiOHOSPreferencesOn = 0; +FFI_EXPORT int FfiOHOSPreferencesOff = 0; +FFI_EXPORT int FfiOHOSPreferencesOffAll = 0; +FFI_EXPORT int FfiOHOSPreferencesGet = 0; +FFI_EXPORT int FfiOHOSPreferencesPut = 0; +FFI_EXPORT int FfiOHOSPreferencesGetAll = 0; +FFI_EXPORT int FfiOHOSPreferencesFlush = 0; +FFI_EXPORT int FfiOHOSPreferencesClear = 0; +} \ No newline at end of file diff --git a/preferences/frameworks/cj/src/preferences_utils.cpp b/preferences/frameworks/cj/src/preferences_utils.cpp new file mode 100644 index 00000000..d4918e2b --- /dev/null +++ b/preferences/frameworks/cj/src/preferences_utils.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "preferences_utils.h" + +namespace OHOS { +namespace Preferences { + char* MallocCString(const std::string& origin) + { + if (origin.empty()) { + return nullptr; + } + auto len = origin.length() + 1; + char* res = static_cast(malloc(len * sizeof(char))); + if (res == nullptr) { + return nullptr; + } + return std::char_traits::copy(res, origin.c_str(), len); + } +} +} \ No newline at end of file diff --git a/preferences/frameworks/cj/src/preferences_utils.h b/preferences/frameworks/cj/src/preferences_utils.h new file mode 100644 index 00000000..437e1ed6 --- /dev/null +++ b/preferences/frameworks/cj/src/preferences_utils.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PREFERENCES_UTILS_H +#define PREFERENCES_UTILS_H + +#include +#include +#include + +namespace OHOS { +namespace Preferences { + enum TagType { + TYPE_INT, TYPE_DOU, TYPE_STR, TYPE_BOOL, TYPE_BOOLARR, TYPE_DOUARR, TYPE_STRARR + }; + + char* MallocCString(const std::string& origin); +} +} +#endif \ No newline at end of file diff --git a/preferences/frameworks/common/include/log_print.h b/preferences/frameworks/common/include/log_print.h index 78857d49..2df903cb 100644 --- a/preferences/frameworks/common/include/log_print.h +++ b/preferences/frameworks/common/include/log_print.h @@ -40,6 +40,13 @@ static inline OHOS::HiviewDFX::HiLogLabel LogLabel() return { LOG_CORE, 0xD001653, "StorageJsKit" }; } } +namespace Sendable::JSPreferences { +static inline OHOS::HiviewDFX::HiLogLabel LogLabel() +{ + return { LOG_CORE, 0xD001653, "JSPreferences" }; +} +} + } // namespace OHOS #define LOG_DEBUG(fmt, ...) \ do { \ diff --git a/preferences/frameworks/js/napi/common/BUILD.gn b/preferences/frameworks/js/napi/common/BUILD.gn new file mode 100644 index 00000000..7bf9f7cc --- /dev/null +++ b/preferences/frameworks/js/napi/common/BUILD.gn @@ -0,0 +1,70 @@ +# Copyright (c) 2024 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import("//build/ohos.gni") +import("//foundation/distributeddatamgr/preferences/preferences.gni") + +config("common_public_config") { + visibility = [ ":*" ] + include_dirs = [ "include" ] +} + +config("common_config") { + visibility = [ ":*" ] + include_dirs = [ + "include", + "${preferences_base_path}/frameworks/common/include", + ] +} + +if (is_ohos) { + ohos_shared_library("preferences_jscommon") { + branch_protector_ret = "pac_ret" + sanitize = { + boundary_sanitize = true + ubsan = true + cfi = true + cfi_cross_dso = true + debug = false + } + + cflags_cc = [ + "-std=c++17", + "-stdlib=libc++", + ] + + sources = [ + "${preferences_napi_path}/common/src/js_ability.cpp", + "${preferences_napi_path}/common/src/js_common_utils.cpp", + "${preferences_napi_path}/common/src/js_observer.cpp", + "${preferences_napi_path}/common/src/js_sendable_utils.cpp", + "${preferences_napi_path}/common/src/napi_async_call.cpp", + "${preferences_napi_path}/common/src/napi_preferences_error.cpp", + "${preferences_napi_path}/common/src/napi_preferences_observer.cpp", + "${preferences_napi_path}/common/src/uv_queue.cpp", + ] + configs = [ ":common_config" ] + public_configs = [ ":common_public_config" ] + deps = + [ "${preferences_base_path}/interfaces/inner_api:native_preferences" ] + version_script = "libcommon.map" + external_deps = [ + "ability_runtime:abilitykit_native", + "ability_runtime:napi_base_context", + "hilog:libhilog", + "napi:ace_napi", + ] + + subsystem_name = "distributeddatamgr" + part_name = "preferences" + } +} diff --git a/preferences/frameworks/js/napi/common/include/js_utils.h b/preferences/frameworks/js/napi/common/include/js_common_utils.h similarity index 96% rename from preferences/frameworks/js/napi/common/include/js_utils.h rename to preferences/frameworks/js/napi/common/include/js_common_utils.h index 7b42a36a..e7e86fed 100644 --- a/preferences/frameworks/js/napi/common/include/js_utils.h +++ b/preferences/frameworks/js/napi/common/include/js_common_utils.h @@ -39,14 +39,14 @@ using namespace NativePreferences; constexpr int32_t OK = 0; constexpr int32_t ERR = -1; constexpr int32_t EXCEED_MAX_LENGTH = -2; -constexpr int32_t DEFAULT_BUF_SIZE = 1024; constexpr int32_t BUF_CACHE_MARGIN = 4; constexpr int32_t ASYNC_RST_SIZE = 2; -constexpr int32_t MAX_VALUE_LENGTH = 8 * DEFAULT_BUF_SIZE; +constexpr int32_t MAX_VALUE_LENGTH = 16 * 1024 * 1024; constexpr int32_t SYNC_RESULT_ELEMNT_NUM = 2; constexpr const char* GLOBAL_JSON = "JSON"; constexpr const char* GLOBAL_STRINGIFY = "stringify"; constexpr const char* GLOBAL_PARSE = "parse"; +constexpr const char* GLOBAL_PARSE_SENDABLE = "parseSendable"; bool Equals(napi_env env, napi_value value, napi_ref copy); @@ -80,7 +80,7 @@ napi_value Convert2JSValue(napi_env env, const std::monostate &value); napi_valuetype GetValueType(napi_env env, napi_value value); std::tuple JsonStringify(napi_env env, napi_value value); -napi_value JsonParse(napi_env env, const std::string &inStr); +napi_value JsonParse(napi_env env, const std::string &inStr, bool sendable = false); template std::enable_if_t, napi_value> Convert2JSValue(napi_env env, const T &value); diff --git a/preferences/frameworks/js/napi/common/include/js_observer.h b/preferences/frameworks/js/napi/common/include/js_observer.h index c437befc..fe8f87a2 100644 --- a/preferences/frameworks/js/napi/common/include/js_observer.h +++ b/preferences/frameworks/js/napi/common/include/js_observer.h @@ -22,17 +22,18 @@ namespace OHOS::PreferencesJsKit { class JSObserver : public std::enable_shared_from_this { public: - JSObserver(std::shared_ptr uvQueue, napi_value callback); + JSObserver(std::shared_ptr uvQueue, napi_value callback, bool sendable); virtual ~JSObserver(); napi_ref GetCallback(); void ClearCallback(); - + napi_env GetEnv(); protected: void AsyncCall(UvQueue::NapiArgsGenerator genArgs = UvQueue::NapiArgsGenerator()); private: - std::shared_ptr uvQueue_; + std::weak_ptr uvQueue_; napi_ref callback_; + bool sendabel_; }; } // namespace OHOS::PreferencesJsKit #endif // OHOS_JS_OBSERVER_H diff --git a/preferences/frameworks/js/napi/common/include/js_proxy.h b/preferences/frameworks/js/napi/common/include/js_proxy.h new file mode 100644 index 00000000..abdd7b2c --- /dev/null +++ b/preferences/frameworks/js/napi/common/include/js_proxy.h @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2023 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef DISTRIBUTEDDATAMGR_APPDATAMGR_JSPROXY_H +#define DISTRIBUTEDDATAMGR_APPDATAMGR_JSPROXY_H +#include +namespace OHOS::JSProxy { +template +class JSCreator { +public: + // This method will be used to call different subclasses for implementation + virtual std::shared_ptr Create() = 0; + +protected: + // It is not allowed to directly use parent class objects for construction and destruction + JSCreator() = default; + ~JSCreator() = default; +}; + +template +class JSProxy { +public: + void SetInstance(std::shared_ptr instance) + { + instance_ = std::move(instance); + } + + std::shared_ptr GetInstance() const + { + return instance_; + } + +protected: + // It is not allowed to directly use parent class objects for construction and destruction + JSProxy() = default; + ~JSProxy() = default; + +private: + std::shared_ptr instance_; +}; + +template +class JSEntity : public JSCreator, public JSProxy { +protected: + // It is not allowed to directly use parent class objects for construction and destruction + JSEntity() = default; + ~JSEntity() = default; +}; +} // namespace OHOS::JSProxy +#endif // DISTRIBUTEDDATAMGR_APPDATAMGR_JSPROXY_H diff --git a/preferences/frameworks/js/napi/common/include/js_sendable_utils.h b/preferences/frameworks/js/napi/common/include/js_sendable_utils.h new file mode 100644 index 00000000..1823af4a --- /dev/null +++ b/preferences/frameworks/js/napi/common/include/js_sendable_utils.h @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_PREFERENCES_JS_COMMON_JS_SENDABLE_UTILS_H +#define OHOS_PREFERENCES_JS_COMMON_JS_SENDABLE_UTILS_H +#include + +#include +#include +#include +#include +#include +#include + +#include "napi/native_api.h" +#include "napi/native_common.h" +#include "js_native_api_types.h" +#include "log_print.h" +#include "napi/native_node_api.h" +#include "napi_preferences_error.h" +#include "preferences_value.h" + +namespace OHOS::Sendable::JSPreferences { +namespace Utils { +using Object = NativePreferences::Object; +using BigInt = NativePreferences::BigInt; +int32_t ConvertFromSendable(napi_env env, napi_value jsValue, bool &output); +int32_t ConvertFromSendable(napi_env env, napi_value jsValue, float &output); +int32_t ConvertFromSendable(napi_env env, napi_value jsValue, double &output); +int32_t ConvertFromSendable(napi_env env, napi_value jsValue, int32_t &output); +int32_t ConvertFromSendable(napi_env env, napi_value jsValue, int64_t &output); +int32_t ConvertFromSendable(napi_env env, napi_value jsValue, std::vector &output); +int32_t ConvertFromSendable(napi_env env, napi_value jsValue, std::string &output); +int32_t ConvertFromSendable(napi_env env, napi_value jsValue, Object &output); +int32_t ConvertFromSendable(napi_env env, napi_value jsValue, BigInt &output); +int32_t ConvertFromSendable(napi_env env, napi_value jsValue, std::monostate &value); + +template +int32_t ConvertFromSendable(napi_env env, napi_value jsValue, std::vector &value); + +template +int32_t ConvertFromSendable(napi_env env, napi_value jsValue, std::variant &value); + +napi_value ConvertToSendable(napi_env env, int32_t value); +napi_value ConvertToSendable(napi_env env, int64_t value); +napi_value ConvertToSendable(napi_env env, uint32_t value); +napi_value ConvertToSendable(napi_env env, bool value); +napi_value ConvertToSendable(napi_env env, float value); +napi_value ConvertToSendable(napi_env env, double value); +napi_value ConvertToSendable(napi_env env, const std::vector &value); +napi_value ConvertToSendable(napi_env env, const std::string &value); +napi_value ConvertToSendable(napi_env env, const OHOS::NativePreferences::Object &value); +napi_value ConvertToSendable(napi_env env, const BigInt &value); +napi_value ConvertToSendable(napi_env env, const std::monostate &value); +template +std::enable_if_t, napi_value> ConvertToSendable(napi_env env, const T &value); +template +std::enable_if_t, napi_value> ConvertToSendable(napi_env env, T value); + +template +napi_value ConvertToSendable(napi_env env, const std::vector &value); + +template +napi_value ConvertToSendable(napi_env env, const std::variant &value); + +template +int32_t GetCPPValue(napi_env env, napi_value jsValue, T &value) +{ + napi_valuetype type; + napi_typeof(env, jsValue, &type); + LOG_ERROR("parameter type error, jsValue type is %{public}d", type); + return napi_invalid_arg; +} + +template +int32_t GetCPPValue(napi_env env, napi_value jsValue, T &value) +{ + First cValue; + auto ret = ConvertFromSendable(env, jsValue, cValue); + if (ret != PreferencesJsKit::NAPI_TYPE_ERROR) { + value = cValue; + return ret; + } + return GetCPPValue(env, jsValue, value); +} + +template +napi_value GetSendableValue(napi_env env, const T &value) +{ + return nullptr; +} + +template +napi_value GetSendableValue(napi_env env, const T &value) +{ + auto *val = std::get_if(&value); + if (val != nullptr) { + return ConvertToSendable(env, *val); + } + return GetSendableValue(env, value); +} +} // namespace Utils + +template +int32_t Utils::ConvertFromSendable(napi_env env, napi_value jsValue, std::vector &value) +{ + bool isArray = false; + napi_is_array(env, jsValue, &isArray); + if (!isArray) { + return PreferencesJsKit::NAPI_TYPE_ERROR; + } + + uint32_t arrLen = 0; + napi_get_array_length(env, jsValue, &arrLen); + if (arrLen == 0) { + return napi_ok; + } + + for (size_t i = 0; i < arrLen; ++i) { + napi_value element; + napi_get_element(env, jsValue, i, &element); + T item; + auto status = ConvertFromSendable(env, element, item); + if (status != napi_ok) { + return status; + } + value.push_back(std::move(item)); + } + return napi_ok; +} + +template +int32_t Utils::ConvertFromSendable(napi_env env, napi_value jsValue, std::variant &value) +{ + return GetCPPValue(env, jsValue, value); +} + +template +napi_value Utils::ConvertToSendable(napi_env env, const std::vector &value) +{ + napi_value jsValue; + napi_status status = napi_create_sendable_array_with_length(env, value.size(), &jsValue); + if (status != napi_ok) { + return nullptr; + } + + for (size_t i = 0; i < value.size(); ++i) { + napi_set_element(env, jsValue, i, ConvertToSendable(env, static_cast(value[i]))); + } + return jsValue; +} + +template +napi_value Utils::ConvertToSendable(napi_env env, const std::variant &value) +{ + return GetSendableValue(env, value); +} +} // namespace OHOS::Sendable::JSPreferences +#endif // OHOS_PREFERENCES_JS_COMMON_JS_SENDABLE_UTILS_H diff --git a/preferences/frameworks/js/napi/common/include/napi_async_call.h b/preferences/frameworks/js/napi/common/include/napi_async_call.h index 823b2636..b7ac0946 100644 --- a/preferences/frameworks/js/napi/common/include/napi_async_call.h +++ b/preferences/frameworks/js/napi/common/include/napi_async_call.h @@ -18,7 +18,7 @@ #include #include -#include "js_utils.h" +#include "js_common_utils.h" #include "napi/native_api.h" #include "napi/native_common.h" #include "napi/native_node_api.h" @@ -43,6 +43,7 @@ public: napi_env env_ = nullptr; bool isAsync_ = true; + bool sendable_ = false; void *boundObj = nullptr; int execCode_ = ERR; std::shared_ptr error; diff --git a/preferences/frameworks/js/napi/common/include/napi_preferences_error.h b/preferences/frameworks/js/napi/common/include/napi_preferences_error.h index 0a4e7512..3f220889 100644 --- a/preferences/frameworks/js/napi/common/include/napi_preferences_error.h +++ b/preferences/frameworks/js/napi/common/include/napi_preferences_error.h @@ -16,6 +16,7 @@ #define PRE_JS_NAPI_ERROR_H #include +#include #include "log_print.h" #include "preferences_errno.h" @@ -32,15 +33,18 @@ constexpr int E_INVALID_PARAM = 401; constexpr int E_INNER_ERROR = 15500000; constexpr int E_NOT_STAGE_MODE = 15501001; constexpr int E_DATA_GROUP_ID_INVALID = 15501002; - -const static std::map ERROR_MAPS = { - { E_NOT_STAGE_MODE, "Only supported in stage mode" }, - { E_DATA_GROUP_ID_INVALID, "The data group id is not valid" }, - { NativePreferences::E_NOT_SUPPORTED, "Capability not supported" }, - { NativePreferences::E_GET_DATAOBSMGRCLIENT_FAIL, "Failed to obtain subscription service." }, - { NativePreferences::E_DELETE_FILE_FAIL, "Failed to delete preferences file." } +constexpr int E_NOT_SUPPORTED = 801; +constexpr int E_GET_DATAOBSMGRCLIENT_FAIL = 15500019; +constexpr int E_DELETE_FILE_FAIL = 15500010; + +struct JsErrorCode { + int32_t nativeCode; + int32_t jsCode; + const char *message; }; +const std::optional GetJsErrorCode(int32_t errorCode); + #define PRE_REVT_NOTHING #define PRE_NAPI_ASSERT_BASE(env, assertion, error, retVal) \ @@ -116,10 +120,11 @@ public: InnerError(int code) { - auto iter = ERROR_MAPS.find(code); - if (iter != ERROR_MAPS.end()) { - code_ = code; - msg_ = iter->second; + auto errorMsg = GetJsErrorCode(code); + if (errorMsg.has_value()) { + auto napiError = errorMsg.value(); + code_ = napiError.jsCode; + msg_ = napiError.message; } else { code_ = E_INNER_ERROR; msg_ = "Inner error. Error code " + std::to_string(code); diff --git a/preferences/frameworks/js/napi/common/include/napi_preferences_observer.h b/preferences/frameworks/js/napi/common/include/napi_preferences_observer.h index 62e31b6d..04eb74ad 100644 --- a/preferences/frameworks/js/napi/common/include/napi_preferences_observer.h +++ b/preferences/frameworks/js/napi/common/include/napi_preferences_observer.h @@ -26,7 +26,7 @@ class JSPreferencesObserver : public OHOS::NativePreferences::PreferencesObserver, public JSObserver { public: - JSPreferencesObserver(std::shared_ptr uvQueue, napi_value callback); + JSPreferencesObserver(std::shared_ptr uvQueue, napi_value callback, bool sendable = false); virtual ~JSPreferencesObserver() = default; void OnChange(const std::string &key) override; void OnChange(const std::map &records) override; diff --git a/preferences/frameworks/js/napi/common/include/uv_queue.h b/preferences/frameworks/js/napi/common/include/uv_queue.h index 21d5da88..87b04cde 100644 --- a/preferences/frameworks/js/napi/common/include/uv_queue.h +++ b/preferences/frameworks/js/napi/common/include/uv_queue.h @@ -23,19 +23,20 @@ namespace OHOS::PreferencesJsKit { class UvQueue final { public: - using NapiArgsGenerator = std::function; + using NapiArgsGenerator = std::function; using NapiCallbackGetter = std::function; UvQueue(napi_env env); ~UvQueue(); napi_env GetEnv(); - void AsyncCall(NapiCallbackGetter getter, NapiArgsGenerator genArgs = NapiArgsGenerator()); + void AsyncCall(NapiCallbackGetter getter, NapiArgsGenerator genArgs = NapiArgsGenerator(), bool sendable = false); private: static void Work(uv_work_t* work, int uvstatus); struct UvEntry { napi_env env; NapiCallbackGetter callback; NapiArgsGenerator args; + bool sendable; }; napi_env env_ = nullptr; uv_loop_s* loop_ = nullptr; diff --git a/kv_store/interfaces/innerkits/distributeddata/cfi_blocklist.txt b/preferences/frameworks/js/napi/common/libcommon.map similarity index 50% rename from kv_store/interfaces/innerkits/distributeddata/cfi_blocklist.txt rename to preferences/frameworks/js/napi/common/libcommon.map index ceff6b4c..685321aa 100644 --- a/kv_store/interfaces/innerkits/distributeddata/cfi_blocklist.txt +++ b/preferences/frameworks/js/napi/common/libcommon.map @@ -1,21 +1,35 @@ -# Copyright (c) 2023 Huawei Device Co., Ltd. -# Licensed under the Apache License, Version 2.0 (the "License"); +# Copyright (c) 2024 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License")*; # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# +# +# http://www.apache.org/licenses/LICENSE-2.0 +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - - [cfi] - type:*OHOS::Parcel* - type:*OHOS::RefBase* - type:*OHOS::MessageParcel* - type:*OHOS::IRemoteObject* - type:*OHOS::IRemoteBroker* - src:*commonlibrary/c_utils/base/include/refbase.h - src:*/foundation/communication/ipc/interfaces/innerkits/ipc_core/include/iremote_broker.h \ No newline at end of file + +1.0 { + global: + *g_async*; + *g_sync*; + *Equals*; + *UvQueue*; + *JSAbility*; + *GetContextInfo*; + *Convert2NativeValue*; + *Convert2JSValue*; + *JSObserver*; + *ConvertFromSendable*; + *ConvertToSendable*; + *BaseContext*; + *ParamTypeError*; + *InnerError*; + *ParamNumError*; + *JSPreferencesObserver*; + *GetJsErrorCode*; + local: + *; +}; \ No newline at end of file diff --git a/preferences/frameworks/js/napi/common/mock/cross_platform/src/js_ability.cpp b/preferences/frameworks/js/napi/common/mock/cross_platform/src/js_ability.cpp index 955655c5..b16359cf 100644 --- a/preferences/frameworks/js/napi/common/mock/cross_platform/src/js_ability.cpp +++ b/preferences/frameworks/js/napi/common/mock/cross_platform/src/js_ability.cpp @@ -29,7 +29,7 @@ std::shared_ptr GetContextInfo(napi_env env, napi_value value, const std::string &dataGroupId, ContextInfo &contextInfo) { if (!dataGroupId.empty()) { - return std::make_shared(NativePreferences::E_NOT_SUPPORTED); + return std::make_shared(E_NOT_SUPPORTED); } auto stageContext = AbilityRuntime::Platform::GetStageModeContext(env, value); if (stageContext == nullptr) { diff --git a/preferences/frameworks/js/napi/common/mock/src/js_ability.cpp b/preferences/frameworks/js/napi/common/mock/src/js_ability.cpp index ea4e9bd4..5403c34d 100644 --- a/preferences/frameworks/js/napi/common/mock/src/js_ability.cpp +++ b/preferences/frameworks/js/napi/common/mock/src/js_ability.cpp @@ -31,7 +31,7 @@ std::shared_ptr GetContextInfo(napi_env env, napi_value value, const std::string &dataGroupId, ContextInfo &contextInfo) { if (!dataGroupId.empty()) { - return std::make_shared(NativePreferences::E_NOT_SUPPORTED); + return std::make_shared(E_NOT_SUPPORTED); } std::string baseDir = ""; #ifdef WINDOWS_PLATFORM diff --git a/preferences/frameworks/js/napi/common/src/js_utils.cpp b/preferences/frameworks/js/napi/common/src/js_common_utils.cpp similarity index 95% rename from preferences/frameworks/js/napi/common/src/js_utils.cpp rename to preferences/frameworks/js/napi/common/src/js_common_utils.cpp index 5828274b..ded3d1ec 100644 --- a/preferences/frameworks/js/napi/common/src/js_utils.cpp +++ b/preferences/frameworks/js/napi/common/src/js_common_utils.cpp @@ -13,13 +13,14 @@ * limitations under the License. */ -#include "js_utils.h" +#include "js_common_utils.h" #include #include #include #include "hilog/log_c.h" #include "js_native_api.h" #include "js_native_api_types.h" +#include "log_print.h" #ifndef MAC_PLATFORM #include "securec.h" @@ -104,7 +105,7 @@ int32_t JSUtils::Convert2NativeValue(napi_env env, napi_value jsValue, std::vect bool isTypedarray = false; napi_status result = napi_is_typedarray(env, jsValue, &isTypedarray); if (result != napi_ok || !isTypedarray) { - LOG_DEBUG("napi_is_typedarray fail %{public}d", result); + LOG_DEBUG("napi_is_typedarray fail. result %{public}d isTypedarray %{public}d", result, isTypedarray); return NAPI_TYPE_ERROR; } napi_typedarray_type type = napi_uint8_array; @@ -173,7 +174,7 @@ int32_t JSUtils::Convert2NativeValue(napi_env env, napi_value jsValue, std::mono bool JSUtils::Equals(napi_env env, napi_value value, napi_ref copy) { - if (copy == nullptr) { + if (copy == nullptr || env == nullptr) { return (value == nullptr); } @@ -329,7 +330,7 @@ std::tuple JSUtils::JsonStringify(napi_env env, napi_va return std::make_tuple(napi_ok, res); } -napi_value JSUtils::JsonParse(napi_env env, const std::string &inStr) +napi_value JSUtils::JsonParse(napi_env env, const std::string &inStr, bool sendable) { if (inStr.empty()) { LOG_ERROR("JsonParse failed, inStr is empty"); @@ -339,17 +340,18 @@ napi_value JSUtils::JsonParse(napi_env env, const std::string &inStr) napi_value global = nullptr; PRE_CHECK_RETURN_CORE(napi_get_global(env, &global) == napi_ok, PRE_REVT_NOTHING, nullptr); napi_value json = nullptr; - PRE_CHECK_RETURN_CORE(napi_get_named_property(env, global, GLOBAL_JSON, &json) == napi_ok, - PRE_REVT_NOTHING, nullptr); + PRE_CHECK_RETURN_CORE( + napi_get_named_property(env, global, GLOBAL_JSON, &json) == napi_ok, PRE_REVT_NOTHING, nullptr); napi_value parse = nullptr; - PRE_CHECK_RETURN_CORE(napi_get_named_property(env, json, GLOBAL_PARSE, &parse) == napi_ok, + PRE_CHECK_RETURN_CORE( + napi_get_named_property(env, json, sendable ? GLOBAL_PARSE_SENDABLE : GLOBAL_PARSE, &parse) == napi_ok, PRE_REVT_NOTHING, nullptr); if (GetValueType(env, parse) != napi_function) { LOG_ERROR("Get parse func failed"); return nullptr; } napi_value res = nullptr; - napi_value argv[1] = {jsValue}; + napi_value argv[1] = { jsValue }; PRE_CHECK_RETURN_CORE(napi_call_function(env, json, parse, 1, argv, &res) == napi_ok, PRE_REVT_NOTHING, nullptr); return res; } diff --git a/preferences/frameworks/js/napi/common/src/js_observer.cpp b/preferences/frameworks/js/napi/common/src/js_observer.cpp index 40cb50f7..6de1fece 100644 --- a/preferences/frameworks/js/napi/common/src/js_observer.cpp +++ b/preferences/frameworks/js/napi/common/src/js_observer.cpp @@ -16,10 +16,10 @@ #include "js_observer.h" namespace OHOS::PreferencesJsKit { -JSObserver::JSObserver(std::shared_ptr uvQueue, napi_value callback) - : uvQueue_(uvQueue) +JSObserver::JSObserver(std::shared_ptr uvQueue, napi_value callback, bool sendable) + : uvQueue_(uvQueue), sendabel_(sendable) { - napi_create_reference(uvQueue_->GetEnv(), callback, 1, &callback_); + napi_create_reference(uvQueue->GetEnv(), callback, 1, &callback_); } JSObserver::~JSObserver() @@ -36,8 +36,22 @@ void JSObserver::ClearCallback() if (callback_ == nullptr) { return; } - napi_delete_reference(uvQueue_->GetEnv(), callback_); - callback_ = nullptr; + auto uvQueue = uvQueue_.lock(); + if (uvQueue != nullptr) { + napi_delete_reference(uvQueue->GetEnv(), callback_); + callback_ = nullptr; + } +} + + +napi_env JSObserver::GetEnv() +{ + auto uvQueue = uvQueue_.lock(); + if (uvQueue != nullptr) { + return uvQueue->GetEnv(); + } + + return nullptr; } void JSObserver::AsyncCall(UvQueue::NapiArgsGenerator genArgs) @@ -45,8 +59,11 @@ void JSObserver::AsyncCall(UvQueue::NapiArgsGenerator genArgs) if (callback_ == nullptr) { return; } - - uvQueue_->AsyncCall( + auto uvQueue = uvQueue_.lock(); + if (uvQueue == nullptr) { + return; + } + uvQueue->AsyncCall( [observer = shared_from_this()](napi_env env) -> napi_value { // the lambda run in js main thread, so it serial run with Clear(), so we can use no lock. if (observer->callback_ == nullptr) { @@ -56,6 +73,6 @@ void JSObserver::AsyncCall(UvQueue::NapiArgsGenerator genArgs) napi_get_reference_value(env, observer->callback_, &callback); return callback; }, - genArgs); + genArgs, sendabel_); } } // namespace OHOS::DistributedKVStore diff --git a/preferences/frameworks/js/napi/common/src/js_sendable_utils.cpp b/preferences/frameworks/js/napi/common/src/js_sendable_utils.cpp new file mode 100644 index 00000000..eb459246 --- /dev/null +++ b/preferences/frameworks/js/napi/common/src/js_sendable_utils.cpp @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "js_sendable_utils.h" + +#include "js_common_utils.h" +#include "napi_preferences_error.h" +#include "node_api.h" + +namespace OHOS::Sendable::JSPreferences { +using namespace PreferencesJsKit::JSUtils; +namespace Utils { + +int32_t ConvertFromSendable(napi_env env, napi_value jsValue, bool &output) +{ + return Convert2NativeValue(env, jsValue, output); +} + +int32_t ConvertFromSendable(napi_env env, napi_value jsValue, float &output) +{ + return Convert2NativeValue(env, jsValue, output); +} + +int32_t ConvertFromSendable(napi_env env, napi_value jsValue, double &output) +{ + return Convert2NativeValue(env, jsValue, output); +} + +int32_t ConvertFromSendable(napi_env env, napi_value jsValue, int32_t &output) +{ + return Convert2NativeValue(env, jsValue, output); +} + +int32_t ConvertFromSendable(napi_env env, napi_value jsValue, int64_t &output) +{ + return Convert2NativeValue(env, jsValue, output); +} + +int32_t ConvertFromSendable(napi_env env, napi_value jsValue, std::vector &output) +{ + return Convert2NativeValue(env, jsValue, output); +} + +int32_t ConvertFromSendable(napi_env env, napi_value jsValue, std::string &output) +{ + return Convert2NativeValue(env, jsValue, output); +} + +int32_t ConvertFromSendable(napi_env env, napi_value jsValue, Object &output) +{ + return Convert2NativeValue(env, jsValue, output); +} + +int32_t ConvertFromSendable(napi_env env, napi_value jsValue, BigInt &output) +{ + return Convert2NativeValue(env, jsValue, output); +} + +int32_t ConvertFromSendable(napi_env env, napi_value jsValue, std::monostate &value) +{ + return Convert2NativeValue(env, jsValue, value); +} + +napi_value ConvertToSendable(napi_env env, int32_t value) +{ + return Convert2JSValue(env, value); +} + +napi_value ConvertToSendable(napi_env env, int64_t value) +{ + return Convert2JSValue(env, value); +} + +napi_value ConvertToSendable(napi_env env, uint32_t value) +{ + return Convert2JSValue(env, value); +} + +napi_value ConvertToSendable(napi_env env, bool value) +{ + return Convert2JSValue(env, value); +} + +napi_value ConvertToSendable(napi_env env, float value) +{ + return Convert2JSValue(env, value); +} + +napi_value ConvertToSendable(napi_env env, double value) +{ + return Convert2JSValue(env, value); +} + +napi_value ConvertToSendable(napi_env env, const std::vector &value) +{ + size_t size = value.size(); + void *data = nullptr; + napi_value buffer = nullptr; + napi_status ret = napi_create_sendable_arraybuffer(env, size, &data, &buffer); + if (ret != napi_ok) { + LOG_ERROR("napi_create_sendable_arraybuffer failed %{public}d", ret); + return nullptr; + } + if (size != 0) { + std::copy(value.begin(), value.end(), static_cast(data)); + } + napi_value sendableValue = nullptr; + ret = napi_create_sendable_typedarray(env, napi_uint8_array, size, buffer, 0, &sendableValue); + if (ret != napi_ok) { + LOG_ERROR("napi_create_sendable_typedarray failed %{public}d", ret); + return nullptr; + } + return sendableValue; +} + +napi_value ConvertToSendable(napi_env env, const std::string &value) +{ + return Convert2JSValue(env, value); +} + +napi_value ConvertToSendable(napi_env env, const OHOS::NativePreferences::Object &value) +{ + napi_value sendableValue = JsonParse(env, value.valueStr, true); + if (sendableValue == nullptr) { + LOG_ERROR("Convert object failed"); + } + return sendableValue; +} + +napi_value ConvertToSendable(napi_env env, const BigInt &value) +{ + return Convert2JSValue(env, value); +} + +napi_value ConvertToSendable(napi_env env, const std::monostate &value) +{ + return Convert2JSValue(env, value); +} +} // namespace Utils +} // namespace OHOS::Sendable::JSPreferences \ No newline at end of file diff --git a/preferences/frameworks/js/napi/common/src/napi_async_call.cpp b/preferences/frameworks/js/napi/common/src/napi_async_call.cpp index 178e6b1b..1fa2622b 100644 --- a/preferences/frameworks/js/napi/common/src/napi_async_call.cpp +++ b/preferences/frameworks/js/napi/common/src/napi_async_call.cpp @@ -31,10 +31,11 @@ void BaseContext::SetAction( napi_value argv[MAX_INPUT_COUNT] = { nullptr }; void *data = nullptr; napi_status status = napi_get_cb_info(env, info, &argc, argv, &self, &data); + napi_is_sendable(env, self, &sendable_); napi_valuetype valueType = napi_undefined; if (status == napi_ok && argc > 0) { napi_typeof(env, argv[argc - 1], &valueType); - if (valueType == napi_function) { + if (!sendable_ && valueType == napi_function) { status = napi_create_reference(env, argv[argc - 1], 1, &callback_); argc = argc - 1; } @@ -55,7 +56,6 @@ void BaseContext::SetAction( output_ = std::move(output); exec_ = std::move(exec); - napi_create_reference(env, self, 1, &self_); } @@ -83,13 +83,16 @@ void AsyncCall::SetBusinessError(napi_env env, napi_value *businessError, std::s { napi_value code = nullptr; napi_value msg = nullptr; - napi_create_object(env, businessError); // if error is not inner error if (error != nullptr && error->GetCode() != E_INVALID_PARAM) { napi_create_int32(env, error->GetCode(), &code); napi_create_string_utf8(env, error->GetMsg().c_str(), NAPI_AUTO_LENGTH, &msg); - napi_set_named_property(env, *businessError, "code", code); - napi_set_named_property(env, *businessError, "message", msg); + napi_property_descriptor descriptors[] = { + DECLARE_NAPI_DEFAULT_PROPERTY("code", code), + DECLARE_NAPI_DEFAULT_PROPERTY("message", msg), + }; + // 2 represents the current number of incorrect object attributes + napi_create_object_with_properties(env, businessError, 2, descriptors); } } @@ -185,7 +188,7 @@ void AsyncCall::OnReturn(napi_env env, napi_status status, void *data) } else { napi_reject_deferred(env, context->defer_, result[ARG_ERROR]); } - } else { + } else if (!context->sendable_) { // callback napi_value callback = nullptr; napi_get_reference_value(env, context->callback_, &callback); diff --git a/preferences/frameworks/js/napi/common/src/napi_preferences_error.cpp b/preferences/frameworks/js/napi/common/src/napi_preferences_error.cpp new file mode 100644 index 00000000..02e60ebe --- /dev/null +++ b/preferences/frameworks/js/napi/common/src/napi_preferences_error.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "napi_preferences_error.h" + +namespace OHOS { +namespace PreferencesJsKit { + +static constexpr JsErrorCode JS_ERROR_MAPS[] = { + { E_NOT_STAGE_MODE, E_NOT_STAGE_MODE, "Only supported in stage mode" }, + { E_DATA_GROUP_ID_INVALID, E_DATA_GROUP_ID_INVALID, "The data group id is not valid" }, + { NativePreferences::E_DELETE_FILE_FAIL, E_DELETE_FILE_FAIL, "Failed to delete preferences file." }, + { NativePreferences::E_GET_DATAOBSMGRCLIENT_FAIL, E_GET_DATAOBSMGRCLIENT_FAIL, + "Failed to obtain subscription service." }, + { NativePreferences::E_NOT_SUPPORTED, E_NOT_SUPPORTED, "Capability not supported" }, +}; + +const std::optional GetJsErrorCode(int32_t errorCode) +{ + auto jsErrorCode = JsErrorCode{ errorCode, -1, "" }; + auto iter = std::lower_bound(JS_ERROR_MAPS, JS_ERROR_MAPS + sizeof(JS_ERROR_MAPS) / sizeof(JS_ERROR_MAPS[0]), + jsErrorCode, [](const JsErrorCode &jsErrorCode1, const JsErrorCode &jsErrorCode2) { + return jsErrorCode1.nativeCode < jsErrorCode2.nativeCode; + }); + if (iter < JS_ERROR_MAPS + sizeof(JS_ERROR_MAPS) / sizeof(JS_ERROR_MAPS[0]) && iter->nativeCode == errorCode) { + return *iter; + } + return std::nullopt; +} + +} // namespace PreferencesJsKit +} // namespace OHOS diff --git a/preferences/frameworks/js/napi/common/src/napi_preferences_observer.cpp b/preferences/frameworks/js/napi/common/src/napi_preferences_observer.cpp index 8a2721fd..79d817e4 100644 --- a/preferences/frameworks/js/napi/common/src/napi_preferences_observer.cpp +++ b/preferences/frameworks/js/napi/common/src/napi_preferences_observer.cpp @@ -14,38 +14,38 @@ */ #include "napi_preferences_observer.h" -#include "js_utils.h" +#include "js_common_utils.h" +#include "js_sendable_utils.h" using namespace OHOS::NativePreferences; - +using namespace OHOS::Sendable::JSPreferences; namespace OHOS { namespace PreferencesJsKit { -JSPreferencesObserver::JSPreferencesObserver(std::shared_ptr uvQueue, napi_value callback) - : JSObserver(uvQueue, callback) +JSPreferencesObserver::JSPreferencesObserver(std::shared_ptr uvQueue, napi_value callback, bool sendabel) + : JSObserver(uvQueue, callback, sendabel) { } void JSPreferencesObserver::OnChange(const std::string &key) { - AsyncCall([key](napi_env env, int &argc, napi_value *argv) { + AsyncCall([key](napi_env env, bool sendable, int &argc, napi_value *argv) { argc = 1; - argv[0] = JSUtils::Convert2JSValue(env, key); + argv[0] = sendable ? Utils::ConvertToSendable(env, key) : JSUtils::Convert2JSValue(env, key); }); LOG_DEBUG("OnChange key end"); } void JSPreferencesObserver::OnChange(const std::map &records) { - AsyncCall([records](napi_env env, int &argc, napi_value *argv) { + AsyncCall([records](napi_env env, bool sendable, int &argc, napi_value *argv) { napi_value result; - int errCode = napi_create_object(env, &result); - if (errCode != napi_ok) { - LOG_ERROR("napi_create_object failed, onChange return."); - return; - } + std::vector descriptors; for (const auto &[key, value] : records) { - napi_set_named_property(env, result, key.c_str(), JSUtils::Convert2JSValue(env, value.value_)); + descriptors.push_back(napi_property_descriptor( + DECLARE_NAPI_DEFAULT_PROPERTY(key.c_str(), Utils::ConvertToSendable(env, value.value_)))); } + sendable ? napi_create_sendable_object_with_properties(env, descriptors.size(), descriptors.data(), &result) + : napi_create_object_with_properties(env, &result, descriptors.size(), descriptors.data()); argc = 1; argv[0] = result; }); diff --git a/preferences/frameworks/js/napi/common/src/uv_queue.cpp b/preferences/frameworks/js/napi/common/src/uv_queue.cpp index f1f044d8..bcd070a5 100644 --- a/preferences/frameworks/js/napi/common/src/uv_queue.cpp +++ b/preferences/frameworks/js/napi/common/src/uv_queue.cpp @@ -34,7 +34,7 @@ UvQueue::~UvQueue() env_ = nullptr; } -void UvQueue::AsyncCall(NapiCallbackGetter getter, NapiArgsGenerator genArgs) +void UvQueue::AsyncCall(NapiCallbackGetter getter, NapiArgsGenerator genArgs, bool sendable) { if (loop_ == nullptr || !getter) { LOG_ERROR("loop_ or callback is nullptr"); @@ -45,7 +45,7 @@ void UvQueue::AsyncCall(NapiCallbackGetter getter, NapiArgsGenerator genArgs) if (work == nullptr) { return; } - work->data = new (std::nothrow) UvEntry{ env_, getter, std::move(genArgs) }; + work->data = new (std::nothrow) UvEntry{ env_, getter, std::move(genArgs), sendable }; if (work->data == nullptr) { delete work; return; @@ -79,7 +79,7 @@ void UvQueue::Work(uv_work_t* work, int uvstatus) napi_value argv[MAX_CALLBACK_ARG_NUM] = { nullptr }; if (entry->args) { argc = MAX_CALLBACK_ARG_NUM; - entry->args(entry->env, argc, argv); + entry->args(entry->env, entry->sendable, argc, argv); } LOG_DEBUG("queue uv_after_work_cb"); napi_value global = nullptr; diff --git a/preferences/frameworks/js/napi/preferences/BUILD.gn b/preferences/frameworks/js/napi/preferences/BUILD.gn index c1423133..ba4e34cb 100644 --- a/preferences/frameworks/js/napi/preferences/BUILD.gn +++ b/preferences/frameworks/js/napi/preferences/BUILD.gn @@ -14,18 +14,37 @@ import("//build/ohos.gni") import("//build/ohos/ace/ace.gni") import("//foundation/distributeddatamgr/preferences/preferences.gni") -base_include = [ - "${preferences_napi_path}/common/include", - "${preferences_napi_path}/preferences/include", - "${preferences_base_path}/frameworks/common/include", -] +config("preferences_public_config") { + visibility = [ ":*" ] + include_dirs = [ "include" ] +} + +config("preferences_config") { + visibility = [ ":*" ] + include_dirs = [ + "include", + "${preferences_base_path}/frameworks/common/include", + ] +} + +if (!is_ohos) { + base_include = [ + "${preferences_napi_path}/common/include", + "${preferences_napi_path}/preferences/include", + "${preferences_base_path}/frameworks/common/include", + ] + common_sources = [ + "${preferences_napi_path}/common/src/js_common_utils.cpp", + "${preferences_napi_path}/common/src/js_observer.cpp", + "${preferences_napi_path}/common/src/js_sendable_utils.cpp", + "${preferences_napi_path}/common/src/napi_async_call.cpp", + "${preferences_napi_path}/common/src/napi_preferences_error.cpp", + "${preferences_napi_path}/common/src/napi_preferences_observer.cpp", + "${preferences_napi_path}/common/src/uv_queue.cpp", + ] +} base_sources = [ - "${preferences_napi_path}/common/src/js_observer.cpp", - "${preferences_napi_path}/common/src/js_utils.cpp", - "${preferences_napi_path}/common/src/napi_async_call.cpp", - "${preferences_napi_path}/common/src/napi_preferences_observer.cpp", - "${preferences_napi_path}/common/src/uv_queue.cpp", "${preferences_napi_path}/preferences/src/entry_point.cpp", "${preferences_napi_path}/preferences/src/napi_preferences.cpp", "${preferences_napi_path}/preferences/src/napi_preferences_helper.cpp", @@ -42,19 +61,27 @@ if (is_ohos) { ohos_shared_library("preferences") { branch_protector_ret = "pac_ret" sanitize = { + boundary_sanitize = true + ubsan = true cfi = true cfi_cross_dso = true debug = false } - include_dirs = base_include sources = base_sources - sources += [ "${preferences_napi_path}/common/src/js_ability.cpp" ] + configs = [ ":preferences_config" ] + cflags_cc = [ + "-std=c++17", + "-stdlib=libc++", + ] - deps = - [ "${preferences_base_path}/interfaces/inner_api:native_preferences" ] + deps = [ + "${preferences_base_path}/interfaces/inner_api:native_preferences", + "${preferences_napi_path}/common:preferences_jscommon", + ] external_deps = [ "ability_runtime:abilitykit_native", + "ability_runtime:extensionkit_native", "ability_runtime:napi_base_context", "c_utils:utils", "hilog:libhilog", @@ -85,7 +112,7 @@ if (is_ohos) { defines = [ "WINDOWS_PLATFORM" ] } - sources = base_sources + sources = common_sources + base_sources sources += [ "${preferences_napi_path}/common/mock/src/js_ability.cpp" ] deps = [ @@ -117,7 +144,7 @@ if (is_ohos) { ] include_dirs += base_include - sources = base_sources + sources = common_sources + base_sources sources += [ "${preferences_napi_path}/common/mock/cross_platform/src/js_ability.cpp", "//foundation/appframework/ability/ability_runtime/cross_platform/interfaces/inner_api/napi_base_context/src/napi_base_context.cpp", @@ -151,7 +178,7 @@ if (is_ohos) { ] include_dirs += base_include - sources = base_sources + sources = common_sources + base_sources sources += [ "${preferences_napi_path}/common/mock/cross_platform/src/js_ability.cpp", ] diff --git a/preferences/frameworks/js/napi/preferences/include/napi_preferences.h b/preferences/frameworks/js/napi/preferences/include/napi_preferences.h index b7474a0d..952be979 100644 --- a/preferences/frameworks/js/napi/preferences/include/napi_preferences.h +++ b/preferences/frameworks/js/napi/preferences/include/napi_preferences.h @@ -22,7 +22,7 @@ #include #include "js_observer.h" -#include "js_utils.h" +#include "js_common_utils.h" #include "napi/native_api.h" #include "napi/native_common.h" #include "napi/native_node_api.h" diff --git a/preferences/frameworks/js/napi/preferences/src/napi_preferences.cpp b/preferences/frameworks/js/napi/preferences/src/napi_preferences.cpp index 161c8fd2..278cd0c0 100644 --- a/preferences/frameworks/js/napi/preferences/src/napi_preferences.cpp +++ b/preferences/frameworks/js/napi/preferences/src/napi_preferences.cpp @@ -148,13 +148,17 @@ int ParseKey(napi_env env, const napi_value arg, std::shared_ptrkey); PRE_CHECK_RETURN_ERR_SET(rc == napi_ok, std::make_shared("The key must be string.")); PRE_CHECK_RETURN_ERR_SET(context->key.length() <= MAX_KEY_LENGTH, - std::make_shared("The key must be less than 80 bytes.")); + std::make_shared("The key must be less than 1024 bytes.")); return OK; } int ParseDefValue(const napi_env env, const napi_value jsVal, std::shared_ptr context) { int32_t rc = JSUtils::Convert2NativeValue(env, jsVal, context->defValue.value_); + if (rc == EXCEED_MAX_LENGTH) { + PRE_CHECK_RETURN_ERR_SET(rc == napi_ok, + std::make_shared("The type of value mast be less then 16 * 1024 * 1024 btyes.")); + } PRE_CHECK_RETURN_ERR_SET(rc == napi_ok, std::make_shared("The type of value mast be ValueType.")); return OK; } @@ -448,7 +452,7 @@ bool PreferencesProxy::HasRegisteredObserver(napi_value callback, RegisterMode m (mode == RegisterMode::MULTI_PRECESS_CHANGE) ? multiProcessObservers_ : dataObservers_; for (auto &it : observers) { if (JSUtils::Equals(env_, callback, it->GetCallback())) { - LOG_INFO("The observer has already subscribed."); + LOG_DEBUG("The observer has already subscribed."); return true; } } @@ -478,7 +482,7 @@ int PreferencesProxy::RegisteredObserver(napi_value callback, RegisterMode mode) } observers.push_back(observer); } - LOG_INFO("The observer subscribed success."); + LOG_DEBUG("The observer subscribed success."); return E_OK; } @@ -495,7 +499,7 @@ int PreferencesProxy::UnRegisteredObserver(napi_value callback, RegisterMode mod } (*it)->ClearCallback(); it = observers.erase(it); - LOG_INFO("The observer unsubscribed success."); + LOG_DEBUG("The observer unsubscribed success."); break; // specified observer is current iterator } ++it; @@ -564,7 +568,7 @@ int PreferencesProxy::RegisteredDataObserver(const std::vector &key } observers.push_back(observer); } - LOG_INFO("The dataChange observer subscribed success."); + LOG_DEBUG("The dataChange observer subscribed success."); return E_OK; } @@ -621,7 +625,7 @@ int PreferencesProxy::UnRegisteredDataObserver(const std::vector &k ++it; } } - LOG_INFO("The dataChange observer unsubscribed success."); + LOG_DEBUG("The dataChange observer unsubscribed success."); return E_OK; } } // namespace PreferencesJsKit diff --git a/preferences/frameworks/js/napi/preferences/src/napi_preferences_helper.cpp b/preferences/frameworks/js/napi/preferences/src/napi_preferences_helper.cpp index 6af833ac..dffedc8d 100644 --- a/preferences/frameworks/js/napi/preferences/src/napi_preferences_helper.cpp +++ b/preferences/frameworks/js/napi/preferences/src/napi_preferences_helper.cpp @@ -17,7 +17,7 @@ #include #include "js_ability.h" -#include "js_utils.h" +#include "js_common_utils.h" #include "napi_async_call.h" #include "napi_preferences.h" #include "preferences_errno.h" diff --git a/preferences/frameworks/js/napi/sendable_preferences/BUILD.gn b/preferences/frameworks/js/napi/sendable_preferences/BUILD.gn new file mode 100644 index 00000000..61f56c69 --- /dev/null +++ b/preferences/frameworks/js/napi/sendable_preferences/BUILD.gn @@ -0,0 +1,71 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import("//build/ohos.gni") +import("//build/ohos/ace/ace.gni") +import("//foundation/distributeddatamgr/preferences/preferences.gni") + +base_include = [ + "${preferences_napi_path}/sendable_preferences/include", + "${preferences_base_path}/frameworks/common/include", +] + +base_sources = [ + "${preferences_napi_path}/sendable_preferences/src/entry_point.cpp", + "${preferences_napi_path}/sendable_preferences/src/napi_preferences.cpp", + "${preferences_napi_path}/sendable_preferences/src/napi_preferences_helper.cpp", +] + +if (is_ohos) { + ohos_copy("preferences_declaration") { + sources = [ "./api" ] + outputs = [ target_out_dir + "/$target_name/" ] + module_source_dir = target_out_dir + "/$target_name" + module_install_name = "" + subsystem_name = "distributeddatamgr" + part_name = "preferences" + } + + ohos_shared_library("sendablepreferences") { + branch_protector_ret = "pac_ret" + sanitize = { + boundary_sanitize = true + ubsan = true + cfi = true + cfi_cross_dso = true + debug = false + } + include_dirs = base_include + sources = base_sources + cflags_cc = [ + "-std=c++17", + "-stdlib=libc++", + ] + + deps = [ + "${preferences_base_path}/interfaces/inner_api:native_preferences", + "${preferences_napi_path}/common:preferences_jscommon", + ] + + external_deps = [ + "ability_runtime:abilitykit_native", + "ability_runtime:napi_base_context", + "c_utils:utils", + "hilog:libhilog", + "napi:ace_napi", + ] + + subsystem_name = "distributeddatamgr" + part_name = "preferences" + relative_install_dir = "module/data" + } +} diff --git a/preferences/frameworks/js/napi/sendable_preferences/include/napi_preferences.h b/preferences/frameworks/js/napi/sendable_preferences/include/napi_preferences.h new file mode 100644 index 00000000..374f49a3 --- /dev/null +++ b/preferences/frameworks/js/napi/sendable_preferences/include/napi_preferences.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PREFERENCES_JSKIT_NAPI_PREFERENCE_H +#define PREFERENCES_JSKIT_NAPI_PREFERENCE_H + +#include + +#include +#include + +#include "js_observer.h" +#include "js_proxy.h" +#include "js_common_utils.h" +#include "napi/native_api.h" +#include "napi/native_common.h" +#include "napi/native_node_api.h" +#include "napi_preferences_observer.h" +#include "preferences.h" +#include "preferences_helper.h" + +namespace OHOS::Sendable::JSPreferences { +using RegisterMode = NativePreferences::PreferencesObserver::RegisterMode; +using JSPreferencesObserver = PreferencesJsKit::JSPreferencesObserver; +using UvQueue = PreferencesJsKit::UvQueue; +using Preferences = NativePreferences::Preferences; +template +using JSProxy = OHOS::JSProxy::JSProxy; +class PreferencesProxy : public JSProxy { +public: + static void Init(napi_env env, napi_value exports); + static napi_value New(napi_env env, napi_callback_info info); + static napi_status NewInstance(napi_env env, std::shared_ptr value, napi_value *instance); + static void Destructor(napi_env env, void *nativeObject, void *finalize_hint); + +private: + static constexpr char STR_CHANGE[] = "change"; + static constexpr char STR_MULTI_PRECESS_CHANGE[] = "multiProcessChange"; + static constexpr const char *STR_DATA_CHANGE = "dataChange"; + using Observer = NativePreferences::PreferencesObserver; + using JSObserverImpl = JSPreferencesObserver; + explicit PreferencesProxy(); + ~PreferencesProxy(); + + static napi_value GetValue(napi_env env, napi_callback_info info); + static napi_value SetValue(napi_env env, napi_callback_info info); + static napi_value HasKey(napi_env env, napi_callback_info info); + static napi_value Delete(napi_env env, napi_callback_info info); + static napi_value Flush(napi_env env, napi_callback_info info); + static napi_value Clear(napi_env env, napi_callback_info info); + static napi_value RegisterObserver(napi_env env, napi_callback_info info); + static napi_value UnregisterObserver(napi_env env, napi_callback_info info); + static napi_value GetAll(napi_env env, napi_callback_info info); + + static std::pair> GetSelfInstance(napi_env env, napi_value self); + + static RegisterMode ConvertToRegisterMode(const std::string &mode); + + int RegisteredObserver(napi_env env, napi_value callback, RegisterMode mode, const std::vector &keys); + int UnregisteredObserver( + napi_env env, napi_value callback, RegisterMode mode, const std::vector &keys); + + class JSObservers { + public: + JSObservers(napi_env env, PreferencesProxy *proxy); + ~JSObservers(); + int Subscribe(napi_value callback, RegisterMode mode, const std::vector &keys); + int Unsubscribe(napi_value callback, RegisterMode mode, const std::vector &keys); + private: + static void CleanEnv(void *obj); + + std::shared_ptr uvQueue_; + std::list> observers_[Observer::CHANGE_BUTT]; + napi_env env_ = nullptr; + PreferencesProxy *proxy_ = nullptr; + }; + std::mutex mutex_{}; + std::map observers_; +}; +} // namespace OHOS::Sendable::Preferences +#endif // PREFERENCES_JSKIT_NAPI_PREFERENCE_H diff --git a/preferences/frameworks/js/napi/sendable_preferences/include/napi_preferences_helper.h b/preferences/frameworks/js/napi/sendable_preferences/include/napi_preferences_helper.h new file mode 100644 index 00000000..3de3b498 --- /dev/null +++ b/preferences/frameworks/js/napi/sendable_preferences/include/napi_preferences_helper.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef PREFERENCES_JSKIT_NAPI_PREFERENCE_HELPER_H +#define PREFERENCES_JSKIT_NAPI_PREFERENCE_HELPER_H + +#include "napi/native_api.h" +#include "napi/native_common.h" +#include "napi/native_node_api.h" + +namespace OHOS::Sendable::JSPreferences { +napi_value InitPreferencesHelper(napi_env env, napi_value exports); +} +#endif // PREFERENCES_JSKIT_NAPI_PREFERENCE_HELPER_H \ No newline at end of file diff --git a/preferences/frameworks/js/napi/sendable_preferences/src/entry_point.cpp b/preferences/frameworks/js/napi/sendable_preferences/src/entry_point.cpp new file mode 100644 index 00000000..d5b699de --- /dev/null +++ b/preferences/frameworks/js/napi/sendable_preferences/src/entry_point.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "log_print.h" +#include "napi/native_api.h" +#include "napi/native_node_api.h" +#include "napi_preferences.h" +#include "napi_preferences_helper.h" + +using namespace OHOS::Sendable::JSPreferences; + +EXTERN_C_START +/* + * function for module exports + */ +static napi_value Init(napi_env env, napi_value exports) +{ + PreferencesProxy::Init(env, exports); + InitPreferencesHelper(env, exports); + return exports; +} +EXTERN_C_END + +/* + * Module define + */ +static napi_module _module = { .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = Init, + .nm_modname = "data.sendablePreferences", + .nm_priv = ((void *)0), + .reserved = { 0 } }; +/* + * Module register function + */ +static __attribute__((constructor)) void RegisterModule(void) +{ + napi_module_register(&_module); +} diff --git a/preferences/frameworks/js/napi/sendable_preferences/src/napi_preferences.cpp b/preferences/frameworks/js/napi/sendable_preferences/src/napi_preferences.cpp new file mode 100644 index 00000000..23949fdb --- /dev/null +++ b/preferences/frameworks/js/napi/sendable_preferences/src/napi_preferences.cpp @@ -0,0 +1,607 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "napi_preferences.h" + +#include +#include +#include +#include +#include + +#include "js_sendable_utils.h" +#include "napi_async_call.h" +#include "napi_preferences_error.h" +#include "preferences.h" +#include "preferences_errno.h" +#include "preferences_value.h" +#include "securec.h" + +using namespace OHOS::NativePreferences; +using namespace OHOS::PreferencesJsKit; +namespace OHOS::Sendable::JSPreferences { +#define MAX_KEY_LENGTH Preferences::MAX_KEY_LENGTH +#define MAX_VALUE_LENGTH Preferences::MAX_VALUE_LENGTH + +struct PreferencesAysncContext : public BaseContext { + std::weak_ptr instance_; + std::string key; + PreferencesValue defValue = PreferencesValue(static_cast(0)); + napi_ref inputValueRef = nullptr; + std::map allElements; + bool hasKey = false; + std::vector> preferencesObservers; + + PreferencesAysncContext() + { + } + virtual ~PreferencesAysncContext(){}; +}; + +static thread_local napi_ref constructor_ = nullptr; + +PreferencesProxy::PreferencesProxy() +{ +} + +PreferencesProxy::~PreferencesProxy() +{ + std::lock_guard lockGuard(mutex_); + observers_.clear(); +} + +void PreferencesProxy::Destructor(napi_env env, void *nativeObject, void *finalize_hint) +{ + PreferencesProxy *obj = static_cast(nativeObject); + delete obj; +} + +void PreferencesProxy::Init(napi_env env, napi_value exports) +{ + napi_property_descriptor descriptors[] = { + DECLARE_NAPI_FUNCTION_WITH_DATA("put", SetValue, ASYNC), + DECLARE_NAPI_FUNCTION_WITH_DATA("putSync", SetValue, SYNC), + DECLARE_NAPI_FUNCTION_WITH_DATA("get", GetValue, ASYNC), + DECLARE_NAPI_FUNCTION_WITH_DATA("getSync", GetValue, SYNC), + DECLARE_NAPI_FUNCTION_WITH_DATA("getAll", GetAll, ASYNC), + DECLARE_NAPI_FUNCTION_WITH_DATA("getAllSync", GetAll, SYNC), + DECLARE_NAPI_FUNCTION_WITH_DATA("delete", Delete, ASYNC), + DECLARE_NAPI_FUNCTION_WITH_DATA("deleteSync", Delete, SYNC), + DECLARE_NAPI_FUNCTION_WITH_DATA("clear", Clear, ASYNC), + DECLARE_NAPI_FUNCTION_WITH_DATA("clearSync", Clear, SYNC), + DECLARE_NAPI_FUNCTION_WITH_DATA("has", HasKey, ASYNC), + DECLARE_NAPI_FUNCTION_WITH_DATA("hasSync", HasKey, SYNC), + DECLARE_NAPI_FUNCTION_WITH_DATA("flush", Flush, ASYNC), + DECLARE_NAPI_FUNCTION_WITH_DATA("flushSync", Flush, SYNC), + DECLARE_NAPI_FUNCTION("on", RegisterObserver), + DECLARE_NAPI_FUNCTION("off", UnregisterObserver), + }; + + napi_value cons = nullptr; + napi_define_sendable_class(env, "Preferences", NAPI_AUTO_LENGTH, New, nullptr, + sizeof(descriptors) / sizeof(napi_property_descriptor), descriptors, nullptr, &cons); + + napi_create_reference(env, cons, 1, &constructor_); +} + +napi_status PreferencesProxy::NewInstance( + napi_env env, std::shared_ptr value, napi_value *instance) +{ + if (value == nullptr) { + LOG_ERROR("PreferencesProxy::NewInstance get native preferences is null"); + return napi_invalid_arg; + } + napi_value cons; + napi_status status = napi_get_reference_value(env, constructor_, &cons); + if (status != napi_ok) { + return status; + } + + status = napi_new_instance(env, cons, 0, nullptr, instance); + if (status != napi_ok) { + return status; + } + + PreferencesProxy *obj = new (std::nothrow) PreferencesProxy(); + if (obj == nullptr) { + LOG_ERROR("PreferencesProxy::New new failed, obj is nullptr"); + return napi_invalid_arg; + } + obj->SetInstance(value); + status = napi_wrap_sendable(env, *instance, obj, PreferencesProxy::Destructor, nullptr); + if (status != napi_ok) { + delete obj; + return status; + } + + return napi_ok; +} + +napi_value PreferencesProxy::New(napi_env env, napi_callback_info info) +{ + napi_value thiz = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thiz, nullptr)); + if (thiz == nullptr) { + LOG_WARN("get this failed"); + return nullptr; + } + return thiz; +} + +int ParseKey(napi_env env, const napi_value arg, std::shared_ptr context) +{ + int32_t rc = Utils::ConvertFromSendable(env, arg, context->key); + PRE_CHECK_RETURN_ERR_SET(rc == napi_ok, std::make_shared("The key must be string.")); + PRE_CHECK_RETURN_ERR_SET(context->key.length() <= MAX_KEY_LENGTH, std::make_shared("The key must " + "be less than " + "80 bytes.")); + return OK; +} + +int ParseDefValue(const napi_env env, const napi_value jsVal, std::shared_ptr context) +{ + int32_t rc = Utils::ConvertFromSendable(env, jsVal, context->defValue.value_); + PRE_CHECK_RETURN_ERR_SET(rc == napi_ok, std::make_shared("The type of value mast be ValueType.")); + return OK; +} + +std::pair> PreferencesProxy::GetSelfInstance( + napi_env env, napi_value self) +{ + void *boundObj = nullptr; + napi_unwrap_sendable(env, self, &boundObj); + if (boundObj != nullptr) { + PreferencesProxy *obj = reinterpret_cast(boundObj); + return { obj, obj->GetInstance() }; + } + return { nullptr, std::weak_ptr() }; +} + +int GetAllExecute(napi_env env, std::shared_ptr context, napi_value &result) +{ + std::vector descriptors; + for (const auto &[key, value] : context->allElements) { + descriptors.push_back(napi_property_descriptor( + DECLARE_NAPI_DEFAULT_PROPERTY(key.c_str(), Utils::ConvertToSendable(env, value.value_)))); + } + napi_create_sendable_object_with_properties(env, descriptors.size(), descriptors.data(), &result); + return OK; +} + +napi_value PreferencesProxy::GetAll(napi_env env, napi_callback_info info) +{ + LOG_DEBUG("GetAll start"); + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { + PRE_CHECK_RETURN_VOID_SET(argc == 0, std::make_shared("0 or 1")); + std::tie(context->boundObj, context->instance_) = GetSelfInstance(env, self); + PRE_CHECK_RETURN_VOID_SET(context->boundObj != nullptr, std::make_shared("Failed to unwrap when " + "getting all.")); + }; + auto exec = [context]() -> int { + auto instance = context->instance_.lock(); + if (instance == nullptr) { + return E_INNER_ERROR; + } + context->allElements = instance->GetAll(); + return OK; + }; + auto output = [context](napi_env env, napi_value &result) { GetAllExecute(env, context, result); }; + context->SetAction(env, info, input, exec, output); + + PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); + return AsyncCall::Call(env, context, "GetAll"); +} + +napi_value PreferencesProxy::GetValue(napi_env env, napi_callback_info info) +{ + LOG_DEBUG("GetValue start"); + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { + PRE_CHECK_RETURN_VOID_SET(argc == 2, std::make_shared("2 or 3")); + PRE_CHECK_RETURN_VOID(ParseKey(env, argv[0], context) == OK); + napi_create_reference(env, argv[1], 1, &context->inputValueRef); + std::tie(context->boundObj, context->instance_) = GetSelfInstance(env, self); + PRE_CHECK_RETURN_VOID_SET(context->boundObj != nullptr, std::make_shared("Failed to unwrap when " + "getting value.")); + }; + auto exec = [context]() -> int { + auto instance = context->instance_.lock(); + if (instance == nullptr) { + return E_INNER_ERROR; + } + context->defValue = instance->Get(context->key, context->defValue); + return OK; + }; + auto output = [context](napi_env env, napi_value &result) { + if (context->defValue.IsLong()) { + LOG_DEBUG("GetValue get default value."); + napi_get_reference_value(env, context->inputValueRef, &result); + } else { + result = Utils::ConvertToSendable(env, context->defValue.value_); + } + napi_delete_reference(env, context->inputValueRef); + PRE_CHECK_RETURN_VOID_SET(result != nullptr, std::make_shared("Failed to delete reference when " + "getting value.")); + }; + context->SetAction(env, info, input, exec, output); + + PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); + return AsyncCall::Call(env, context, "GetValue"); +} + +napi_value PreferencesProxy::SetValue(napi_env env, napi_callback_info info) +{ + LOG_DEBUG("SetValue start"); + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { + PRE_CHECK_RETURN_VOID_SET(argc == 2, std::make_shared("2 or 3")); + PRE_CHECK_RETURN_VOID(ParseKey(env, argv[0], context) == OK); + PRE_CHECK_RETURN_VOID(ParseDefValue(env, argv[1], context) == OK); + std::tie(context->boundObj, context->instance_) = GetSelfInstance(env, self); + PRE_CHECK_RETURN_VOID_SET(context->boundObj != nullptr, std::make_shared("Failed to unwrap when " + "setting value.")); + }; + auto exec = [context]() -> int { + auto instance = context->instance_.lock(); + if (instance == nullptr) { + return E_INNER_ERROR; + } + return instance->Put(context->key, context->defValue); + }; + auto output = [context](napi_env env, napi_value &result) { + napi_status status = napi_get_undefined(env, &result); + PRE_CHECK_RETURN_VOID_SET(status == napi_ok, std::make_shared("Failed to get undefined when " + "setting value.")); + LOG_DEBUG("SetValue end."); + }; + context->SetAction(env, info, input, exec, output); + + PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); + return AsyncCall::Call(env, context, "SetValue"); +} + +napi_value PreferencesProxy::Delete(napi_env env, napi_callback_info info) +{ + LOG_DEBUG("Delete start"); + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { + PRE_CHECK_RETURN_VOID_SET(argc == 1, std::make_shared("1 or 2")); + PRE_CHECK_RETURN_VOID(ParseKey(env, argv[0], context) == OK); + std::tie(context->boundObj, context->instance_) = GetSelfInstance(env, self); + PRE_CHECK_RETURN_VOID_SET(context->boundObj != nullptr, std::make_shared("Failed to unwrap when " + "deleting value.")); + }; + auto exec = [context]() -> int { + auto instance = context->instance_.lock(); + if (instance == nullptr) { + return E_INNER_ERROR; + } + return instance->Delete(context->key); + }; + auto output = [context](napi_env env, napi_value &result) { + napi_status status = napi_get_undefined(env, &result); + PRE_CHECK_RETURN_VOID_SET(status == napi_ok, std::make_shared("Failed to get undefined when " + "deleting value.")); + LOG_DEBUG("Delete end."); + }; + context->SetAction(env, info, input, exec, output); + + PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); + return AsyncCall::Call(env, context, "Delete"); +} + +napi_value PreferencesProxy::HasKey(napi_env env, napi_callback_info info) +{ + LOG_DEBUG("HasKey start"); + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { + PRE_CHECK_RETURN_VOID_SET(argc == 1, std::make_shared("1 or 2")); + PRE_CHECK_RETURN_VOID(ParseKey(env, argv[0], context) == OK); + std::tie(context->boundObj, context->instance_) = GetSelfInstance(env, self); + PRE_CHECK_RETURN_VOID_SET(context->boundObj != nullptr, std::make_shared("Failed to unwrap when " + "having key.")); + }; + auto exec = [context]() -> int { + auto instance = context->instance_.lock(); + if (instance == nullptr) { + return E_INNER_ERROR; + } + context->hasKey = instance->HasKey(context->key); + return OK; + }; + auto output = [context](napi_env env, napi_value &result) { + napi_status status = napi_get_boolean(env, context->hasKey, &result); + PRE_CHECK_RETURN_VOID_SET(status == napi_ok, std::make_shared("Failed to get boolean when having " + "key.")); + LOG_DEBUG("HasKey end."); + }; + context->SetAction(env, info, input, exec, output); + + PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); + return AsyncCall::Call(env, context, "HasKey"); +} + +napi_value PreferencesProxy::Flush(napi_env env, napi_callback_info info) +{ + LOG_DEBUG("Flush start"); + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { + PRE_CHECK_RETURN_VOID_SET(argc == 0, std::make_shared("0 or 1")); + std::tie(context->boundObj, context->instance_) = GetSelfInstance(env, self); + PRE_CHECK_RETURN_VOID_SET(context->boundObj != nullptr, std::make_shared("Failed to unwrap when " + "flushing.")); + }; + auto exec = [context]() -> int { + auto instance = context->instance_.lock(); + if (instance == nullptr) { + return E_INNER_ERROR; + } + return instance->FlushSync(); + }; + auto output = [context](napi_env env, napi_value &result) { + napi_status status = napi_get_undefined(env, &result); + PRE_CHECK_RETURN_VOID_SET(status == napi_ok, std::make_shared("Failed to get undefined when " + "flushing.")); + LOG_DEBUG("Flush end."); + }; + context->SetAction(env, info, input, exec, output); + + PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); + return AsyncCall::Call(env, context, "Flush"); +} + +napi_value PreferencesProxy::Clear(napi_env env, napi_callback_info info) +{ + LOG_DEBUG("Clear start"); + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { + PRE_CHECK_RETURN_VOID_SET(argc == 0, std::make_shared("0 or 1")); + std::tie(context->boundObj, context->instance_) = GetSelfInstance(env, self); + PRE_CHECK_RETURN_VOID_SET(context->boundObj != nullptr, std::make_shared("Failed to unwrap unwrap " + "when clearing.")); + }; + auto exec = [context]() -> int { + auto instance = context->instance_.lock(); + if (instance == nullptr) { + return E_INNER_ERROR; + } + return instance->Clear(); + }; + auto output = [context](napi_env env, napi_value &result) { + napi_status status = napi_get_undefined(env, &result); + PRE_CHECK_RETURN_VOID_SET(status == napi_ok, std::make_shared("Failed to get undefined when " + "clearing.")); + LOG_DEBUG("Clear end."); + }; + context->SetAction(env, info, input, exec, output); + + PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); + return AsyncCall::Call(env, context, "Clear"); +} + +napi_value PreferencesProxy::RegisterObserver(napi_env env, napi_callback_info info) +{ + napi_value thiz = nullptr; + size_t argc = 3; // 3 is specifies the length of the provided argc array + napi_value args[3] = { 0 }; // 3 is the max args length + + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thiz, nullptr)); + // This interface must have 2 or 3 parameters. + PRE_NAPI_ASSERT(env, argc == 2 || argc == 3, std::make_shared("2 or 3")); + napi_valuetype type; + NAPI_CALL(env, napi_typeof(env, args[0], &type)); + PRE_NAPI_ASSERT(env, type == napi_string, std::make_shared("The registerMode must be string.")); + std::string registerMode; + Utils::ConvertFromSendable(env, args[0], registerMode); + PRE_NAPI_ASSERT(env, + registerMode == STR_CHANGE || registerMode == STR_MULTI_PRECESS_CHANGE || registerMode == STR_DATA_CHANGE, + std::make_shared("The registerMode must be 'change' or 'multiProcessChange' or " + "'dataChange'.")); + + size_t funIndex = 1; + std::vector keys; + auto mode = ConvertToRegisterMode(registerMode); + if (mode == Observer::DATA_CHANGE) { + int errCode = Utils::ConvertFromSendable(env, args[funIndex], keys); + PRE_NAPI_ASSERT(env, errCode == napi_ok && !keys.empty(), + std::make_shared("The keys must be Array.")); + funIndex++; + } + + PRE_NAPI_ASSERT(env, argc == funIndex + 1, std::make_shared("2 or 3")); + NAPI_CALL(env, napi_typeof(env, args[funIndex], &type)); + PRE_NAPI_ASSERT(env, type == napi_function, std::make_shared("The callback must be function.")); + + auto [obj, instance] = GetSelfInstance(env, thiz); + PRE_NAPI_ASSERT(env, obj != nullptr && obj->GetInstance() != nullptr, + std::make_shared("Failed to unwrap when register callback")); + int errCode = obj->RegisteredObserver(env, args[funIndex], mode, keys); + LOG_DEBUG("The observer subscribe %{public}d.", errCode); + PRE_NAPI_ASSERT(env, errCode == OK, std::make_shared(errCode)); + return nullptr; +} + +napi_value PreferencesProxy::UnregisterObserver(napi_env env, napi_callback_info info) +{ + napi_value thiz = nullptr; + size_t argc = 3; // 3 is specifies the length of the provided argc array + napi_value args[3] = { 0 }; // 3 is the max args length + + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thiz, nullptr)); + PRE_NAPI_ASSERT(env, argc > 0, std::make_shared("more than 1")); + + napi_valuetype type; + NAPI_CALL(env, napi_typeof(env, args[0], &type)); + PRE_NAPI_ASSERT(env, type == napi_string, std::make_shared("The registerMode must be string.")); + + std::string registerMode; + Utils::ConvertFromSendable(env, args[0], registerMode); + PRE_NAPI_ASSERT(env, + registerMode == STR_CHANGE || registerMode == STR_MULTI_PRECESS_CHANGE || registerMode == STR_DATA_CHANGE, + std::make_shared("The unRegisterMode must be 'change' or 'multiProcessChange' or " + "'dataChange'.")); + + size_t funIndex = 1; + napi_value callback = nullptr; + std::vector keys; + auto mode = ConvertToRegisterMode(registerMode); + if (mode == Observer::DATA_CHANGE) { + int errCode = Utils::ConvertFromSendable(env, args[funIndex], keys); + PRE_NAPI_ASSERT(env, errCode == napi_ok && !keys.empty(), + std::make_shared("The keys must be Array.")); + funIndex++; + } + + PRE_NAPI_ASSERT(env, argc <= funIndex + 1, std::make_shared("1 or 2 or 3")); + if (argc == funIndex + 1) { + NAPI_CALL(env, napi_typeof(env, args[funIndex], &type)); + PRE_NAPI_ASSERT(env, type == napi_function || type == napi_undefined || type == napi_null, + std::make_shared("The callback must be function.")); + callback = args[funIndex]; + } + + auto [obj, instance] = GetSelfInstance(env, thiz); + PRE_NAPI_ASSERT(env, obj != nullptr, std::make_shared("Failed to unwrap when unregister callback")); + + int errCode = obj->UnregisteredObserver(env, callback, mode, keys); + LOG_DEBUG("The observer unsubscribe 0x%{public}x.", errCode); + PRE_NAPI_ASSERT(env, errCode == OK, std::make_shared(errCode)); + return nullptr; +} + +RegisterMode PreferencesProxy::ConvertToRegisterMode(const std::string &mode) +{ + if (mode == STR_CHANGE) { + return RegisterMode::LOCAL_CHANGE; + } else if (mode == STR_MULTI_PRECESS_CHANGE) { + return RegisterMode::MULTI_PRECESS_CHANGE; + } else { + return RegisterMode::DATA_CHANGE; + } +} + +int PreferencesProxy::RegisteredObserver( + napi_env env, napi_value callback, RegisterMode mode, const std::vector &keys) +{ + std::lock_guard lockGuard(mutex_); + auto it = observers_.find(env); + if (it == observers_.end()) { + it = observers_.emplace( + std::piecewise_construct, std::forward_as_tuple(env), std::forward_as_tuple(env, this)).first; + } + if (it == observers_.end()) { + return E_INNER_ERROR; + } + return it->second.Subscribe(callback, mode, keys); +} + +int PreferencesProxy::UnregisteredObserver( + napi_env env, napi_value callback, RegisterMode mode, const std::vector &keys) +{ + std::lock_guard lockGuard(mutex_); + auto it = observers_.find(env); + if (it == observers_.end()) { + return E_OK; + } + return it->second.Unsubscribe(callback, mode, keys); +} + +PreferencesProxy::JSObservers::~JSObservers() +{ + for (int mode = 0; mode < RegisterMode::CHANGE_BUTT; ++mode) { + Unsubscribe(nullptr, RegisterMode(mode), {}); + } + napi_remove_env_cleanup_hook(env_, &CleanEnv, this); + uvQueue_ = nullptr; + env_ = nullptr; + proxy_ = nullptr; +} + +PreferencesProxy::JSObservers::JSObservers(napi_env env, PreferencesProxy *proxy) : env_(env), proxy_(proxy) +{ + uvQueue_ = std::make_shared(env); + napi_add_env_cleanup_hook(env_, &CleanEnv, this); +} + +void PreferencesProxy::JSObservers::CleanEnv(void *obj) +{ + auto *realObj = reinterpret_cast(obj); + if (realObj == nullptr) { + return; + } + auto proxy = realObj->proxy_; + auto env = realObj->env_; + if (proxy == nullptr || env == nullptr) { + return; + } + + std::lock_guardmutex_)> lockGuard(proxy->mutex_); + proxy->observers_.erase(env); +} + +int PreferencesProxy::JSObservers::Subscribe( + napi_value callback, RegisterMode mode, const std::vector &keys) +{ + auto &observers = observers_[mode]; + auto observerIt = std::find_if( + observers.begin(), observers.end(), [env = env_, callback](std::shared_ptr observer) { + if (observer == nullptr) { + return false; + } + return JSUtils::Equals(env, callback, observer->GetCallback()); + }); + if (observerIt != observers.end()) { + return E_OK; + } + + auto jsObserver = std::make_shared(uvQueue_, callback); + auto instance = proxy_->GetInstance(); + if (instance == nullptr) { + return E_INNER_ERROR; + } + auto errCode = instance->Subscribe(jsObserver, mode, keys); + if (errCode != E_OK) { + return errCode; + } + observers.push_back(jsObserver); + return errCode; +} + +int PreferencesProxy::JSObservers::Unsubscribe( + napi_value callback, RegisterMode mode, const std::vector &keys) +{ + auto instance = proxy_->GetInstance(); + if (instance == nullptr) { + return E_INNER_ERROR; + } + int errCode = E_OK; + auto &observers = observers_[mode]; + for (auto observer = observers.begin(); observer != observers.end();) { + if (callback == nullptr || JSUtils::Equals(env_, callback, (*observer)->GetCallback())) { + int status = instance->Unsubscribe(*observer, mode, keys); + if (status == E_OK) { + (*observer)->ClearCallback(); + observer = observers.erase(observer); + continue; + } + errCode = status; + } + ++observer; + } + + return errCode; +} +} // namespace OHOS::Sendable::JSPreferences diff --git a/preferences/frameworks/js/napi/sendable_preferences/src/napi_preferences_helper.cpp b/preferences/frameworks/js/napi/sendable_preferences/src/napi_preferences_helper.cpp new file mode 100644 index 00000000..eeecf01b --- /dev/null +++ b/preferences/frameworks/js/napi/sendable_preferences/src/napi_preferences_helper.cpp @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "napi_preferences_helper.h" + +#include + +#include "js_ability.h" +#include "js_sendable_utils.h" +#include "js_common_utils.h" +#include "napi_async_call.h" +#include "napi_preferences.h" +#include "preferences.h" +#include "preferences_errno.h" +#include "securec.h" + +using namespace OHOS::NativePreferences; +using namespace OHOS::PreferencesJsKit; + +namespace OHOS::Sendable::JSPreferences { +constexpr const char *DATA_GROUP_ID = "dataGroupId"; +constexpr const char *NAME = "name"; + +struct HelperAysncContext : public BaseContext { + std::string path; + std::string name; + std::string bundleName; + std::string dataGroupId; + std::shared_ptr proxy; + + HelperAysncContext() + { + } + virtual ~HelperAysncContext(){}; +}; + +int ParseParameters(const napi_env env, napi_value *argv, std::shared_ptr context) +{ + if (Utils::ConvertFromSendable(env, argv[1], context->name) != napi_ok) { + napi_value temp = nullptr; + napi_get_named_property(env, argv[1], NAME, &temp); + PRE_CHECK_RETURN_ERR_SET(temp && Utils::ConvertFromSendable(env, temp, context->name) == napi_ok, + std::make_shared("The name must be string.")); + + bool hasGroupId = false; + napi_has_named_property(env, argv[1], DATA_GROUP_ID, &hasGroupId); + if (hasGroupId) { + temp = nullptr; + napi_get_named_property(env, argv[1], DATA_GROUP_ID, &temp); + napi_valuetype type = napi_undefined; + napi_status status = napi_typeof(env, temp, &type); + if (status == napi_ok && (type != napi_null && type != napi_undefined)) { + PRE_CHECK_RETURN_ERR_SET(Utils::ConvertFromSendable(env, temp, context->dataGroupId) == napi_ok, + std::make_shared("The dataGroupId must be string.")); + } + } + } + JSAbility::ContextInfo contextInfo; + std::shared_ptr err = JSAbility::GetContextInfo(env, argv[0], context->dataGroupId, contextInfo); + PRE_CHECK_RETURN_ERR_SET(err == nullptr, err); + + context->bundleName = contextInfo.bundleName; + context->path = contextInfo.preferencesDir.append("/").append(context->name); + return OK; +} + +napi_value GetPreferences(napi_env env, napi_callback_info info) +{ + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { + PRE_CHECK_RETURN_VOID_SET(argc == 2, std::make_shared("2 or 3")); + PRE_CHECK_RETURN_VOID(ParseParameters(env, argv, context) == OK); + }; + auto exec = [context]() -> int { + int errCode = E_OK; + Options options(context->path, context->bundleName, context->dataGroupId); + context->proxy = PreferencesHelper::GetPreferences(options, errCode); + return errCode; + }; + auto output = [context](napi_env env, napi_value &result) { + auto status = PreferencesProxy::NewInstance(env, context->proxy, &result); + PRE_CHECK_RETURN_VOID_SET(status == napi_ok, std::make_shared("Failed to get instance when " + "getting preferences.")); + }; + context->SetAction(env, info, input, exec, output); + + PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); + return AsyncCall::Call(env, context, "GetPreferences"); +} + +napi_value DeletePreferences(napi_env env, napi_callback_info info) +{ + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { + PRE_CHECK_RETURN_VOID_SET(argc == 2, std::make_shared("2 or 3")); + PRE_CHECK_RETURN_VOID(ParseParameters(env, argv, context) == OK); + }; + auto exec = [context]() -> int { return PreferencesHelper::DeletePreferences(context->path); }; + auto output = [context](napi_env env, napi_value &result) { + napi_status status = napi_get_undefined(env, &result); + PRE_CHECK_RETURN_VOID_SET(status == napi_ok, std::make_shared("Failed to get undefined when " + "deleting preferences.")); + }; + context->SetAction(env, info, input, exec, output); + + PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); + return AsyncCall::Call(env, context, "DeletePreferences"); +} + +napi_value RemovePreferencesFromCache(napi_env env, napi_callback_info info) +{ + auto context = std::make_shared(); + auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { + PRE_CHECK_RETURN_VOID_SET(argc == 2, std::make_shared("2 or 3")); + PRE_CHECK_RETURN_VOID(ParseParameters(env, argv, context) == OK); + }; + auto exec = [context]() -> int { return PreferencesHelper::RemovePreferencesFromCache(context->path); }; + auto output = [context](napi_env env, napi_value &result) { + napi_status status = napi_get_undefined(env, &result); + PRE_CHECK_RETURN_VOID_SET(status == napi_ok, std::make_shared("Failed to get undefined when " + "removing preferences.")); + }; + context->SetAction(env, info, input, exec, output); + + PRE_CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); + return AsyncCall::Call(env, context, "RemovePreferencesFromCache"); +} + +napi_value InitPreferencesHelper(napi_env env, napi_value exports) +{ + napi_property_descriptor properties[] = { + DECLARE_NAPI_FUNCTION_WITH_DATA("getPreferences", GetPreferences, ASYNC), + DECLARE_NAPI_FUNCTION_WITH_DATA("getPreferencesSync", GetPreferences, SYNC), + DECLARE_NAPI_FUNCTION_WITH_DATA("deletePreferences", DeletePreferences, ASYNC), + DECLARE_NAPI_FUNCTION_WITH_DATA("deletePreferencesSync", DeletePreferences, SYNC), + DECLARE_NAPI_FUNCTION_WITH_DATA("removePreferencesFromCache", RemovePreferencesFromCache, ASYNC), + DECLARE_NAPI_FUNCTION_WITH_DATA("removePreferencesFromCacheSync", RemovePreferencesFromCache, SYNC), + DECLARE_NAPI_PROPERTY("MAX_KEY_LENGTH", JSUtils::Convert2JSValue(env, Preferences::MAX_KEY_LENGTH)), + DECLARE_NAPI_PROPERTY("MAX_VALUE_LENGTH", JSUtils::Convert2JSValue(env, Preferences::MAX_VALUE_LENGTH)), + }; + NAPI_CALL(env, napi_define_properties(env, exports, sizeof(properties) / sizeof(*properties), properties)); + return exports; +} +} // namespace OHOS::Sendable::JSPreferences diff --git a/preferences/frameworks/js/napi/storage/BUILD.gn b/preferences/frameworks/js/napi/storage/BUILD.gn index 503618f0..23f758df 100644 --- a/preferences/frameworks/js/napi/storage/BUILD.gn +++ b/preferences/frameworks/js/napi/storage/BUILD.gn @@ -13,7 +13,6 @@ import("//build/ohos.gni") import("//build/ohos/ace/ace.gni") import("//foundation/distributeddatamgr/preferences/preferences.gni") -import("//foundation/distributeddatamgr/relational_store/relational_store.gni") if (!is_mingw && !is_mac) { ohos_copy("preferences_declaration") { @@ -28,31 +27,35 @@ if (!is_mingw && !is_mac) { ohos_shared_library("storage") { branch_protector_ret = "pac_ret" sanitize = { + boundary_sanitize = true + ubsan = true cfi = true cfi_cross_dso = true debug = false } + cflags_cc = [ + "-std=c++17", + "-stdlib=libc++", + ] include_dirs = [ "include", - "../common/include", "${preferences_base_path}/frameworks/common/include", ] sources = [ - "../common/src/js_observer.cpp", - "../common/src/js_utils.cpp", - "../common/src/napi_async_call.cpp", - "../common/src/napi_preferences_observer.cpp", - "../common/src/uv_queue.cpp", "src/entry_point_storage.cpp", "src/napi_storage.cpp", "src/napi_storage_helper.cpp", ] - deps = - [ "${preferences_base_path}/interfaces/inner_api:native_preferences" ] + deps = [ + "${preferences_base_path}/interfaces/inner_api:native_preferences", + "${preferences_napi_path}/common:preferences_jscommon", + ] external_deps = [ + "ability_runtime:abilitykit_native", + "ability_runtime:napi_base_context", "hilog:libhilog", "napi:ace_napi", ] diff --git a/preferences/frameworks/js/napi/storage/src/napi_storage.cpp b/preferences/frameworks/js/napi/storage/src/napi_storage.cpp index 8b6c3da1..35f475ec 100644 --- a/preferences/frameworks/js/napi/storage/src/napi_storage.cpp +++ b/preferences/frameworks/js/napi/storage/src/napi_storage.cpp @@ -19,7 +19,7 @@ #include #include -#include "js_utils.h" +#include "js_common_utils.h" #include "napi_async_call.h" #include "preferences.h" #include "preferences_errno.h" @@ -269,7 +269,7 @@ int ParseKey(const napi_env env, const napi_value arg, std::shared_ptr MAX_KEY_LENGTH) { LOG_ERROR("the length of the key is over maximum length."); - std::shared_ptr paramError = std::make_shared("The key must be less than 80 bytes."); + std::shared_ptr paramError = std::make_shared("The key must be less than 1024 bytes."); asyncContext->SetError(paramError); return ERR; } @@ -314,7 +314,7 @@ int ParseDefValue(const napi_env env, const napi_value jsVal, std::shared_ptr paramError = - std::make_shared("The value must be less than 8192 bytes."); + std::make_shared("The value must be less than 16 * 1024 * 1024 bytes."); asyncContext->SetError(paramError); return ERR; } @@ -487,7 +487,7 @@ napi_value StorageProxy::DeleteSync(napi_env env, napi_callback_info info) NAPI_CALL(env, napi_unwrap(env, thiz, reinterpret_cast(&obj))); int result = obj->value_->Delete(key); NAPI_ASSERT(env, result == E_OK, "call Delete failed"); - LOG_INFO("Delete"); + LOG_DEBUG("Delete"); return nullptr; } @@ -704,7 +704,7 @@ void StorageProxy::RegisterObserver(napi_value callback) auto observer = std::make_shared(uvQueue_, callback); value_->RegisterObserver(observer); dataObserver_.push_back(observer); - LOG_INFO("The observer subscribed success."); + LOG_DEBUG("The observer subscribed success."); } } @@ -719,7 +719,7 @@ void StorageProxy::UnRegisterObserver(napi_value callback) } value_->UnRegisterObserver(*it); it = dataObserver_.erase(it); - LOG_INFO("The observer unsubscribed success."); + LOG_DEBUG("The observer unsubscribed success."); } } } // namespace StorageJsKit diff --git a/preferences/frameworks/js/napi/storage/src/napi_storage_helper.cpp b/preferences/frameworks/js/napi/storage/src/napi_storage_helper.cpp index 714543c0..69a659fa 100644 --- a/preferences/frameworks/js/napi/storage/src/napi_storage_helper.cpp +++ b/preferences/frameworks/js/napi/storage/src/napi_storage_helper.cpp @@ -18,7 +18,7 @@ #include -#include "js_utils.h" +#include "js_common_utils.h" #include "napi_async_call.h" #include "napi_storage.h" #include "preferences.h" diff --git a/preferences/frameworks/js/napi/system_storage/BUILD.gn b/preferences/frameworks/js/napi/system_storage/BUILD.gn index 2f386e6f..ef68f0dd 100644 --- a/preferences/frameworks/js/napi/system_storage/BUILD.gn +++ b/preferences/frameworks/js/napi/system_storage/BUILD.gn @@ -13,7 +13,6 @@ import("//build/ohos.gni") import("//build/ohos/ace/ace.gni") import("//foundation/distributeddatamgr/preferences/preferences.gni") -import("//foundation/distributeddatamgr/relational_store/relational_store.gni") if (!is_mingw && !is_mac) { ohos_copy("preferences_declaration") { @@ -28,28 +27,34 @@ if (!is_mingw && !is_mac) { ohos_shared_library("storage_napi") { branch_protector_ret = "pac_ret" sanitize = { + boundary_sanitize = true + ubsan = true cfi = true cfi_cross_dso = true debug = false } + cflags_cc = [ + "-std=c++17", + "-stdlib=libc++", + ] include_dirs = [ "include", - "../common/include", "${preferences_base_path}/frameworks/common/include", ] sources = [ - "../common/src/js_ability.cpp", - "../common/src/js_utils.cpp", "src/entry_point_system_storage.cpp", "src/napi_system_storage.cpp", ] - deps = - [ "${preferences_base_path}/interfaces/inner_api:native_preferences" ] + deps = [ + "${preferences_base_path}/interfaces/inner_api:native_preferences", + "${preferences_napi_path}/common:preferences_jscommon", + ] external_deps = [ "ability_runtime:abilitykit_native", + "ability_runtime:extensionkit_native", "ability_runtime:napi_base_context", "common_event_service:cesfwk_innerkits", "hilog:libhilog", diff --git a/preferences/frameworks/js/napi/system_storage/src/napi_system_storage.cpp b/preferences/frameworks/js/napi/system_storage/src/napi_system_storage.cpp index a7794550..e627691a 100644 --- a/preferences/frameworks/js/napi/system_storage/src/napi_system_storage.cpp +++ b/preferences/frameworks/js/napi/system_storage/src/napi_system_storage.cpp @@ -18,7 +18,7 @@ #include #include "js_ability.h" -#include "js_utils.h" +#include "js_common_utils.h" #include "preferences_errno.h" #include "preferences_helper.h" diff --git a/preferences/frameworks/native/include/preferences_base.h b/preferences/frameworks/native/include/preferences_base.h index 6884b31c..3e2d7d7b 100644 --- a/preferences/frameworks/native/include/preferences_base.h +++ b/preferences/frameworks/native/include/preferences_base.h @@ -34,6 +34,7 @@ namespace OHOS { template class sptr; class Uri; namespace NativePreferences { +class ExecutorPool; class DataPreferencesObserverStub; /** * The function class of the preference. Various operations on preferences instances are provided in this class. @@ -96,6 +97,8 @@ public: const std::vector &keys = {}) override; std::string GetGroupId() const override; + + int CloseDb() override; protected: Uri MakeUri(const std::string &key = ""); struct WeakPtrCompare { @@ -113,6 +116,8 @@ protected: DataObserverMap dataObserversMap_; const Options options_; + + static ExecutorPool executorPool_; }; } // End of namespace NativePreferences } // End of namespace OHOS diff --git a/preferences/frameworks/native/include/preferences_enhance_impl.h b/preferences/frameworks/native/include/preferences_enhance_impl.h index 32661470..62905c12 100644 --- a/preferences/frameworks/native/include/preferences_enhance_impl.h +++ b/preferences/frameworks/native/include/preferences_enhance_impl.h @@ -49,11 +49,17 @@ public: std::map GetAll() override; int Delete(const std::string &key) override; + + int Clear() override; + + int CloseDb() override; private: explicit PreferencesEnhanceImpl(const Options &options); - void NotifyPreferencesObserver(const std::string &key, const PreferencesValue &value); + static void NotifyPreferencesObserver(std::shared_ptr pref, const std::string &key, + const PreferencesValue &value); std::shared_mutex dbMutex_; std::shared_ptr db_; + std::shared_mutex mapSharedMutex_; }; } // End of namespace NativePreferences } // End of namespace OHOS diff --git a/preferences/frameworks/native/include/preferences_impl.h b/preferences/frameworks/native/include/preferences_impl.h index 63266798..4f6dcbbf 100644 --- a/preferences/frameworks/native/include/preferences_impl.h +++ b/preferences/frameworks/native/include/preferences_impl.h @@ -28,7 +28,6 @@ namespace OHOS { namespace NativePreferences { -class ExecutorPool; class PreferencesImpl : public PreferencesBase, public std::enable_shared_from_this { public: static std::shared_ptr GetPreferences(const Options &options) @@ -98,8 +97,6 @@ private: std::list modifiedKeys_; - static ExecutorPool executorPool_; - std::map map_; }; } // End of namespace NativePreferences diff --git a/preferences/frameworks/native/include/preferences_utils.h b/preferences/frameworks/native/include/preferences_utils.h index 21bc05e1..47792b16 100644 --- a/preferences/frameworks/native/include/preferences_utils.h +++ b/preferences/frameworks/native/include/preferences_utils.h @@ -25,11 +25,11 @@ namespace NativePreferences { /** * @brief The constant Indicates the maximum length of the key in the preferences. */ -static constexpr uint32_t MAX_KEY_LENGTH = 80; +static constexpr uint32_t MAX_KEY_LENGTH = 1024; /** * @brief The constant Indicates the maximum length of the value in the preferences. */ -static constexpr uint32_t MAX_VALUE_LENGTH = 8 * 1024; +static constexpr uint32_t MAX_VALUE_LENGTH = 16 * 1024 * 1024; static const char *STR_BROKEN = ".broken"; static const char *STR_BACKUP = ".bak"; diff --git a/preferences/frameworks/native/include/preferences_value_parcel.h b/preferences/frameworks/native/include/preferences_value_parcel.h index 78576bf9..ff182bb9 100644 --- a/preferences/frameworks/native/include/preferences_value_parcel.h +++ b/preferences/frameworks/native/include/preferences_value_parcel.h @@ -34,18 +34,19 @@ public: private: enum ParcelTypeIndex { - INT_TYPE = 0, - LONG_TYPE = 1, - FLOAT_TYPE = 2, - DOUBLE_TYPE = 3, - BOOL_TYPE = 4, - STRING_TYPE = 5, - STRING_ARRAY_TYPE = 6, - BOOL_ARRAY_TYPE = 7, - DOUBLE_ARRAY_TYPE = 8, - UINT8_ARRAY_TYPE = 9, - OBJECT_TYPE = 10, - BIG_INT_TYPE = 11 + MONO_TYPE = 0, + INT_TYPE = 1, + LONG_TYPE = 2, + FLOAT_TYPE = 3, + DOUBLE_TYPE = 4, + BOOL_TYPE = 5, + STRING_TYPE = 6, + STRING_ARRAY_TYPE = 7, + BOOL_ARRAY_TYPE = 8, + DOUBLE_ARRAY_TYPE = 9, + UINT8_ARRAY_TYPE = 10, + OBJECT_TYPE = 11, + BIG_INT_TYPE = 12 }; static int MarshallingBasicValue(const PreferencesValue &value, const uint8_t type, std::vector &data); static int MarshallingStringValue(const PreferencesValue &value, const uint8_t type, std::vector &data); diff --git a/preferences/frameworks/native/mock/c_utils/utils/base/src/refbase.cpp b/preferences/frameworks/native/mock/c_utils/utils/base/src/refbase.cpp index 7c8b879d..95774e18 100644 --- a/preferences/frameworks/native/mock/c_utils/utils/base/src/refbase.cpp +++ b/preferences/frameworks/native/mock/c_utils/utils/base/src/refbase.cpp @@ -229,7 +229,9 @@ ATTEMPT_SUCCESS: RefBase::RefBase() : refs_(new RefCounter()) { refs_->IncRefCount(); - refs_->SetCallback(std::bind(&RefBase::RefPtrCallback, this)); + refs_->SetCallback([this] { + this->RefPtrCallback(); + }); } RefBase::RefBase(const RefBase &other) @@ -237,7 +239,9 @@ RefBase::RefBase(const RefBase &other) refs_ = new RefCounter(); if (refs_ != nullptr) { refs_->IncRefCount(); - refs_->SetCallback(std::bind(&RefBase::RefPtrCallback, this)); + refs_->SetCallback([this] { + this->RefPtrCallback(); + }); } } @@ -256,7 +260,9 @@ RefBase &RefBase::operator=(const RefBase &other) refs_ = new RefCounter(); if (refs_ != nullptr) { refs_->IncRefCount(); - refs_->SetCallback(std::bind(&RefBase::RefPtrCallback, this)); + refs_->SetCallback([this] { + this->RefPtrCallback(); + }); } return *this; diff --git a/preferences/frameworks/native/platform/include/preferences_db_adapter.h b/preferences/frameworks/native/platform/include/preferences_db_adapter.h index da1f9347..473fd924 100644 --- a/preferences/frameworks/native/platform/include/preferences_db_adapter.h +++ b/preferences/frameworks/native/platform/include/preferences_db_adapter.h @@ -27,9 +27,6 @@ namespace NativePreferences { typedef struct GRD_DB GRD_DB; -const char * const TABLENAME = "preferences_data"; -const char * const TABLE_MODE = "{\"mode\" : \"kv\", \"indextype\" : \"hash\"}"; - #define GRD_DB_OPEN_CREATE 0x01 #define GRD_DB_CLOSE_IGNORE_ERROR 0x01 @@ -115,10 +112,16 @@ public: int Delete(const std::vector &key); int Get(const std::vector &key, std::vector &value); int GetAll(std::list, std::vector>> &data); + int DropCollection(); + int CreateCollection(); + int GetAllInner(std::list, std::vector>> &data, GRD_ResultSet *resultSet); + int OpenDb(); + int CloseDb(); private: GRD_KVItemT BlobToKvItem(const std::vector &blob); std::vector KvItemToBlob(GRD_KVItemT &item); GRD_DB *db_ = nullptr; + std::string dbPath_ = ""; }; // grd errcode @@ -129,6 +132,7 @@ private: #define GRD_FAILED_MEMORY_ALLOCATE (-13000) #define GRD_FAILED_MEMORY_RELEASE (-14000) #define GRD_PERMISSION_DENIED (-43000) +#define GRD_UNDEFINED_TABLE (-23000) } // End of namespace NativePreferences } // End of namespace OHOS diff --git a/preferences/frameworks/native/platform/src/preferences_db_adapter.cpp b/preferences/frameworks/native/platform/src/preferences_db_adapter.cpp index 9880d12f..93d943c1 100644 --- a/preferences/frameworks/native/platform/src/preferences_db_adapter.cpp +++ b/preferences/frameworks/native/platform/src/preferences_db_adapter.cpp @@ -30,6 +30,14 @@ GRD_APIInfo PreferenceDbAdapter::api_; std::atomic PreferenceDbAdapter::isInit_ = false; +const char * const TABLENAME = "preferences_data"; +const char * const TABLE_MODE = "{\"mode\" : \"kv\", \"indextype\" : \"hash\"}"; +const char * const CONFIG_STR = + "{\"pageSize\": 4, \"redoFlushByTrx\": 1, \"redoPubBufSize\": 256, \"maxConnNum\": 100, " + "\"bufferPoolSize\": 1024, \"crcCheckEnable\": 0, \"bufferPoolPolicy\" : \"BUF_PRIORITY_INDEX\", " + "\"sharedModeEnable\" : 1, \"MetaInfoBak\": 1}"; +const int CREATE_COLLECTION_RETRY_TIMES = 2; + void GRDDBApiInitEnhance(GRD_APIInfo &GRD_DBApiInfo) { #ifndef _WIN32 @@ -113,38 +121,73 @@ void PreferenceDbAdapter::ApiInit() PreferencesDb::PreferencesDb() { } + PreferencesDb::~PreferencesDb() { if (db_ != nullptr) { PreferenceDbAdapter::GetApiInstance().DbCloseApi(db_, GRD_DB_CLOSE_IGNORE_ERROR); + db_ = nullptr; + LOG_DEBUG("destructor: calling close db."); + } else { + LOG_DEBUG("destructor: db closed before."); + } +} + +int PreferencesDb::CloseDb() +{ + if (db_ != nullptr) { + int errCode = TransferGrdErrno(PreferenceDbAdapter::GetApiInstance().DbCloseApi(db_, + GRD_DB_CLOSE_IGNORE_ERROR)); + if (errCode != E_OK) { + LOG_ERROR("close db failed, errcode=%{public}d", errCode); + return errCode; + } + LOG_INFO("db has been closed."); + db_ = nullptr; + return E_OK; } + LOG_INFO("CloseDb: DB closed before."); + return E_OK; +} + +int PreferencesDb::CreateCollection() +{ + int errCode = TransferGrdErrno(PreferenceDbAdapter::GetApiInstance().DbCreateCollectionApi(db_, TABLENAME, + TABLE_MODE, 0)); + if (errCode != E_OK) { + LOG_ERROR("rd create table failed:%{public}d", errCode); + } + return errCode; +} + +int PreferencesDb::OpenDb() +{ + return TransferGrdErrno(PreferenceDbAdapter::GetApiInstance().DbOpenApi(dbPath_.c_str(), + CONFIG_STR, GRD_DB_OPEN_CREATE, &db_)); } int PreferencesDb::Init(const std::string &dbPath) { if (db_ != nullptr) { - LOG_DEBUG("db handle is already inited"); + LOG_DEBUG("Init: already init."); return E_OK; } - std::string configStr = R"({"pageSize": 4, "redoFlushByTrx": 1, "redoPubBufSize": 256, "maxConnNum": 100, - "bufferPoolSize": 2048, "crcCheckEnable": 0, "bufferPoolPolicy" : "BUF_PRIORITY_INDEX", - "sharedModeEnable" : 1})"; - int errCode = TransferGrdErrno(PreferenceDbAdapter::GetApiInstance().DbOpenApi(dbPath.c_str(), configStr.c_str(), - GRD_DB_OPEN_CREATE, &db_)); + dbPath_ = dbPath + ".db"; + int errCode = OpenDb(); if (errCode != E_OK) { - LOG_ERROR("rd open failed:%d", errCode); + LOG_ERROR("rd open failed:%{public}d", errCode); return errCode; } - errCode = TransferGrdErrno(PreferenceDbAdapter::GetApiInstance().DbCreateCollectionApi(db_, TABLENAME, TABLE_MODE, - 0)); + + errCode = CreateCollection(); if (errCode != E_OK) { - LOG_ERROR("rd create table failed:%d", errCode); - return errCode; + LOG_ERROR("create collection failed when init, but ignored."); + // ignore create collection error } errCode = TransferGrdErrno(PreferenceDbAdapter::GetApiInstance().DbIndexPreloadApi(db_, TABLENAME)); if (errCode != E_OK) { - LOG_ERROR("[RdSingleVerStorageEngine] GRD_IndexPreload FAILED %d", errCode); + LOG_ERROR("Init: Index preload FAILED %{public}d", errCode); return errCode; } return errCode; @@ -153,42 +196,96 @@ int PreferencesDb::Init(const std::string &dbPath) int PreferencesDb::Put(const std::vector &key, const std::vector &value) { if (db_ == nullptr) { - LOG_DEBUG("db handle is nullptr"); + LOG_ERROR("Put failed, db has been closed."); return E_ERROR; } + GRD_KVItemT innerKey = BlobToKvItem(key); GRD_KVItemT innerVal = BlobToKvItem(value); - int ret = TransferGrdErrno(PreferenceDbAdapter::GetApiInstance().DbKvPutApi(db_, TABLENAME, &innerKey, &innerVal)); - if (ret != E_OK) { - LOG_ERROR("rd put failed:%d", ret); - } + + int retryTimes = CREATE_COLLECTION_RETRY_TIMES; + int ret = E_OK; + do { + ret = PreferenceDbAdapter::GetApiInstance().DbKvPutApi(db_, TABLENAME, &innerKey, &innerVal); + if (ret == GRD_UNDEFINED_TABLE) { + (void)CreateCollection(); + } else { + ret = TransferGrdErrno(ret); + if (ret == E_OK) { + return ret; + } else { + LOG_ERROR("rd put failed:%{public}d", ret); + return ret; + } + } + retryTimes--; + } while (retryTimes > 0); + + LOG_ERROR("rd put over retry times, errcode: :%{public}d", ret); return ret; } int PreferencesDb::Delete(const std::vector &key) { if (db_ == nullptr) { - LOG_DEBUG("db handle is nullptr"); + LOG_ERROR("Delete failed, db has been closed."); return E_ERROR; } + GRD_KVItemT innerKey = BlobToKvItem(key); - int ret = TransferGrdErrno(PreferenceDbAdapter::GetApiInstance().DbKvDelApi(db_, TABLENAME, &innerKey)); - if (ret != E_OK) { - LOG_ERROR("rd put failed:%d", ret); - } + + int retryTimes = CREATE_COLLECTION_RETRY_TIMES; + int ret = E_OK; + do { + ret = PreferenceDbAdapter::GetApiInstance().DbKvDelApi(db_, TABLENAME, &innerKey); + if (ret == GRD_UNDEFINED_TABLE) { + (void)CreateCollection(); + } else { + ret = TransferGrdErrno(ret); + if (ret == E_OK) { + return ret; + } else { + LOG_ERROR("rd delete failed:%{public}d", ret); + return ret; + } + } + retryTimes--; + } while (retryTimes > 0); + + LOG_ERROR("rd delete over retry times, errcode: :%{public}d", ret); return ret; } + int PreferencesDb::Get(const std::vector &key, std::vector &value) { if (db_ == nullptr) { - LOG_DEBUG("db handle is nullptr"); + LOG_ERROR("Get failed, db has been closed."); return E_ERROR; } + GRD_KVItemT innerKey = BlobToKvItem(key); GRD_KVItemT innerVal = { NULL, 0 }; - int ret = TransferGrdErrno(PreferenceDbAdapter::GetApiInstance().DbKvGetApi(db_, TABLENAME, &innerKey, &innerVal)); - if (ret != E_OK) { - LOG_ERROR("[rdUtils][GetKvData] Cannot get the data %d", ret); + + int retryTimes = CREATE_COLLECTION_RETRY_TIMES; + int ret = E_OK; + do { + ret = PreferenceDbAdapter::GetApiInstance().DbKvGetApi(db_, TABLENAME, &innerKey, &innerVal); + if (ret == GRD_UNDEFINED_TABLE) { + (void)CreateCollection(); + } else { + ret = TransferGrdErrno(ret); + if (ret == E_OK) { + break; + } else { + LOG_ERROR("rd get failed:%{public}d", ret); + return ret; + } + } + retryTimes--; + } while (retryTimes > 0); + + if (retryTimes == 0) { + LOG_ERROR("rd get over retry times, errcode: :%{public}d", ret); return ret; } value.resize(innerVal.dataLen); @@ -197,27 +294,17 @@ int PreferencesDb::Get(const std::vector &key, std::vector &va return E_OK; } -int PreferencesDb::GetAll(std::list, std::vector>> &data) +int PreferencesDb::GetAllInner(std::list, std::vector>> &data, + GRD_ResultSet *resultSet) { - if (db_ == nullptr) { - LOG_DEBUG("db handle is nullptr"); - return E_ERROR; - } - GRD_FilterOptionT param; - param.mode = KV_SCAN_ALL; - GRD_ResultSet *resultSet = nullptr; - int ret = TransferGrdErrno(PreferenceDbAdapter::GetApiInstance().DbKvFilterApi(db_, TABLENAME, ¶m, &resultSet)); - if (ret != E_OK) { - LOG_ERROR("ger reulstSet failed %d", ret); - return ret; - } + int ret = E_OK; while (TransferGrdErrno(PreferenceDbAdapter::GetApiInstance().NextApi(resultSet)) == E_OK) { std::pair, std::vector> dataItem; uint32_t keySize = 0; uint32_t valueSize = 0; ret = TransferGrdErrno(PreferenceDbAdapter::GetApiInstance().GetItemSizeApi(resultSet, &keySize, &valueSize)); if (ret != E_OK) { - LOG_ERROR("ger reulstSet kv size failed %d", ret); + LOG_ERROR("ger reulstSet kv size failed %{public}d", ret); PreferenceDbAdapter::GetApiInstance().FreeResultSetApi(resultSet); return ret; } @@ -226,13 +313,64 @@ int PreferencesDb::GetAll(std::list, std::vector< ret = TransferGrdErrno(PreferenceDbAdapter::GetApiInstance().GetItemApi(resultSet, dataItem.first.data(), dataItem.second.data())); if (ret != E_OK) { - LOG_ERROR("ger reulstSet failed %d", ret); + LOG_ERROR("ger reulstSet failed %{public}d", ret); PreferenceDbAdapter::GetApiInstance().FreeResultSetApi(resultSet); return ret; } data.emplace_back(std::move(dataItem)); } - return E_OK; + return ret; +} + +int PreferencesDb::GetAll(std::list, std::vector>> &data) +{ + if (db_ == nullptr) { + LOG_ERROR("GetAll failed, db has been closed."); + return E_ERROR; + } + + GRD_FilterOptionT param; + param.mode = KV_SCAN_ALL; + GRD_ResultSet *resultSet = nullptr; + + int retryTimes = CREATE_COLLECTION_RETRY_TIMES; + int ret = E_OK; + do { + ret = PreferenceDbAdapter::GetApiInstance().DbKvFilterApi(db_, TABLENAME, ¶m, &resultSet); + if (ret == GRD_UNDEFINED_TABLE) { + (void)CreateCollection(); + } else { + ret = TransferGrdErrno(ret); + if (ret == E_OK) { + break; + } else { + LOG_ERROR("rd kv filter failed:%{public}d", ret); + return ret; + } + } + retryTimes--; + } while (retryTimes > 0); + + if (retryTimes == 0) { + LOG_ERROR("rd get over retry times, errcode: :%{public}d", ret); + return ret; + } + + return GetAllInner(data, resultSet); +} + +int PreferencesDb::DropCollection() +{ + if (db_ == nullptr) { + LOG_ERROR("DropCollection failed, db has been closed."); + return E_ERROR; + } + + int errCode = TransferGrdErrno(PreferenceDbAdapter::GetApiInstance().DbDropCollectionApi(db_, TABLENAME, 0)); + if (errCode != E_OK) { + LOG_ERROR("rd drop collection failed:%{public}d", errCode); + } + return errCode; } GRD_KVItemT PreferencesDb::BlobToKvItem(const std::vector &blob) @@ -245,7 +383,8 @@ GRD_KVItemT PreferencesDb::BlobToKvItem(const std::vector &blob) std::vector PreferencesDb::KvItemToBlob(GRD_KVItemT &item) { - return std::vector((uint8_t *)item.data, (uint8_t *)item.data + item.dataLen); + return std::vector(static_cast(item.data), + static_cast(item.data) + item.dataLen); } } // End of namespace NativePreferences } // End of namespace OHOS \ No newline at end of file diff --git a/preferences/frameworks/native/src/preferences_base.cpp b/preferences/frameworks/native/src/preferences_base.cpp index f33f86d6..e1ab75ae 100644 --- a/preferences/frameworks/native/src/preferences_base.cpp +++ b/preferences/frameworks/native/src/preferences_base.cpp @@ -23,12 +23,15 @@ #include #include "base64_helper.h" +#include "executor_pool.h" #include "log_print.h" #include "preferences_observer_stub.h" -#include "securec.h" namespace OHOS { namespace NativePreferences { + +ExecutorPool PreferencesBase::executorPool_ = ExecutorPool(1, 0); + PreferencesBase::PreferencesBase(const Options &options) : options_(options) { } @@ -210,6 +213,11 @@ std::string PreferencesBase::GetGroupId() const return options_.dataGroupId; } +int PreferencesBase::CloseDb() +{ + return E_OK; +} + int PreferencesBase::RegisterDataObserver(std::shared_ptr preferencesObserver, const std::vector &keys) { diff --git a/preferences/frameworks/native/src/preferences_enhance_impl.cpp b/preferences/frameworks/native/src/preferences_enhance_impl.cpp index fd0dba37..1fb05713 100644 --- a/preferences/frameworks/native/src/preferences_enhance_impl.cpp +++ b/preferences/frameworks/native/src/preferences_enhance_impl.cpp @@ -23,6 +23,7 @@ #include #include +#include "executor_pool.h" #include "log_print.h" #include "preferences_observer_stub.h" #include "preferences_value.h" @@ -54,16 +55,21 @@ PreferencesValue PreferencesEnhanceImpl::Get(const std::string &key, const Prefe return defValue; } std::shared_lock autoLock(dbMutex_); + if (db_ == nullptr) { + LOG_ERROR("PreferencesEnhanceImpl:Get failed, db has been closed."); + return defValue; + } + std::vector oriKey(key.begin(), key.end()); std::vector oriValue; int errCode = db_->Get(oriKey, oriValue); if (errCode != E_OK) { - LOG_ERROR("get key failed, errCode=%d", errCode); + LOG_ERROR("get key failed, errCode=%{public}d", errCode); return defValue; } auto item = PreferencesValueParcel::UnmarshallingPreferenceValue(oriValue); if (item.first != E_OK) { - LOG_ERROR("get key failed, errCode=%d", errCode); + LOG_ERROR("get key failed, errCode=%{public}d", errCode); return defValue; } return item.second; @@ -75,11 +81,16 @@ bool PreferencesEnhanceImpl::HasKey(const std::string &key) return false; } std::shared_lock autoLock(dbMutex_); + if (db_ == nullptr) { + LOG_ERROR("PreferencesEnhanceImpl:HasKey failed, db has been closed."); + return E_ERROR; + } + std::vector oriKey(key.begin(), key.end()); std::vector oriValue; int errCode = db_->Get(oriKey, oriValue); if (errCode != E_OK) { - LOG_ERROR("get key failed, errCode=%d", errCode); + LOG_ERROR("get key failed, errCode=%{public}d", errCode); return false; } return true; @@ -96,21 +107,30 @@ int PreferencesEnhanceImpl::Put(const std::string &key, const PreferencesValue & return errCode; } std::unique_lock writeLock(dbMutex_); + if (db_ == nullptr) { + LOG_ERROR("PreferencesEnhanceImpl:Put failed, db has been closed."); + return E_ERROR; + } + std::vector oriValue; uint32_t oriValueLen = PreferencesValueParcel::CalSize(value); oriValue.resize(oriValueLen); errCode = PreferencesValueParcel::MarshallingPreferenceValue(value, oriValue); if (errCode != E_OK) { - LOG_ERROR("marshalling value failed, errCode=%d", errCode); + LOG_ERROR("marshalling value failed, errCode=%{public}d", errCode); return errCode; } std::vector oriKey(key.begin(), key.end()); errCode = db_->Put(oriKey, oriValue); if (errCode != E_OK) { - LOG_ERROR("put data failed, errCode=%d", errCode); + LOG_ERROR("put data failed, errCode=%{public}d", errCode); return errCode; } - NotifyPreferencesObserver(key, value); + + ExecutorPool::Task task = [pref = shared_from_this(), key, value] { + PreferencesEnhanceImpl::NotifyPreferencesObserver(pref, key, value); + }; + executorPool_.Execute(std::move(task)); return E_OK; } @@ -121,25 +141,39 @@ int PreferencesEnhanceImpl::Delete(const std::string &key) return errCode; } std::unique_lock writeLock(dbMutex_); + if (db_ == nullptr) { + LOG_ERROR("PreferencesEnhanceImpl:Delete failed, db has been closed."); + return E_ERROR; + } + std::vector oriKey(key.begin(), key.end()); errCode = db_->Delete(oriKey); if (errCode != E_OK) { - LOG_ERROR("delete data failed, errCode=%d", errCode); + LOG_ERROR("delete data failed, errCode=%{public}d", errCode); return errCode; } + PreferencesValue value; - NotifyPreferencesObserver(key, value); + ExecutorPool::Task task = [pref = shared_from_this(), key, value] { + PreferencesEnhanceImpl::NotifyPreferencesObserver(pref, key, value); + }; + executorPool_.Execute(std::move(task)); return E_OK; } std::map PreferencesEnhanceImpl::GetAll() { std::shared_lock autoLock(dbMutex_); + if (db_ == nullptr) { + LOG_ERROR("PreferencesEnhanceImpl:GetAll failed, db has been closed."); + return {}; + } + std::map result; std::list, std::vector>> data; int errCode = db_->GetAll(data); if (errCode != E_OK) { - LOG_ERROR("get all failed, errCode=%d", errCode); + LOG_ERROR("get all failed, errCode=%{public}d", errCode); return {}; } for (auto it = data.begin(); it != data.end(); it++) { @@ -147,17 +181,19 @@ std::map PreferencesEnhanceImpl::GetAll() auto item = PreferencesValueParcel::UnmarshallingPreferenceValue(it->second); result.insert({key, item.second}); if (item.first != E_OK) { - LOG_ERROR("get key failed, errCode=%d", errCode); + LOG_ERROR("get key failed, errCode=%{public}d", errCode); return {}; } } return result; } -void PreferencesEnhanceImpl::NotifyPreferencesObserver(const std::string &key, const PreferencesValue &value) +void PreferencesEnhanceImpl::NotifyPreferencesObserver(std::shared_ptr pref, + const std::string &key, const PreferencesValue &value) { - LOG_DEBUG("notify observer size:%{public}zu", dataObserversMap_.size()); - for (const auto &[weakPrt, keys] : dataObserversMap_) { + std::shared_lock readLock(pref->mapSharedMutex_); + LOG_DEBUG("notify observer size:%{public}zu", pref->dataObserversMap_.size()); + for (const auto &[weakPrt, keys] : pref->dataObserversMap_) { std::map records = {{key, value}}; if (std::shared_ptr sharedPtr = weakPrt.lock()) { LOG_DEBUG("dataChange observer call, resultSize:%{public}zu", records.size()); @@ -165,15 +201,52 @@ void PreferencesEnhanceImpl::NotifyPreferencesObserver(const std::string &key, c } } auto dataObsMgrClient = DataObsMgrClient::GetInstance(); - for (auto it = localObservers_.begin(); it != localObservers_.end(); ++it) { + for (auto it = pref->localObservers_.begin(); it != pref->localObservers_.end(); ++it) { std::weak_ptr weakPreferencesObserver = *it; if (std::shared_ptr sharedPreferencesObserver = weakPreferencesObserver.lock()) { sharedPreferencesObserver->OnChange(key); } } if (dataObsMgrClient != nullptr) { - dataObsMgrClient->NotifyChange(MakeUri(key)); + dataObsMgrClient->NotifyChange(pref->MakeUri(key)); + } +} + +int PreferencesEnhanceImpl::Clear() +{ + std::unique_lock writeLock(dbMutex_); + if (db_ == nullptr) { + LOG_ERROR("PreferencesEnhanceImpl:Clear failed, db has been closed."); + return E_ERROR; + } + + int errCode = db_->DropCollection(); + if (errCode != E_OK) { + LOG_ERROR("drop collection failed when clear, errCode=%{public}d", errCode); + return errCode; + } + errCode = db_->CreateCollection(); + if (errCode != E_OK) { + LOG_ERROR("create collection failed when clear, errCode=%{public}d", errCode); + } + return errCode; +} + +int PreferencesEnhanceImpl::CloseDb() +{ + std::unique_lock writeLock(dbMutex_); + if (db_ == nullptr) { + LOG_WARN("PreferencesEnhanceImpl:CloseDb failed, db has been closed, no need to close again."); + return E_OK; } + int errCode = db_->CloseDb(); + if (errCode != E_OK) { + LOG_ERROR("PreferencesEnhanceImpl:CloseDb failed."); + return errCode; + } + db_ = nullptr; + return E_OK; } + } // End of namespace NativePreferences } // End of namespace OHOS diff --git a/preferences/frameworks/native/src/preferences_helper.cpp b/preferences/frameworks/native/src/preferences_helper.cpp index c0497bde..0a26ca47 100644 --- a/preferences/frameworks/native/src/preferences_helper.cpp +++ b/preferences/frameworks/native/src/preferences_helper.cpp @@ -28,10 +28,9 @@ #include "preferences_file_operation.h" #include "preferences_impl.h" #include "preferences_enhance_impl.h" -#include "securec.h" namespace OHOS { namespace NativePreferences { -std::map> PreferencesHelper::prefsCache_; +std::map, bool>> PreferencesHelper::prefsCache_; std::mutex PreferencesHelper::prefsCacheMutex_; static bool IsFileExist(const std::string &path) @@ -42,35 +41,42 @@ static bool IsFileExist(const std::string &path) static int RemoveEnhanceDbFileIfNeed(const std::string &filePath) { - if (IsFileExist(filePath.c_str()) && std::remove(filePath.c_str()) != 0) { - LOG_ERROR("remove filePath failed."); + std::string dbFilePath = filePath + ".db"; + if (IsFileExist(dbFilePath) && std::remove(dbFilePath.c_str()) != 0) { + LOG_ERROR("remove dbFilePath failed."); return E_DELETE_FILE_FAIL; } - std::string tmpFilePath = filePath + ".ctrl"; - if (IsFileExist(tmpFilePath.c_str()) && std::remove(tmpFilePath.c_str()) != 0) { + std::string tmpFilePath = dbFilePath + ".ctrl"; + if (IsFileExist(tmpFilePath) && std::remove(tmpFilePath.c_str()) != 0) { LOG_ERROR("remove ctrlFile failed."); return E_DELETE_FILE_FAIL; } - tmpFilePath = filePath + ".redo"; - if (IsFileExist(tmpFilePath.c_str()) && std::remove(tmpFilePath.c_str()) != 0) { + tmpFilePath = dbFilePath + ".ctrl.dwr"; + if (IsFileExist(tmpFilePath) && std::remove(tmpFilePath.c_str()) != 0) { + LOG_ERROR("remove ctrl dwr File failed."); + return E_DELETE_FILE_FAIL; + } + tmpFilePath = dbFilePath + ".redo"; + if (IsFileExist(tmpFilePath) && std::remove(tmpFilePath.c_str()) != 0) { LOG_ERROR("remove ctrlFile failed."); return E_DELETE_FILE_FAIL; } - tmpFilePath = filePath + ".undo"; - if (IsFileExist(tmpFilePath.c_str()) && std::remove(tmpFilePath.c_str()) != 0) { + tmpFilePath = dbFilePath + ".undo"; + if (IsFileExist(tmpFilePath) && std::remove(tmpFilePath.c_str()) != 0) { LOG_ERROR("remove ctrlFile failed."); return E_DELETE_FILE_FAIL; } - tmpFilePath = filePath + ".safe"; - if (IsFileExist(tmpFilePath.c_str()) && std::remove(tmpFilePath.c_str()) != 0) { + tmpFilePath = dbFilePath + ".safe"; + if (IsFileExist(tmpFilePath) && std::remove(tmpFilePath.c_str()) != 0) { LOG_ERROR("remove ctrlFile failed."); return E_DELETE_FILE_FAIL; } - tmpFilePath = filePath + ".map"; - if (IsFileExist(tmpFilePath.c_str()) && std::remove(tmpFilePath.c_str()) != 0) { + tmpFilePath = dbFilePath + ".map"; + if (IsFileExist(tmpFilePath) && std::remove(tmpFilePath.c_str()) != 0) { LOG_ERROR("remove ctrlFile failed."); return E_DELETE_FILE_FAIL; } + LOG_DEBUG("db files has been removed."); return E_OK; } @@ -122,10 +128,18 @@ std::string PreferencesHelper::GetRealPath(const std::string &path, int &errorCo } #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) -static bool IsUseEnhanceDb(std::string bundleName) +static bool IsUseEnhanceDb(const Options &options) { + if (IsFileExist(options.filePath)) { + return false; + } PreferenceDbAdapter::ApiInit(); - return (bundleName.find("meetimeservice") != std::string::npos) && PreferenceDbAdapter::IsEnhandceDbEnable(); + return (options.bundleName.find("uttest") != std::string::npos || + options.bundleName.find("alipay") != std::string::npos || + options.bundleName.find("com.jd.") != std::string::npos || + options.bundleName.find("cmblife") != std::string::npos || + options.bundleName.find("os.mms") != std::string::npos || + options.bundleName.find("meetimeservice") != std::string::npos) && PreferenceDbAdapter::IsEnhandceDbEnable(); } #endif @@ -137,18 +151,26 @@ std::shared_ptr PreferencesHelper::GetPreferences(const Options &op } std::lock_guard lock(prefsCacheMutex_); - std::map>::iterator it = prefsCache_.find(realPath); + auto it = prefsCache_.find(realPath); if (it != prefsCache_.end()) { - return it->second; + auto pre = it->second.first; + if (pre != nullptr) { + LOG_DEBUG("GetPreferences: found preferences in cache"); + return pre; + } + LOG_DEBUG("GetPreferences: found preferences in cache but it's null, erase it."); + prefsCache_.erase(it); } const_cast(options).filePath = realPath; std::shared_ptr pref = nullptr; + bool isEnhancePreferences = false; #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) &&!defined(IOS_PLATFORM) - if (IsUseEnhanceDb(options.bundleName)) { + if (IsUseEnhanceDb(options)) { LOG_DEBUG("PreferencesHelper::GetPreferences using enhance db."); pref = PreferencesEnhanceImpl::GetPreferences(options); errCode = std::static_pointer_cast(pref)->Init(); + isEnhancePreferences = true; } else { pref = PreferencesImpl::GetPreferences(options); errCode = std::static_pointer_cast(pref)->Init(); @@ -160,7 +182,7 @@ std::shared_ptr PreferencesHelper::GetPreferences(const Options &op if (errCode != E_OK) { return nullptr; } - prefsCache_.insert(make_pair(realPath, pref)); + prefsCache_.insert({realPath, {pref, isEnhancePreferences}}); return pref; } @@ -175,10 +197,22 @@ int PreferencesHelper::DeletePreferences(const std::string &path) std::string dataGroupId = ""; { std::lock_guard lock(prefsCacheMutex_); - std::map>::iterator it = prefsCache_.find(realPath); + std::map, bool>>::iterator it = prefsCache_.find(realPath); if (it != prefsCache_.end()) { - dataGroupId = it->second->GetGroupId(); + auto pref = it->second.first; + if (pref != nullptr) { + dataGroupId = pref->GetGroupId(); + errCode = pref->CloseDb(); + if (errCode != E_OK) { + LOG_ERROR("failed to close db when delete preferences."); + return errCode; + } + } + pref = nullptr; prefsCache_.erase(it); + LOG_INFO("DeletePreferences: found preferences in cache, erase it."); + } else { + LOG_INFO("DeletePreferences: cache not found, just delete files."); } } @@ -214,12 +248,23 @@ int PreferencesHelper::RemovePreferencesFromCache(const std::string &path) } std::lock_guard lock(prefsCacheMutex_); - std::map>::iterator it = prefsCache_.find(realPath); + std::map, bool>>::iterator it = prefsCache_.find(realPath); if (it == prefsCache_.end()) { + LOG_INFO("RemovePreferencesFromCache: preferences not in cache, just return"); return E_OK; } + + if (it->second.second) { + auto pref = it->second.first; + errCode = std::static_pointer_cast(pref)->CloseDb(); + if (errCode != E_OK) { + LOG_ERROR("RemovePreferencesFromCache: failed to close db."); + return E_ERROR; + } + } + prefsCache_.erase(it); return E_OK; } } // End of namespace NativePreferences -} // End of namespace OHOS +} // End of namespace OHOS \ No newline at end of file diff --git a/preferences/frameworks/native/src/preferences_impl.cpp b/preferences/frameworks/native/src/preferences_impl.cpp index 8145f921..238fc0b3 100644 --- a/preferences/frameworks/native/src/preferences_impl.cpp +++ b/preferences/frameworks/native/src/preferences_impl.cpp @@ -22,17 +22,20 @@ #include #include #include +#include +#include #include "base64_helper.h" #include "executor_pool.h" #include "log_print.h" #include "preferences_observer_stub.h" #include "preferences_xml_utils.h" -#include "securec.h" namespace OHOS { namespace NativePreferences { +using namespace std::chrono; + constexpr int32_t WAIT_TIME = 2; template @@ -119,8 +122,6 @@ std::string GetTypeName() return "BigInt"; } -ExecutorPool PreferencesImpl::executorPool_ = ExecutorPool(1, 0); - PreferencesImpl::PreferencesImpl(const Options &options) : PreferencesBase(options), loaded_(false) { currentMemoryStateGeneration_ = 0; @@ -146,7 +147,7 @@ bool PreferencesImpl::StartLoadFromDisk() loaded_ = false; } - ExecutorPool::Task task = std::bind(PreferencesImpl::LoadFromDisk, shared_from_this()); + ExecutorPool::Task task = [pref = shared_from_this()] { PreferencesImpl::LoadFromDisk(pref); }; return (executorPool_.Execute(std::move(task)) == ExecutorPool::INVALID_TASK_ID) ? false : true; } @@ -159,7 +160,8 @@ void PreferencesImpl::LoadFromDisk(std::shared_ptr pref) } bool loadResult = pref->ReadSettingXml(pref); if (!loadResult) { - LOG_ERROR("The settingXml load failed."); + auto time = static_cast(duration_cast(system_clock::now().time_since_epoch()).count()); + LOG_ERROR("The settingXml load failed. times %{public}" PRIu64 ".", time); } pref->loaded_ = true; pref->cond_.notify_all(); @@ -224,6 +226,7 @@ PreferencesValue PreferencesImpl::Get(const std::string &key, const PreferencesV std::map PreferencesImpl::GetAll() { AwaitLoadFile(); + std::lock_guard lock(mutex_); return map_; } @@ -460,6 +463,7 @@ int PreferencesImpl::Delete(const std::string &key) if (errCode != E_OK) { return errCode; } + AwaitLoadFile(); std::lock_guard lock(mutex_); @@ -474,6 +478,7 @@ int PreferencesImpl::Delete(const std::string &key) int PreferencesImpl::Clear() { + AwaitLoadFile(); std::lock_guard lock(mutex_); if (!map_.empty()) { @@ -489,7 +494,7 @@ void PreferencesImpl::Flush() { std::shared_ptr request = commitToMemory(); request->isSyncRequest_ = false; - ExecutorPool::Task task = std::bind(PreferencesImpl::WriteToDiskFile, shared_from_this(), request); + ExecutorPool::Task task = [pref = shared_from_this(), request] { PreferencesImpl::WriteToDiskFile(pref, request); }; executorPool_.Execute(std::move(task)); NotifyPreferencesObserver(*request); diff --git a/preferences/frameworks/native/src/preferences_utils.cpp b/preferences/frameworks/native/src/preferences_utils.cpp index 5638d43a..40a0e42d 100644 --- a/preferences/frameworks/native/src/preferences_utils.cpp +++ b/preferences/frameworks/native/src/preferences_utils.cpp @@ -35,7 +35,7 @@ int CheckKey(const std::string &key) return E_KEY_EMPTY; } if (MAX_KEY_LENGTH < key.length()) { - LOG_ERROR("The key string length should shorter than 80."); + LOG_ERROR("The key string length should shorter than 1024."); return E_KEY_EXCEED_MAX_LENGTH; } return E_OK; @@ -53,13 +53,13 @@ int CheckValue(const PreferencesValue &value) if (value.IsString()) { std::string val = value; - return lengthCheck(val.length(), "the value string length should shorter than 8 * 1024."); + return lengthCheck(val.length(), "the value string length should shorter than 16 * 1024 * 1024."); } if (value.IsObject()) { Object obj = value; - return lengthCheck(obj.valueStr.length(), "the length of the object converted to JSON should be less than 8 *" - " 1024"); + return lengthCheck(obj.valueStr.length(), "the length of the object converted to JSON should be less than 16 *" + " 1024 * 1024"); } if (value.IsBigInt()) { diff --git a/preferences/frameworks/native/src/preferences_value.cpp b/preferences/frameworks/native/src/preferences_value.cpp index 2394e1d4..28ac43cc 100644 --- a/preferences/frameworks/native/src/preferences_value.cpp +++ b/preferences/frameworks/native/src/preferences_value.cpp @@ -60,7 +60,7 @@ PreferencesValue::PreferencesValue(bool value) PreferencesValue::PreferencesValue(const char *value) { - PreferencesValue(std::string(value)); + value_ = std::string(value); } PreferencesValue::PreferencesValue(std::string value) diff --git a/preferences/frameworks/native/src/preferences_value_parcel.cpp b/preferences/frameworks/native/src/preferences_value_parcel.cpp index 4920c12e..435755a4 100644 --- a/preferences/frameworks/native/src/preferences_value_parcel.cpp +++ b/preferences/frameworks/native/src/preferences_value_parcel.cpp @@ -46,8 +46,10 @@ uint8_t PreferencesValueParcel::GetTypeIndex(const PreferencesValue &value) return UINT8_ARRAY_TYPE; } else if (value.IsObject()) { return OBJECT_TYPE; - } else { + } else if (value.IsBigInt()) { return BIG_INT_TYPE; + } else { + return MONO_TYPE; } } @@ -105,7 +107,7 @@ int PreferencesValueParcel::MarshallingBasicValueInner(const PreferencesValue &v uint8_t *startAddr = data.data(); size_t basicDataLen = 0; if (data.size() <= sizeof(uint8_t)) { - LOG_ERROR("memcpy error when marshalling basic value, type: %d", type); + LOG_ERROR("memcpy error when marshalling basic value, type: %{public}d", type); return E_ERROR; } size_t memLen = data.size() - sizeof(uint8_t); @@ -146,7 +148,7 @@ int PreferencesValueParcel::MarshallingBasicValueInner(const PreferencesValue &v } if (errCode != E_OK) { - LOG_ERROR("memcpy failed when marshalling basic value, %d", errCode); + LOG_ERROR("memcpy failed when marshalling basic value, %{public}d", errCode); return E_ERROR; } return E_OK; @@ -164,7 +166,7 @@ int PreferencesValueParcel::MarshallingBasicValue(const PreferencesValue &value, uint8_t *startAddr = data.data(); int errCode = memcpy_s(startAddr, data.size(), &type, sizeof(uint8_t)); if (errCode != E_OK) { - LOG_ERROR("memcpy failed when marshalling basic value's type, %d", errCode); + LOG_ERROR("memcpy failed when marshalling basic value's type, %{public}d", errCode); return E_NOT_SUPPORTED; } return MarshallingBasicValueInner(value, type, data); @@ -190,19 +192,19 @@ int PreferencesValueParcel::MarshallingStringValue(const PreferencesValue &value uint8_t *startAddr = data.data(); int errCode = memcpy_s(startAddr, sizeof(uint8_t), &type, sizeof(uint8_t)); if (errCode != E_OK) { - LOG_ERROR("memcpy failed when marshalling string value's type, %d", errCode); + LOG_ERROR("memcpy failed when marshalling string value's type, %{public}d", errCode); return -E_ERROR; } size_t strLen = stringValue.size(); errCode = memcpy_s(startAddr + sizeof(uint8_t), sizeof(size_t), &strLen, sizeof(size_t)); if (errCode != E_OK) { - LOG_ERROR("memcpy failed when marshalling string value's str len, %d", errCode); + LOG_ERROR("memcpy failed when marshalling string value's str len, %{public}d", errCode); return -E_ERROR; } errCode = memcpy_s(startAddr + sizeof(uint8_t) + sizeof(size_t), strLen, stringValue.c_str(), strLen); if (errCode != E_OK) { - LOG_ERROR("memcpy failed when marshalling string value's str data, %d", errCode); + LOG_ERROR("memcpy failed when marshalling string value's str data, %{public}d", errCode); return -E_ERROR; } return E_OK; @@ -222,7 +224,7 @@ int PreferencesValueParcel::MarshallingStringArrayValue(const PreferencesValue & // write type into data int errCode = memcpy_s(startAddr, sizeof(uint8_t), &type, sizeof(uint8_t)); if (errCode != E_OK) { - LOG_ERROR("memcpy failed when marshalling string array value's type, %d", errCode); + LOG_ERROR("memcpy failed when marshalling string array value's type, %{public}d", errCode); return -E_ERROR; } startAddr += sizeof(uint8_t); @@ -231,7 +233,7 @@ int PreferencesValueParcel::MarshallingStringArrayValue(const PreferencesValue & size_t vecNum = strVec.size(); errCode = memcpy_s(startAddr, sizeof(size_t), &vecNum, sizeof(size_t)); if (errCode != E_OK) { - LOG_ERROR("memcpy failed when marshalling string array value's vector num, %d", errCode); + LOG_ERROR("memcpy failed when marshalling string array value's vector num, %{public}d", errCode); return -E_ERROR; } startAddr += sizeof(size_t); @@ -241,14 +243,14 @@ int PreferencesValueParcel::MarshallingStringArrayValue(const PreferencesValue & size_t strLen = strVec[i].size(); errCode = memcpy_s(startAddr, sizeof(size_t), &strLen, sizeof(size_t)); if (errCode != E_OK) { - LOG_ERROR("memcpy failed when marshalling string array value's str len, %d", errCode); + LOG_ERROR("memcpy failed when marshalling string array value's str len, %{public}d", errCode); return -E_ERROR; } startAddr += sizeof(size_t); errCode = memcpy_s(startAddr, strLen, strVec[i].c_str(), strLen); if (errCode != E_OK) { - LOG_ERROR("memcpy failed when marshalling string array value's str data, %d", errCode); + LOG_ERROR("memcpy failed when marshalling string array value's str data, %{public}d", errCode); return -E_ERROR; } startAddr += strLen; @@ -263,13 +265,13 @@ int PreferencesValueParcel::MarshallingVecUInt8AfterType(const PreferencesValue // write vec num int errCode = memcpy_s(startAddr, sizeof(size_t), &vecNum, sizeof(size_t)); if (errCode != E_OK) { - LOG_ERROR("memcpy failed when marshalling uint8 array value's vector num, %d", errCode); + LOG_ERROR("memcpy failed when marshalling uint8 array value's vector num, %{public}d", errCode); return E_ERROR; } startAddr += sizeof(size_t); errCode = memcpy_s(startAddr, vecNum * sizeof(uint8_t), vec.data(), vecNum * sizeof(uint8_t)); if (errCode != E_OK) { - LOG_ERROR("memcpy failed when marshalling uint8 array value's data, %d", errCode); + LOG_ERROR("memcpy failed when marshalling uint8 array value's data, %{public}d", errCode); return E_ERROR; } return errCode; @@ -291,7 +293,7 @@ int PreferencesValueParcel::MarshallingVecBigIntAfterType(const PreferencesValue size_t vecNum = words.size(); int errCode = memcpy_s(startAddr, sizeof(size_t), &vecNum, sizeof(size_t)); if (errCode != E_OK) { - LOG_ERROR("memcpy failed when marshalling bigInt array value's vector num, %d", errCode); + LOG_ERROR("memcpy failed when marshalling bigInt array value's vector num, %{public}d", errCode); return E_ERROR; } startAddr += sizeof(size_t); @@ -299,7 +301,7 @@ int PreferencesValueParcel::MarshallingVecBigIntAfterType(const PreferencesValue // write sign errCode = memcpy_s(startAddr, sizeof(int64_t), &sign, sizeof(int64_t)); if (errCode != E_OK) { - LOG_ERROR("memcpy failed when marshalling bigInt array value's sign, %d", errCode); + LOG_ERROR("memcpy failed when marshalling bigInt array value's sign, %{public}d", errCode); return E_ERROR; } startAddr += sizeof(int64_t); @@ -309,7 +311,7 @@ int PreferencesValueParcel::MarshallingVecBigIntAfterType(const PreferencesValue uint64_t item = words[i]; errCode = memcpy_s(startAddr, sizeof(uint64_t), &item, sizeof(uint64_t)); if (errCode != E_OK) { - LOG_ERROR("memcpy failed when marshalling bigInt array value's words, %d", errCode); + LOG_ERROR("memcpy failed when marshalling bigInt array value's words, %{public}d", errCode); return E_ERROR; } startAddr += sizeof(uint64_t); @@ -324,7 +326,7 @@ int PreferencesValueParcel::MarshallingVecDoubleAfterType(const PreferencesValue // write vec num int errCode = memcpy_s(startAddr, sizeof(size_t), &vecNum, sizeof(size_t)); if (errCode != E_OK) { - LOG_ERROR("memcpy failed when marshalling double array value's vector num, %d", errCode); + LOG_ERROR("memcpy failed when marshalling double array value's vector num, %{public}d", errCode); return E_ERROR; } startAddr += sizeof(size_t); @@ -334,7 +336,7 @@ int PreferencesValueParcel::MarshallingVecDoubleAfterType(const PreferencesValue double item = vec[i]; errCode = memcpy_s(startAddr, sizeof(double), &item, sizeof(double)); if (errCode != E_OK) { - LOG_ERROR("memcpy failed when marshalling double array value's vector data, %d", errCode); + LOG_ERROR("memcpy failed when marshalling double array value's vector data, %{public}d", errCode); return E_ERROR; } startAddr += sizeof(double); @@ -349,7 +351,7 @@ int PreferencesValueParcel::MarshallingVecBoolAfterType(const PreferencesValue & // write vec num int errCode = memcpy_s(startAddr, sizeof(size_t), &vecNum, sizeof(size_t)); if (errCode != E_OK) { - LOG_ERROR("memcpy failed when marshalling bool array value's vector num, %d", errCode); + LOG_ERROR("memcpy failed when marshalling bool array value's vector num, %{public}d", errCode); return E_ERROR; } startAddr += sizeof(size_t); @@ -359,7 +361,7 @@ int PreferencesValueParcel::MarshallingVecBoolAfterType(const PreferencesValue & bool item = vec[i]; errCode = memcpy_s(startAddr, sizeof(bool), &item, sizeof(bool)); if (errCode != E_OK) { - LOG_ERROR("memcpy failed when marshalling bool array value's vector data, %d", errCode); + LOG_ERROR("memcpy failed when marshalling bool array value's vector data, %{public}d", errCode); return E_ERROR; } startAddr += sizeof(bool); @@ -379,7 +381,7 @@ int PreferencesValueParcel::MarshallingBasicArrayValue(const PreferencesValue &v uint8_t *startAddr = data.data(); int errCode = memcpy_s(startAddr, sizeof(uint8_t), &type, sizeof(uint8_t)); if (errCode != E_OK) { - LOG_ERROR("memcpy failed when marshalling basic array value's type, %d", errCode); + LOG_ERROR("memcpy failed when marshalling basic array value's type, %{public}d", errCode); return E_ERROR; } // write type @@ -432,7 +434,7 @@ int PreferencesValueParcel::MarshallingPreferenceValue(const PreferencesValue &v break; default: errCode = E_INVALID_ARGS; - LOG_ERROR("MarshallingPreferenceValue failed, type invalid, %d", errCode); + LOG_ERROR("MarshallingPreferenceValue failed, type invalid, %{public}d", errCode); break; } return errCode; @@ -608,7 +610,7 @@ std::pair PreferencesValueParcel::UnmarshallingPreference { PreferencesValue value(0); if (data.empty()) { - LOG_ERROR("UnmarshallingPreferenceValue failed, data empty, %d", E_INVALID_ARGS); + LOG_ERROR("UnmarshallingPreferenceValue failed, data empty, %{public}d", E_INVALID_ARGS); return std::make_pair(E_INVALID_ARGS, value); } uint8_t type = data[0]; diff --git a/preferences/frameworks/native/src/preferences_xml_utils.cpp b/preferences/frameworks/native/src/preferences_xml_utils.cpp index 69343220..468de99b 100644 --- a/preferences/frameworks/native/src/preferences_xml_utils.cpp +++ b/preferences/frameworks/native/src/preferences_xml_utils.cpp @@ -89,7 +89,7 @@ static bool RenameToBrokenFile(const std::string &fileName) static xmlDoc *ReadFile(const std::string &fileName) { - return xmlReadFile(fileName.c_str(), "UTF-8", XML_PARSE_NOBLANKS); + return xmlReadFile(fileName.c_str(), "UTF-8", XML_PARSE_NOBLANKS | XML_PARSE_HUGE); } static xmlDoc *XmlReadFile(const std::string &fileName, const std::string &dataGroupId) diff --git a/preferences/interfaces/inner_api/BUILD.gn b/preferences/interfaces/inner_api/BUILD.gn index 49b3e917..a8efac9b 100644 --- a/preferences/interfaces/inner_api/BUILD.gn +++ b/preferences/interfaces/inner_api/BUILD.gn @@ -71,10 +71,17 @@ if (is_ohos) { ohos_shared_library("native_preferences") { branch_protector_ret = "pac_ret" sanitize = { + boundary_sanitize = true + ubsan = true cfi = true cfi_cross_dso = true debug = false } + cflags_cc = [ + "-std=c++17", + "-stdlib=libc++", + "-fvisibility=hidden", + ] all_dependent_configs = [ ":native_preferences_public_config" ] sources = base_sources sources += [ @@ -90,8 +97,6 @@ if (is_ohos) { configs = [ ":native_preferences_config" ] - cflags_cc = [ "-fvisibility=hidden" ] - deps = [ "//third_party/libxml2:libxml2" ] external_deps = [ "ability_base:zuri", "ability_runtime:dataobs_manager", @@ -99,6 +104,7 @@ if (is_ohos) { "hilog:libhilog", "hitrace:hitrace_meter", "ipc:ipc_core", + "libxml2:libxml2", ] public_configs = [ ":native_preferences_public_config" ] subsystem_name = "distributeddatamgr" @@ -130,8 +136,8 @@ if (is_ohos) { } deps = [ "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog_${buildos}", - "//third_party/libxml2:static_libxml2", ] + external_deps = [ "libxml2:static_libxml2" ] public_configs = [ ":native_preferences_public_config" ] subsystem_name = "distributeddatamgr" @@ -202,12 +208,14 @@ ohos_static_library("native_preferences_static") { } deps = [ "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog_${buildos}", - "//third_party/libxml2:static_libxml2", ] + external_deps = [ "libxml2:static_libxml2" ] } else { if (is_ohos) { branch_protector_ret = "pac_ret" sanitize = { + boundary_sanitize = true + ubsan = true cfi = true cfi_cross_dso = true debug = false @@ -218,7 +226,6 @@ ohos_static_library("native_preferences_static") { "${preferences_native_path}/src/preferences_value_parcel.cpp", ] } - deps = [ "//third_party/libxml2:libxml2" ] external_deps = [ "ability_base:zuri", "ability_runtime:dataobs_manager", @@ -226,6 +233,7 @@ ohos_static_library("native_preferences_static") { "hilog:libhilog", "hitrace:hitrace_meter", "ipc:ipc_core", + "libxml2:libxml2", ] } diff --git a/preferences/interfaces/inner_api/include/preferences.h b/preferences/interfaces/inner_api/include/preferences.h index d0537e75..a7ac1c9a 100644 --- a/preferences/interfaces/inner_api/include/preferences.h +++ b/preferences/interfaces/inner_api/include/preferences.h @@ -61,12 +61,12 @@ public: /** * @brief The constant Indicates the maximum length of the key in the preferences. */ - PREF_API_EXPORT static constexpr uint32_t MAX_KEY_LENGTH = 80; + PREF_API_EXPORT static constexpr uint32_t MAX_KEY_LENGTH = 1024; /** * @brief The constant Indicates the maximum length of the value in the preferences. */ - PREF_API_EXPORT static constexpr uint32_t MAX_VALUE_LENGTH = 8 * 1024; + PREF_API_EXPORT static constexpr uint32_t MAX_VALUE_LENGTH = 16 * 1024 * 1024; /** * @brief Obtains the value of a preferences. @@ -304,6 +304,21 @@ public: virtual int RegisterObserver( std::shared_ptr preferencesObserver, RegisterMode mode = RegisterMode::LOCAL_CHANGE) = 0; + int Subscribe(std::shared_ptr observer, RegisterMode mode = RegisterMode::LOCAL_CHANGE, + const std::vector &keys = {}) + { + switch (mode) { + case RegisterMode::LOCAL_CHANGE: + case RegisterMode::MULTI_PRECESS_CHANGE: + return RegisterObserver(observer, mode); + case RegisterMode::DATA_CHANGE: + return RegisterDataObserver(observer, keys); + default: + break; + } + return E_INVALID_ARGS; + } + /** * @brief Unregister an existing observer. * @@ -313,7 +328,22 @@ public: */ virtual int UnRegisterObserver( std::shared_ptr preferencesObserver, RegisterMode mode = RegisterMode::LOCAL_CHANGE) = 0; - + + int Unsubscribe(std::shared_ptr observer, RegisterMode mode = RegisterMode::LOCAL_CHANGE, + const std::vector &keys = {}) + { + switch (mode) { + case RegisterMode::LOCAL_CHANGE: + case RegisterMode::MULTI_PRECESS_CHANGE: + return UnRegisterObserver(observer, mode); + case RegisterMode::DATA_CHANGE: + return UnRegisterDataObserver(observer, keys); + default: + break; + } + return E_INVALID_ARGS; + } + /** * @brief Get group id. * @@ -326,6 +356,11 @@ public: return ""; } + virtual int CloseDb() + { + return E_OK; + } + /** * @brief Registers a data observer. * diff --git a/preferences/interfaces/inner_api/include/preferences_errno.h b/preferences/interfaces/inner_api/include/preferences_errno.h index b8e20c3b..2a9051c4 100644 --- a/preferences/interfaces/inner_api/include/preferences_errno.h +++ b/preferences/interfaces/inner_api/include/preferences_errno.h @@ -21,6 +21,13 @@ namespace OHOS { namespace NativePreferences { +constexpr int SUBSYS_DISTRIBUTEDDATAMNG = 13; +constexpr int SUBSYSTEM_BIT_NUM = 21; +constexpr int MODULE_BIT_NUM = 16; +constexpr int MODULE_PREFERENCES = 6; +constexpr int DISTRIBUTEDDATAMGR_PREFERENCES_ERR_OFFSET = (SUBSYS_DISTRIBUTEDDATAMNG << SUBSYSTEM_BIT_NUM) | + (MODULE_PREFERENCES << MODULE_BIT_NUM); + /** * @brief The error code in the correct case. */ @@ -29,12 +36,12 @@ constexpr int E_OK = 0; /** * @brief The base code of the exception error code. */ -constexpr int E_BASE = 15500000; +constexpr int E_BASE = DISTRIBUTEDDATAMGR_PREFERENCES_ERR_OFFSET; /** * @brief The error when the capability not supported. */ -constexpr int E_NOT_SUPPORTED = 801; +constexpr int E_NOT_SUPPORTED = (E_BASE + 801); /** * @brief The error code for common exceptions. @@ -67,7 +74,7 @@ constexpr int E_NOT_PERMIT = (E_BASE + 4); // operation is not permitted constexpr int E_KEY_EMPTY = (E_BASE + 5); /** -* @brief The error code for the key string length exceed the max length (80). +* @brief The error code for the key string length exceed the max length (1024). */ constexpr int E_KEY_EXCEED_MAX_LENGTH = (E_BASE + 6); @@ -108,7 +115,7 @@ constexpr int E_INVALID_FILE_PATH = (E_BASE + 12); constexpr int E_PATH_EXCEED_MAX_LENGTH = (E_BASE + 13); /** -* @brief The error code for the value exceeds the max length (8 * 1024). +* @brief The error code for the value exceeds the max length (16 * 1024 * 1024 ). */ constexpr int E_VALUE_EXCEED_MAX_LENGTH = (E_BASE + 14); diff --git a/preferences/interfaces/inner_api/include/preferences_helper.h b/preferences/interfaces/inner_api/include/preferences_helper.h index 6e813392..984788f5 100644 --- a/preferences/interfaces/inner_api/include/preferences_helper.h +++ b/preferences/interfaces/inner_api/include/preferences_helper.h @@ -69,7 +69,8 @@ public: PREF_API_EXPORT static int RemovePreferencesFromCache(const std::string &path); private: - static std::map> prefsCache_; + // use bool to mark whether Preferences is EnhancePreferences or not + static std::map, bool>> prefsCache_; static std::mutex prefsCacheMutex_; static std::string GetRealPath(const std::string &path, int &errorCode); diff --git a/preferences/interfaces/inner_api/include/preferences_observer.h b/preferences/interfaces/inner_api/include/preferences_observer.h index 390f6118..e844cc67 100644 --- a/preferences/interfaces/inner_api/include/preferences_observer.h +++ b/preferences/interfaces/inner_api/include/preferences_observer.h @@ -30,7 +30,7 @@ namespace NativePreferences { class PREF_API_EXPORT PreferencesObserver { public: - enum RegisterMode { LOCAL_CHANGE = 0, MULTI_PRECESS_CHANGE, DATA_CHANGE}; + enum RegisterMode { LOCAL_CHANGE = 0, MULTI_PRECESS_CHANGE, DATA_CHANGE, CHANGE_BUTT }; PREF_API_EXPORT virtual ~PreferencesObserver(); /** diff --git a/preferences/interfaces/inner_api/include/preferences_value.h b/preferences/interfaces/inner_api/include/preferences_value.h index f8dea609..e0c7f65f 100644 --- a/preferences/interfaces/inner_api/include/preferences_value.h +++ b/preferences/interfaces/inner_api/include/preferences_value.h @@ -362,8 +362,8 @@ public: */ PREF_API_EXPORT bool operator==(const PreferencesValue &value); - std::variant, - std::vector, std::vector, std::vector, Object, BigInt, std::monostate> value_; + std::variant, + std::vector, std::vector, std::vector, Object, BigInt> value_; }; } // End of namespace NativePreferences } // End of namespace OHOS diff --git a/preferences/preferences.gni b/preferences/preferences.gni index 9e0b2eae..039eec52 100644 --- a/preferences/preferences.gni +++ b/preferences/preferences.gni @@ -15,6 +15,8 @@ preferences_base_path = "//foundation/distributeddatamgr/preferences" preferences_napi_path = "${preferences_base_path}/frameworks/js/napi" +preferences_cj_path = "${preferences_base_path}/frameworks/cj/src" + preferences_native_path = "${preferences_base_path}/frameworks/native" preferences_innerapi_path = "${preferences_base_path}/interfaces/inner_api" diff --git a/preferences/test/js/unittest/preferences/src/PreferencesCallBackJsunit.test.js b/preferences/test/js/unittest/preferences/src/PreferencesCallBackJsunit.test.js index 829ca740..64bedc97 100644 --- a/preferences/test/js/unittest/preferences/src/PreferencesCallBackJsunit.test.js +++ b/preferences/test/js/unittest/preferences/src/PreferencesCallBackJsunit.test.js @@ -373,18 +373,22 @@ describe('PreferencesCallBackJsunit', function () { * @tc.desc put Uint8Array callback interface test */ it('testPreferencesPutUint8Array0183', 0, async function (done) { - let uInt8Array = new Uint8Array(8192); + console.log(TAG + "testPreferencesPutUint8Array0183 start."); + let uInt8Array = new Uint8Array(16 * 1024 * 1024); uInt8Array.fill(100); mPreferences.put(KEY_TEST_UINT8ARRAY, uInt8Array, async function (err, ret) { let pre = await mPreferences.get(KEY_TEST_UINT8ARRAY, new Uint8Array(0)); - expect(uInt8Array.toString() === pre.toString()).assertTrue(); + expect(uInt8Array.length === pre.length).assertTrue(); + expect(100 === pre[0]).assertTrue(); await mPreferences.flush(); await data_preferences.removePreferencesFromCache(context, NAME); mPreferences = null; mPreferences = await data_preferences.getPreferences(context, NAME); let pre2 = await mPreferences.get(KEY_TEST_UINT8ARRAY, new Uint8Array(0)); + expect(uInt8Array.length === pre2.length).assertTrue(); + expect(100 === pre2[0]).assertTrue(); done(); - expect(uInt8Array.toString() === pre2.toString()).assertTrue(); + console.log(TAG + "testPreferencesPutUint8Array0183 end."); }); }) @@ -394,7 +398,7 @@ describe('PreferencesCallBackJsunit', function () { * @tc.desc put Uint8Array callback interface test */ it('testPreferencesPutUint8Array0183', 0, async function (done) { - let uInt8Array = new Uint8Array(8193); + let uInt8Array = new Uint8Array(16 * 1024 * 1024 + 1); uInt8Array.fill(100); try { await mPreferences.put(KEY_TEST_UINT8ARRAY, uInt8Array); diff --git a/preferences/test/js/unittest/preferences/src/PreferencesPromiseJsunit.test.js b/preferences/test/js/unittest/preferences/src/PreferencesPromiseJsunit.test.js index e2b76cc3..a1002e43 100644 --- a/preferences/test/js/unittest/preferences/src/PreferencesPromiseJsunit.test.js +++ b/preferences/test/js/unittest/preferences/src/PreferencesPromiseJsunit.test.js @@ -514,18 +514,22 @@ describe('PreferencesPromiseJsunit', function () { * @tc.desc put Uint8Array promise interface test */ it('testPreferencesPutUint8Array0202', 0, async function () { - let uInt8Array = new Uint8Array(8192); + console.log("testPreferencesPutUint8Array0202 start"); + let uInt8Array = new Uint8Array(16 * 1024 * 1024); uInt8Array.fill(100); const promise = mPreferences.put(KEY_TEST_UINT8ARRAY, uInt8Array); await promise.then(async (ret) => { let pre = await mPreferences.get(KEY_TEST_UINT8ARRAY, new Uint8Array(0)); - expect(uInt8Array.toString() === pre.toString()).assertTrue(); + expect(uInt8Array.length === pre.length).assertTrue(); + expect(100 === pre[0]).assertTrue(); await mPreferences.flush(); await data_preferences.removePreferencesFromCache(context, NAME); mPreferences = null; mPreferences = await data_preferences.getPreferences(context, NAME); let pre2 = await mPreferences.get(KEY_TEST_UINT8ARRAY, new Uint8Array(0)); - expect(uInt8Array.toString() === pre2.toString()).assertTrue(); + expect(uInt8Array.length === pre2.length).assertTrue(); + expect(100 === pre2[0]).assertTrue(); + console.log("testPreferencesPutUint8Array0202 end"); }).catch((err) => { expect(null).assertFail(); }); @@ -537,7 +541,7 @@ describe('PreferencesPromiseJsunit', function () { * @tc.desc put Uint8Array promise interface test */ it('testPreferencesPutUint8Array0203', 0, async function () { - let uInt8Array = new Uint8Array(8193); + let uInt8Array = new Uint8Array(16 * 1024 * 1024 + 1); uInt8Array.fill(100); try { await mPreferences.put(KEY_TEST_UINT8ARRAY, uInt8Array); @@ -579,6 +583,7 @@ describe('PreferencesPromiseJsunit', function () { name: "xiaohong", age: "99" } + console.log("testPreferencesPutObject002 start"); const promise = mPreferences.put(KEY_TEST_OBJECT, obj); await promise.then(async (ret) => { await mPreferences.flush(); @@ -593,6 +598,7 @@ describe('PreferencesPromiseJsunit', function () { console.log('get object data2 : ' + JSON.stringify(data2)); expect(obj["age"]).assertEqual("99"); expect(JSON.stringify(data2)).assertEqual(JSON.stringify(obj)); + console.log("testPreferencesPutObject002 end"); done(); }).catch((err) => { console.log("try catch err =" + err + ", code =" + err.code + ", message =" + err.message); @@ -606,7 +612,8 @@ describe('PreferencesPromiseJsunit', function () { * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Preferences_0206 * @tc.desc put Bigint negative test */ - it('testPreferencesPutBigInt0001', 0, async function () { + it('testPreferencesPutBigInt0001', 0, async function (done) { + console.log("testPreferencesPutBigInt0001 start"); let bigint = BigInt("-12345678912345678912345678971234567123456"); await mPreferences.put(KEY_TEST_BIGINT, bigint); let pre = await mPreferences.get(KEY_TEST_BIGINT, BigInt(0)); @@ -617,6 +624,8 @@ describe('PreferencesPromiseJsunit', function () { mPreferences = await data_preferences.getPreferences(context, NAME); let pre2 = await mPreferences.get(KEY_TEST_BIGINT, BigInt(0)); expect(bigint === pre2).assertTrue(); + console.log("testPreferencesPutBigInt0001 end"); + done(); }) /** diff --git a/preferences/test/js/unittest/preferences/src/PreferencesSyncJsunit.test.js b/preferences/test/js/unittest/preferences/src/PreferencesSyncJsunit.test.js index a4a12355..b472621e 100644 --- a/preferences/test/js/unittest/preferences/src/PreferencesSyncJsunit.test.js +++ b/preferences/test/js/unittest/preferences/src/PreferencesSyncJsunit.test.js @@ -16,7 +16,7 @@ import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from import data_preferences from '@ohos.data.preferences' import featureAbility from '@ohos.ability.featureAbility'; -const NAME = 'test_preferences'; +const NAME = 'test_taskpool_preferences'; const KEY_TEST_INT_ELEMENT = 'key_test_int'; const KEY_TEST_LONG_ELEMENT = 'key_test_long'; const KEY_TEST_FLOAT_ELEMENT = 'key_test_float'; diff --git a/preferences/test/js/unittest/preferences/src/PreferencesTaskpoolJsunit.test.js b/preferences/test/js/unittest/preferences/src/PreferencesTaskpoolJsunit.test.js new file mode 100644 index 00000000..bee77e80 --- /dev/null +++ b/preferences/test/js/unittest/preferences/src/PreferencesTaskpoolJsunit.test.js @@ -0,0 +1,182 @@ +/* +* Copyright (c) 2024 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from 'deccjsunit/index' +import data_preferences from '@ohos.data.preferences'; +import featureAbility from '@ohos.ability.featureAbility'; +import taskpool from '@ohos.taskpool' + +const NAME = 'test_taskpool_preferences'; +const KEY_TEST_STRING_ELEMENT = 'key_test_string'; +var context; + +const TAG = '[PREFERENCES_CALLBACK_JSUNIT_TEST]' + +function sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +} + +describe('PreferencesTaskpoolJsunit', function () { + beforeAll(function () { + console.info('beforeAll') + context = featureAbility.getContext() + }) + + beforeEach(async function () { + console.info('beforeEach'); + }) + + afterEach(async function () { + console.info('afterEach'); + await data_preferences.deletePreferences(context, NAME); + }) + + afterAll(function () { + console.info('afterAll') + }) + + /** + * @tc.name clear taskpool interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Taskpool_0001 + * @tc.desc clear taskpool interface test + */ + it('testPreferencesTaskpoolClear0001', 0, async function (done) { + async function PreferencesPut() { + for (let index = 0; index < 100; index++) { + let mPreferences = await data_preferences.getPreferences(context, NAME); + await mPreferences.put(KEY_TEST_STRING_ELEMENT + index.toString(), "test" + index.toString()); + await mPreferences.flush() + } + } + async function PreferencesClear() { + for (let index = 0; index < 100; index++) { + let mPreferences = await data_preferences.getPreferences(context, NAME); + await mPreferences.clear(); + await mPreferences.flush() + } + } + taskpool.execute(PreferencesPut); + taskpool.execute(PreferencesClear); + await sleep(3000); + done(); + }) + + /** + * @tc.name clear taskpool interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Taskpool_0002 + * @tc.desc clear taskpool interface test + */ + it('testPreferencesTaskpoolClear0002', 0, async function (done) { + async function PreferencesPut() { + for (let index = 0; index < 100; index++) { + let mPreferences = await data_preferences.getPreferences(context, NAME); + mPreferences.putSync(KEY_TEST_STRING_ELEMENT + index.toString(), "test" + index.toString()); + await mPreferences.flush() + } + } + async function PreferencesClear() { + for (let index = 0; index < 100; index++) { + let mPreferences = await data_preferences.getPreferences(context, NAME); + mPreferences.clearSync(); + await mPreferences.flush() + } + } + taskpool.execute(PreferencesPut); + taskpool.execute(PreferencesClear); + await sleep(3000); + done(); + }) + + /** + * @tc.name preferences taskpool interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Taskpool_0003 + * @tc.desc preferences taskpool interface test + */ + it('testPreferencesTaskpool0001', 0, async function (done) { + console.info('testPreferencesTaskpool0001 start'); + async function PreferencesPut() { + for (let index = 0; index < 100; index++) { + let mPreferences = await data_preferences.getPreferences(context, NAME); + await mPreferences.put(KEY_TEST_STRING_ELEMENT + index.toString(), "test" + index.toString()); + await mPreferences.get(KEY_TEST_STRING_ELEMENT + index.toString(), "defaultvalue"); + await mPreferences.flush() + } + } + async function PreferencesUpdate() { + for (let index = 0; index < 100; index++) { + let pref = await data_preferences.getPreferences(context, NAME); + pref.has(KEY_TEST_STRING_ELEMENT + index.toString(), async function (err, ret) { + let val = "test" + index.toString(); + await pref.delete(KEY_TEST_STRING_ELEMENT + index.toString()); + await pref.flush(); + await pref.put(KEY_TEST_STRING_ELEMENT + index.toString(), "test"); + await pref.flush(); + }); + } + } + taskpool.execute(PreferencesPut); + taskpool.execute(PreferencesUpdate); + await sleep(3000); + await data_preferences.removePreferencesFromCache(context, NAME); + let preference = await data_preferences.getPreferences(context, NAME); + preference.getAll().then((ret) => { + done(); + console.log("testPreferencesTaskpool0002 end."); + }).catch((err) => { + console.log("getAll err =" + err + ", code =" + err.code + ", message =" + err.message); + expect(false).assertTrue(); + }) + }) + + /** + * @tc.name preferences sync taskpool interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Taskpool_0004 + * @tc.desc preferences sync taskpool interface test + */ + it('testPreferencesTaskpool0002', 0, async function (done) { + async function PreferencesPutSync() { + for (let index = 0; index < 100; index++) { + let mPreferences = await data_preferences.getPreferences(context, NAME); + mPreferences.putSync(KEY_TEST_STRING_ELEMENT + index.toString(), "test" + index.toString()); + mPreferences.getSync(KEY_TEST_STRING_ELEMENT + index.toString(), "defaultvalue"); + await mPreferences.flush() + } + } + async function PreferencesUpdateSync() { + for (let index = 0; index < 100; index++) { + let pref = await data_preferences.getPreferences(context, NAME); + pref.has(KEY_TEST_STRING_ELEMENT + index.toString(), async function (err, ret) { + let val = "test" + index.toString(); + pref.deleteSync(KEY_TEST_STRING_ELEMENT + index.toString()); + await pref.flush(); + pref.putSync(KEY_TEST_STRING_ELEMENT + index.toString(), "test"); + await pref.flush(); + pref.getSync(KEY_TEST_STRING_ELEMENT + index.toString(), "defaultvalue"); + }); + } + } + taskpool.execute(PreferencesPutSync); + taskpool.execute(PreferencesUpdateSync); + await sleep(3000); + await data_preferences.removePreferencesFromCache(context, NAME); + let preference = await data_preferences.getPreferences(context, NAME); + preference.getAll().then((ret) => { + done(); + console.log("testPreferencesTaskpool0002 end."); + }).catch((err) => { + console.log("getAll err =" + err + ", code =" + err.code + ", message =" + err.message); + expect(false).assertTrue(); + }) + }) +}) \ No newline at end of file diff --git a/preferences/test/js/unittest/preferences/src/V9_PreferencesCallBackJsunit.test.js b/preferences/test/js/unittest/preferences/src/V9_PreferencesCallBackJsunit.test.js index d114ed52..b4c19737 100644 --- a/preferences/test/js/unittest/preferences/src/V9_PreferencesCallBackJsunit.test.js +++ b/preferences/test/js/unittest/preferences/src/V9_PreferencesCallBackJsunit.test.js @@ -28,11 +28,11 @@ const KEY_TEST_BOOL_ARRAY_ELEMENT = 'key_test_bool_array' var mPreference = undefined var context -const ILLEGAL_CHAR_10 = '1234567890' -const ILLEGAL_CHAR_80 = ILLEGAL_CHAR_10.repeat(8); -const ILLEGAL_CHAR_81 = ILLEGAL_CHAR_80 + '1'; -const ILLEGAL_CHAR_8192 = ILLEGAL_CHAR_80.repeat(102) + '1'.repeat(32); -const ILLEGAL_CHAR_8193 = ILLEGAL_CHAR_8192 + '1'; +const ILLEGAL_CHAR_8 = '12345678' +const ILLEGAL_CHAR_1024 = ILLEGAL_CHAR_8.repeat(128); +const ILLEGAL_CHAR_1025 = ILLEGAL_CHAR_1024 + '1'; +const ILLEGAL_CHAR_LARGEST = ILLEGAL_CHAR_1024.repeat(16 * 1024); +const ILLEGAL_CHAR_INVALID = ILLEGAL_CHAR_LARGEST + '1'; describe('V9_PreferencesCallBackJsunit', async function () { beforeAll(async function () { @@ -336,11 +336,11 @@ describe('V9_PreferencesCallBackJsunit', async function () { /** * @tc.name test put interface - * @tc.desc test put interface input parameter key exceed 80bytes. + * @tc.desc test put interface input parameter key exceed 1024 bytes. */ it('testPreferencesPutIllegal0003', 0, async function (done) { try { - mPreference.put(ILLEGAL_CHAR_81, "123456", (ret) => { + mPreference.put(ILLEGAL_CHAR_1025, "123456", (ret) => { done(); }); } catch (err) { @@ -356,7 +356,7 @@ describe('V9_PreferencesCallBackJsunit', async function () { */ it('testPreferencesPutIllegal0004', 0, async function (done) { try { - mPreference.put(ILLEGAL_CHAR_80, "123456", (ret) => { + mPreference.put(ILLEGAL_CHAR_1024, "123456", (ret) => { done(); }); } catch (err) { @@ -368,11 +368,11 @@ describe('V9_PreferencesCallBackJsunit', async function () { /** * @tc.name test put interface - * @tc.desc test put interface input parameter value exceed 8192bytes. + * @tc.desc test put interface input parameter value exceed 16 * 1024 * 1024 bytes. */ it('testPreferencesPutIllegal0005', 0, async function (done) { try { - mPreference.put("test", ILLEGAL_CHAR_8193, (ret) => { + mPreference.put("test", ILLEGAL_CHAR_INVALID, (ret) => { done(); }); } catch (err) { @@ -388,7 +388,7 @@ describe('V9_PreferencesCallBackJsunit', async function () { */ it('testPreferencesPutIllegal0006', 0, async function (done) { try { - mPreference.put("test", ILLEGAL_CHAR_8192, (ret) => { + mPreference.put("test", ILLEGAL_CHAR_LARGEST, (ret) => { done(); }); } catch (err) { @@ -434,11 +434,11 @@ describe('V9_PreferencesCallBackJsunit', async function () { /** * @tc.name test get interface - * @tc.desc test get interface input parameter key exceed 80bytes. + * @tc.desc test get interface input parameter key exceed 1024 bytes. */ it('testPreferencesGetIllegal0003', 0, async function (done) { try { - mPreference.get(ILLEGAL_CHAR_81, "defaultValue", (ret) => { + mPreference.get(ILLEGAL_CHAR_1025, "defaultValue", (ret) => { done(); }); } catch (err) { @@ -454,7 +454,7 @@ describe('V9_PreferencesCallBackJsunit', async function () { */ it('testPreferencesGetIllegal0004', 0, async function (done) { try { - mPreference.get(ILLEGAL_CHAR_80, "defaultValue", (ret) => { + mPreference.get(ILLEGAL_CHAR_1024, "defaultValue", (ret) => { done(); }); } catch (err) { @@ -500,11 +500,11 @@ describe('V9_PreferencesCallBackJsunit', async function () { /** * @tc.name test delete interface - * @tc.desc test delete interface input parameter key exceed 80bytes. + * @tc.desc test delete interface input parameter key exceed 1024 bytes. */ it('testPreferencesDeleteIllegal0003', 0, async function (done) { try { - mPreference.delete(ILLEGAL_CHAR_81, (ret) => { + mPreference.delete(ILLEGAL_CHAR_1025, (ret) => { done(); }); } catch (err) { @@ -520,7 +520,7 @@ describe('V9_PreferencesCallBackJsunit', async function () { */ it('testPreferencesDeleteIllegal0004', 0, async function (done) { try { - mPreference.delete(ILLEGAL_CHAR_80, (ret) => { + mPreference.delete(ILLEGAL_CHAR_1024, (ret) => { done(); }); } catch (err) { @@ -566,11 +566,11 @@ describe('V9_PreferencesCallBackJsunit', async function () { /** * @tc.name test has interface - * @tc.desc test has interface input parameter key exceed 80bytes. + * @tc.desc test has interface input parameter key exceed 1024 bytes. */ it('testPreferencesHasIllegal0003', 0, async function (done) { try { - mPreference.has(ILLEGAL_CHAR_81, (ret) => { + mPreference.has(ILLEGAL_CHAR_1025, (ret) => { done(); }); } catch (err) { @@ -586,7 +586,7 @@ describe('V9_PreferencesCallBackJsunit', async function () { */ it('testPreferencesHasIllegal0004', 0, async function (done) { try { - mPreference.has(ILLEGAL_CHAR_80, (ret) => { + mPreference.has(ILLEGAL_CHAR_1024, (ret) => { done(); }); } catch (err) { diff --git a/preferences/test/js/unittest/preferences/src/V9_PreferencesPromiseJsunit.test.js b/preferences/test/js/unittest/preferences/src/V9_PreferencesPromiseJsunit.test.js index 7bd95464..aee3268a 100644 --- a/preferences/test/js/unittest/preferences/src/V9_PreferencesPromiseJsunit.test.js +++ b/preferences/test/js/unittest/preferences/src/V9_PreferencesPromiseJsunit.test.js @@ -304,6 +304,7 @@ describe('V9_PreferencesPromiseJsunit', async function () { expect(false).assertTrue() } finally { mPreference.off('change', observer); + done(); } }) @@ -362,6 +363,7 @@ describe('V9_PreferencesPromiseJsunit', async function () { } }) + // test on dataChange with an empty array key it('testPreferencesDataChange001', 0, async function (done) { console.log("testPreferencesDataChange001 begin.") await mPreference.clear(); @@ -369,26 +371,28 @@ describe('V9_PreferencesPromiseJsunit', async function () { var observer = function (data) { }; mPreference.on('dataChange', [], observer); - expect(false).assertTrue() + expect().assertFail() } catch (err) { console.log("trycatch err =" + err + ", code =" + err.code + ", message =" + err.message) done(); } }) + // test off dataChange with non-array key it('testPreferencesDataChange002', 0, async function (done) { console.log("testPreferencesDataChange002 begin.") await mPreference.clear(); try { var observer = function (data) {} mPreference.off('dataChange', {}, observer); - expect(false).assertTrue() + expect().assertFail() } catch (err) { console.log("trycatch err =" + err + ", code =" + err.code + ", message =" + err.message) done(); } }) + // test on dataChange with non-array key it('testPreferencesDataChange003', 0, async function (done) { console.log("testPreferencesDataChange003 begin.") await mPreference.clear(); @@ -399,25 +403,27 @@ describe('V9_PreferencesPromiseJsunit', async function () { var observer = function (data) { }; mPreference.on('dataChange', obj, observer); - expect(false).assertTrue() + expect().assertFail() } catch (err) { console.log("trycatch err =" + err + ", code =" + err.code + ", message =" + err.message) done(); } }) + // test on dataChange without callback it('testPreferencesDataChange004', 0, async function (done) { console.log("testPreferencesDataChange004 begin.") await mPreference.clear(); try { mPreference.on('dataChange', []); - expect(false).assertTrue() + expect().assertFail() } catch (err) { console.log("trycatch err =" + err + ", code =" + err.code + ", message =" + err.message) done(); } }) + // test the subscription callback of on dataChange it('testPreferencesDataChange005', 0, async function (done) { console.log("testPreferencesDataChange005 begin.") await mPreference.clear(); @@ -461,7 +467,7 @@ describe('V9_PreferencesPromiseJsunit', async function () { await mPreference.flush() } catch (err) { console.log("trycatch err =" + err + ", code =" + err.code + ", message =" + err.message) - expect(false).assertTrue() + expect().assertFail() } finally { mPreference.off('dataChange', ['key1'], observer1) mPreference.off('dataChange', ['key1', 'key2', 'key4'], observer2) @@ -470,13 +476,14 @@ describe('V9_PreferencesPromiseJsunit', async function () { } }) + // test off dataChange with an empty key and callback1 it('testPreferencesDataChange006', 0, async function (done) { console.log("testPreferencesDataChange006 begin.") await mPreference.clear(); try { var observer1 = function (data) { console.log("observer1") - expect(false).assertTrue() + expect().assertFail() } var observer2 = function (data) { console.log("observer2") @@ -496,10 +503,11 @@ describe('V9_PreferencesPromiseJsunit', async function () { done() } catch (err) { console.log("trycatch err =" + err + ", code =" + err.code + ", message =" + err.message) - expect(false).assertTrue() + expect().assertFail() } }) + // test off dataChange with array keys1 and without callback it('testPreferencesDataChange007', 0, async function (done) { console.log("testPreferencesDataChange007 begin.") await mPreference.clear(); @@ -529,27 +537,26 @@ describe('V9_PreferencesPromiseJsunit', async function () { done() } catch (err) { console.log("trycatch err =" + err + ", code =" + err.code + ", message =" + err.message) - expect(false).assertTrue() + expect().assertFail() } }) - - + // test off dataChange with an empty array key without callback it('testPreferencesDataChange008', 0, async function (done) { console.log("testPreferencesDataChange008 begin.") await mPreference.clear(); try { var observer1 = function (data) { console.log("observer1") - expect(false).assertTrue() + expect().assertFail() } var observer2 = function (data) { console.log("observer2") - expect(false).assertTrue() + expect().assertFail() } var observer3= function (data) { console.log("observer3") - expect(false).assertTrue() + expect().assertFail() } let keys = ['key1', 'key2', 'key3'] mPreference.on('dataChange', keys, observer1); @@ -562,10 +569,11 @@ describe('V9_PreferencesPromiseJsunit', async function () { done() } catch (err) { console.log("trycatch err =" + err + ", code =" + err.code + ", message =" + err.message) - expect(false).assertTrue() + expect().assertFail() } }) + // test off dataChange with array keys1, callback1 and array keys2, callback2 it('testPreferencesDataChange009', 0, async function (done) { console.log("testPreferencesDataChange009 begin.") await mPreference.clear(); @@ -579,7 +587,7 @@ describe('V9_PreferencesPromiseJsunit', async function () { } var observer2 = function (data) { console.log("observer2") - expect(false).assertTrue() + expect().assertFail() } mPreference.on('dataChange', ['key1', 'key2'], observer1); mPreference.on('dataChange', ['key1', 'key3'], observer2); @@ -591,13 +599,14 @@ describe('V9_PreferencesPromiseJsunit', async function () { await mPreference.flush() } catch (err) { console.log("trycatch err =" + err + ", code =" + err.code + ", message =" + err.message) - expect(false).assertTrue() + expect().assertFail() } finally { mPreference.off('dataChange', []) done() } }) + // test put then delete and on dataChange subscribe to callback it('testPreferencesDataChange010', 0, async function (done) { console.log("testPreferencesDataChange010 begin.") await mPreference.clear(); @@ -624,14 +633,14 @@ describe('V9_PreferencesPromiseJsunit', async function () { await mPreference.delete("key2", (err) => { if (err) { console.log("delete err =" + err + ", code =" + err.code +", message =" + err.message) - expect(false).assertTrue() + expect().assertFail() } console.log("delete err") }); await mPreference.flush() } catch (err) { console.log("trycatch err =" + err + ", code =" + err.code + ", message =" + err.message) - expect(false).assertTrue() + expect().assertFail() } finally { mPreference.off('dataChange', []) done() diff --git a/preferences/test/js/unittest/storage/src/StorageCallBackJsunit.test.js b/preferences/test/js/unittest/storage/src/StorageCallBackJsunit.test.js index 64129ff4..4588234a 100644 --- a/preferences/test/js/unittest/storage/src/StorageCallBackJsunit.test.js +++ b/preferences/test/js/unittest/storage/src/StorageCallBackJsunit.test.js @@ -358,11 +358,11 @@ describe('StorageCallBackJsunit', function () { /** * @tc.name test put interface * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0123 - * @tc.desc test put interface input parameter value exceed 8192byte. + * @tc.desc test put interface input parameter value exceed 16 * 1024 * 1024byte. */ it('testPutIllegal003', 0, async function (done) { let phoneStr = "1"; - phoneStr = phoneStr.repeat(8193); + phoneStr = phoneStr.repeat(16 * 1024 * 1024 + 1); try { mPref.put("phoneNum", phoneStr, (ret) => { done(); @@ -381,7 +381,7 @@ describe('StorageCallBackJsunit', function () { */ it('testPutIllegal004', 0, async function (done) { let phoneStr = "1"; - phoneStr = phoneStr.repeat(8192); + phoneStr = phoneStr.repeat(16 * 1024 * 1024); try { mPref.put("phoneNum", phoneStr, (ret) => { done(); @@ -396,11 +396,11 @@ describe('StorageCallBackJsunit', function () { /** * @tc.name test put interface * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0125 - * @tc.desc test put interface input parameter key exceed 80byte. + * @tc.desc test put interface input parameter key exceed 1024 byte. */ it('testPutIllegal005', 0, async function (done) { let phoneNum = "1"; - phoneNum = phoneNum.repeat(81); + phoneNum = phoneNum.repeat(1025); try { mPref.put(phoneNum, "123456", (ret) => { done(); @@ -419,7 +419,7 @@ describe('StorageCallBackJsunit', function () { */ it('testPutIllegal006', 0, async function (done) { let phoneNum = "1"; - phoneNum = phoneNum.repeat(80); + phoneNum = phoneNum.repeat(1024); try { mPref.put(phoneNum, "123456", (ret) => { done(); @@ -470,11 +470,11 @@ describe('StorageCallBackJsunit', function () { /** * @tc.name test get interface * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0128 - * @tc.desc test get interface input parameter key exceed 80byte. + * @tc.desc test get interface input parameter key exceed 1024 byte. */ it('testGetIllegal003', 0, async function (done) { let illegalKey = "1"; - illegalKey = illegalKey.repeat(81); + illegalKey = illegalKey.repeat(1025); try { mPref.get(illegalKey, "defaultValue", (ret) => { done(); @@ -493,7 +493,7 @@ describe('StorageCallBackJsunit', function () { */ it('testGetIllegal004', 0, async function (done) { let legalKey = "1"; - legalKey = legalKey.repeat(80); + legalKey = legalKey.repeat(1024); try { mPref.get(legalKey, "defaultValue", (ret) => { done(); diff --git a/preferences/test/js/unittest/storage/src/StorageSyncJsunit.test.js b/preferences/test/js/unittest/storage/src/StorageSyncJsunit.test.js index 2324968c..982368c5 100644 --- a/preferences/test/js/unittest/storage/src/StorageSyncJsunit.test.js +++ b/preferences/test/js/unittest/storage/src/StorageSyncJsunit.test.js @@ -301,11 +301,11 @@ describe('StorageSyncJsunit', function () { /** * @tc.name test putSync interface * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Sync_0170 - * @tc.desc test put interface input parameter key exceed 80byte. + * @tc.desc test put interface input parameter key exceed 1024 bytes. */ it('testputSyncIllegal001', 0, function () { let illegalKey = "1"; - illegalKey = illegalKey.repeat(81); + illegalKey = illegalKey.repeat(1025); try { mPref.putSync(illegalKey, "123456"); expect(false).assertTrue(); @@ -321,7 +321,7 @@ describe('StorageSyncJsunit', function () { */ it('testputSyncIllegal002', 0, function () { let legalKey = "1"; - legalKey = legalKey.repeat(80); + legalKey = legalKey.repeat(1024); try { mPref.putSync(legalKey, "123456"); } catch (err) { @@ -333,11 +333,11 @@ describe('StorageSyncJsunit', function () { /** * @tc.name test putSync interface * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Sync_0180 - * @tc.desc test put interface input parameter value exceed 8192byte. + * @tc.desc test put interface input parameter value exceed 16 * 1024 * 1024byte. */ it('testputSyncIllegal003', 0, function () { let illegalValue = "1"; - illegalValue = illegalValue.repeat(8193); + illegalValue = illegalValue.repeat(16 * 1024 * 1024 + 1); try { mPref.putSync("test", illegalValue); expect(false).assertTrue(); @@ -353,7 +353,7 @@ describe('StorageSyncJsunit', function () { */ it('testputSyncIllegal004', 0, function () { let legalValue = "1"; - legalValue = legalValue.repeat(8192); + legalValue = legalValue.repeat(16 * 1024 * 1024); try { mPref.putSync("test", legalValue); } catch (err) { @@ -365,11 +365,11 @@ describe('StorageSyncJsunit', function () { /** * @tc.name test getSync interface * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Sync_0190 - * @tc.desc test getSync interface input parameter key exceed 80byte. + * @tc.desc test getSync interface input parameter key exceed 1024 bytes. */ it('testgetSyncIllegal001', 0, function () { let illegalkey = "1"; - illegalkey = illegalkey.repeat(81); + illegalkey = illegalkey.repeat(1025); try { mPref.getSync(illegalkey, "defaultValue"); expect(false).assertTrue(); @@ -385,7 +385,7 @@ describe('StorageSyncJsunit', function () { */ it('testgetSyncIllegal002', 0, function () { let legalkey = "1"; - legalkey = legalkey.repeat(80); + legalkey = legalkey.repeat(1024); try { mPref.getSync(legalkey, "defaultValue"); } catch (err) { @@ -397,11 +397,11 @@ describe('StorageSyncJsunit', function () { /** * @tc.name test deleteSync interface * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Sync_0200 - * @tc.desc test deleteSync interface input parameter key exceed 80byte. + * @tc.desc test deleteSync interface input parameter key exceed 1024 bytes. */ it('testdeleteSyncIllegal001', 0, function () { let illegalkey = "1"; - illegalkey = illegalkey.repeat(81); + illegalkey = illegalkey.repeat(1025); try { mPref.deleteSync(illegalkey); expect(false).assertTrue(); @@ -417,7 +417,7 @@ describe('StorageSyncJsunit', function () { */ it('testdeleteSyncIllegal002', 0, function () { let legalkey = "1"; - legalkey = legalkey.repeat(80); + legalkey = legalkey.repeat(1024); try { mPref.deleteSync(legalkey); } catch (err) { @@ -429,11 +429,11 @@ describe('StorageSyncJsunit', function () { /** * @tc.name test hasSync interface * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Sync_0210 - * @tc.desc test hasSync interface input parameter key exceed 80byte. + * @tc.desc test hasSync interface input parameter key exceed 1024 bytes. */ it('testhasSyncIllegal001', 0, function () { let illegalkey = "1"; - illegalkey = illegalkey.repeat(81); + illegalkey = illegalkey.repeat(1025); try { mPref.hasSync(illegalkey); expect(false).assertTrue(); @@ -449,7 +449,7 @@ describe('StorageSyncJsunit', function () { */ it('testhasSyncIllegal002', 0, function () { let legalkey = "1"; - legalkey = legalkey.repeat(80); + legalkey = legalkey.repeat(1024); try { mPref.hasSync(legalkey); } catch (err) { diff --git a/preferences/test/native/BUILD.gn b/preferences/test/native/BUILD.gn index 96c27476..fbd0b67d 100644 --- a/preferences/test/native/BUILD.gn +++ b/preferences/test/native/BUILD.gn @@ -27,6 +27,12 @@ config("module_private_config") { } ohos_unittest("NativePreferencesTest") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } module_out_path = module_output_path sources = [ diff --git a/preferences/test/native/unittest/preferences_test.cpp b/preferences/test/native/unittest/preferences_test.cpp index 612d9a35..8ade6d4b 100644 --- a/preferences/test/native/unittest/preferences_test.cpp +++ b/preferences/test/native/unittest/preferences_test.cpp @@ -91,6 +91,7 @@ class PreferencesObserverCounter : public PreferencesObserver { public: virtual ~PreferencesObserverCounter(); void OnChange(const std::string &key) override; + void OnChange(const std::map &records) override; std::atomic_int notifyTimes; static const std::vector NOTIFY_KEYS_VECTOR; @@ -110,6 +111,20 @@ void PreferencesObserverCounter::OnChange(const std::string &key) } } +void PreferencesObserverCounter::OnChange( + const std::map &records) +{ + for (auto it = NOTIFY_KEYS_VECTOR.cbegin(); it != NOTIFY_KEYS_VECTOR.cend(); it++) { + for (auto iter = records.begin(); iter != records.end(); iter++) { + std::string key = iter->first; + if (key.compare(*it)) { + notifyTimes++; + return; + } + } + } +} + const std::vector PreferencesObserverCounter::NOTIFY_KEYS_VECTOR = { KEY_TEST_INT_ELEMENT, KEY_TEST_LONG_ELEMENT, KEY_TEST_FLOAT_ELEMENT, KEY_TEST_BOOL_ELEMENT, KEY_TEST_STRING_ELEMENT }; @@ -968,6 +983,23 @@ HWTEST_F(PreferencesTest, NativePreferencesTest_031, TestSize.Level1) PreferencesHelper::DeletePreferences("/data/test/test1"); } +/** + * @tc.name: NativePreferencesTest_032 + * @tc.desc: normal testcase of OnChange DataChange + * @tc.type: FUNC + * @tc.require: Na + * @tc.author: lirui + */ +HWTEST_F(PreferencesTest, NativePreferencesTest_032, TestSize.Level1) +{ + std::shared_ptr counter = std::make_shared(); + std::vector keys = { KEY_TEST_STRING_ELEMENT }; + pref->RegisterDataObserver(counter, keys); + pref->PutString(KEY_TEST_STRING_ELEMENT, "test"); + pref->FlushSync(); + EXPECT_EQ(static_cast(counter.get())->notifyTimes, 1); +} + /** * @tc.name: OperatorTest_001 * @tc.desc: normal testcase of PreferencesValue Operator @@ -1016,5 +1048,14 @@ HWTEST_F(PreferencesTest, PreferencesValueTest_001, TestSize.Level1) std::vector valueVectorUint8(3, 1); std::vector retVectorUint8 = PreferencesValue(valueVectorUint8); EXPECT_EQ(valueVectorUint8, retVectorUint8); + + Object object("{\"key1\":\"value1\",\"key2\":222}"); + Object retObjecte = PreferencesValue(object); + EXPECT_EQ(object, retObjecte); + + std::vector words = { 1, 2, 3 }; + BigInt bigint(words, 0); + BigInt retBigint = PreferencesValue(bigint); + EXPECT_EQ(bigint, retBigint); } } // namespace diff --git a/relational_store/CMakeLists.txt b/relational_store/CMakeLists.txt index b7ac72e8..e8e4d52d 100644 --- a/relational_store/CMakeLists.txt +++ b/relational_store/CMakeLists.txt @@ -23,6 +23,7 @@ aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/native/appdatafwk/sr list(REMOVE_ITEM relational_store_src "${CMAKE_CURRENT_SOURCE_DIR}/frameworks/native/appdatafwk/src/general_endian.cpp") aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/native/rdb/src relational_store_src) +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/native/dfx/src relational_store_src) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/native/dataability/src rdb_adapter_src) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/native/rdb_bms_adaptor/src rdb_adapter_src) @@ -34,6 +35,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/common/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/js/napi/common/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/js/napi/dataability/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/native/dataability/src) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/native/dfx/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/native/rdb/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/frameworks/native/rdb_device_manager_adapter/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../datamgr_service/services/distributeddataservice/adapter/include/dfx) diff --git a/relational_store/bundle.json b/relational_store/bundle.json index 64db47ba..720e818a 100644 --- a/relational_store/bundle.json +++ b/relational_store/bundle.json @@ -54,6 +54,7 @@ "components": [ "ability_base", "ability_runtime", + "access_token", "common_event_service", "c_utils", "device_manager", @@ -64,7 +65,8 @@ "ipc", "kv_store", "napi", - "samgr" + "samgr", + "hisysevent" ], "third_party": [ "icu", @@ -79,6 +81,7 @@ "//foundation/distributeddatamgr/relational_store/interfaces/inner_api/rdb:native_rdb", "//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/cj:cj_relational_store_ffi", "//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", @@ -170,6 +173,8 @@ "//foundation/distributeddatamgr/relational_store/test/js/relationalstore:unittest", "//foundation/distributeddatamgr/relational_store/test/js/clouddata:cloudtest", "//foundation/distributeddatamgr/relational_store/test/ndk:unittest", + "//foundation/distributeddatamgr/relational_store/test/native/appdatafwk:unittest", + "//foundation/distributeddatamgr/relational_store/test/native/clouddata:unittest", "//foundation/distributeddatamgr/relational_store/test/native/dataability:unittest", "//foundation/distributeddatamgr/relational_store/test/native/rdb:unittest", "//foundation/distributeddatamgr/relational_store/test/native/rdb:fuzztest", diff --git a/relational_store/frameworks/cj/BUILD.gn b/relational_store/frameworks/cj/BUILD.gn new file mode 100644 index 00000000..4a01d574 --- /dev/null +++ b/relational_store/frameworks/cj/BUILD.gn @@ -0,0 +1,69 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//build/ohos/ace/ace.gni") +import("//foundation/distributeddatamgr/relational_store/relational_store.gni") + +ohos_shared_library("cj_relational_store_ffi") { + sanitize = { + boundary_sanitize = true + ubsan = true + cfi = true + cfi_cross_dso = true + debug = false + } + + include_dirs = [ + "include", + "${relational_store_common_path}/include", + "${relational_store_js_common_path}/include", + "${relational_store_napi_path}/relationalstore/include", + ] + + if (product_name != "ohos-sdk") { + sources = [ + "src/relational_store_ffi.cpp", + "src/relational_store_impl_rdbpredicatesproxy.cpp", + "src/relational_store_impl_rdbstore.cpp", + "src/relational_store_impl_resultsetproxy.cpp", + "src/relational_store_utils.cpp", + ] + + deps = [ + "${relational_store_innerapi_path}/appdatafwk:native_appdatafwk", + "${relational_store_innerapi_path}/rdb:native_rdb", + "${relational_store_innerapi_path}/rdb_data_share_adapter:rdb_data_share_adapter", + "${relational_store_napi_path}/rdb:napi_rdb", + "${relational_store_napi_path}/relationalstore:relationalstore", + ] + + external_deps = [ + "ability_runtime:abilitykit_native", + "ability_runtime:napi_base_context", + "c_utils:utils", + "common_event_service:cesfwk_innerkits", + "hilog:libhilog", + "hitrace:hitrace_meter", + "napi:ace_napi", + "napi:cj_bind_ffi", + "napi:cj_bind_native", + ] + } else { + defines += [ "PREVIEWER" ] + sources = [ "mock/relational_store_mock.cpp" ] + } + innerapi_tags = [ "platformsdk" ] + subsystem_name = "distributeddatamgr" + part_name = "relational_store" +} diff --git a/relational_store/frameworks/cj/include/native_log.h b/relational_store/frameworks/cj/include/native_log.h new file mode 100644 index 00000000..2abae3fa --- /dev/null +++ b/relational_store/frameworks/cj/include/native_log.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_RELATIONAL_STORE_NATIVE_LOG_H +#define OHOS_RELATIONAL_STORE_NATIVE_LOG_H + +#include "hilog/log.h" + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#ifdef LOG_DOMAIN +#undef LOG_DOMAIN +#endif + +#define LOG_TAG "Rdb" +#define LOG_DOMAIN 0xD001650 + +#define LOGI(...) \ +if (HiLogIsLoggable(LOG_DOMAIN, LOG_TAG, LOG_INFO)) { \ + HILOG_INFO(LOG_CORE, ##__VA_ARGS__); \ +} + +#define LOGE(...) \ +if (HiLogIsLoggable(LOG_DOMAIN, LOG_TAG, LOG_ERROR)) { \ + HILOG_ERROR(LOG_CORE, __VA_ARGS__); \ +} + +#endif // OHOS_RELATIONAL_STORE_NATIVE_LOG_H diff --git a/relational_store/frameworks/cj/include/relational_store_ffi.h b/relational_store/frameworks/cj/include/relational_store_ffi.h new file mode 100644 index 00000000..1cfd3fb7 --- /dev/null +++ b/relational_store/frameworks/cj/include/relational_store_ffi.h @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RELATIONAL_STORE_FFI_H +#define RELATIONAL_STORE_FFI_H + +#include "relational_store_impl_rdbstore.h" +#include "relational_store_impl_rdbpredicatesproxy.h" +#include "relational_store_impl_resultsetproxy.h" +#include +#include "napi_base_context.h" +#include "rdb_store_config.h" +#include "rdb_helper.h" +#include "ffi_remote_data.h" +#include +#include +#include +#include +#include "logger.h" +#include "rdb_errno.h" +#include "rdb_open_callback.h" +#include "rdb_sql_utils.h" +#include "unistd.h" +#include "native_log.h" +#include "js_ability.h" +#include "rdb_common.h" + + +namespace OHOS { +namespace Relational { +extern "C" { + FFI_EXPORT int64_t FfiOHOSRelationalStoreGetRdbStore(OHOS::AbilityRuntime::Context* context, StoreConfig config, + int32_t *errCode); + + FFI_EXPORT void FfiOHOSRelationalStoreDeleteRdbStore(OHOS::AbilityRuntime::Context* context, const char* name, + int32_t *errCode); + + FFI_EXPORT void FfiOHOSRelationalStoreDeleteRdbStoreConfig(OHOS::AbilityRuntime::Context* context, + StoreConfig config, int32_t *errCode); + + FFI_EXPORT int64_t FfiOHOSRelationalStoreRdbPredicatesConstructor(const char* tableName); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreInDevices(int64_t id, const char** devicesArray, int64_t devicesSize); + + FFI_EXPORT CArrStr FfiOHOSRelationalStoreGetAllColumnNames(int64_t id); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreGetColumnCount(int64_t id); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreGetRowCount(int64_t id); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreGetRowIndex(int64_t id); + + FFI_EXPORT bool FfiOHOSRelationalStoreIsAtFirstRow(int64_t id, int32_t *errCode); + + FFI_EXPORT bool FfiOHOSRelationalStoreIsAtLastRow(int64_t id, int32_t *errCode); + + FFI_EXPORT bool FfiOHOSRelationalStoreIsEnded(int64_t id, int32_t *errCode); + + FFI_EXPORT bool FfiOHOSRelationalStoreIsStarted(int64_t id, int32_t *errCode); + + FFI_EXPORT bool FfiOHOSRelationalStoreIsClosed(int64_t id, int32_t *errCode); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreInAllDevices(int64_t id); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreBeginWrap(int64_t id); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreEndWrap(int64_t id); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreOr(int64_t id); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreAnd(int64_t id); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreContains(int64_t id, const char* field, const char* value); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreBeginsWith(int64_t id, const char* field, const char* value); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreEndsWith(int64_t id, const char* field, const char* value); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreIsNull(int64_t id, const char* field); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreIsNotNull(int64_t id, const char* field); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreLike(int64_t id, const char* field, const char* value); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreGlob(int64_t id, const char* field, const char* value); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreOrderByAsc(int64_t id, const char* field); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreOrderByDesc(int64_t id, const char* field); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreDistinct(int64_t id); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreLimitAs(int64_t id, int32_t value); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreOffsetAs(int64_t id, int32_t rowOffset); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreGroupBy(int64_t id, const char** fieldsArray, int64_t fieldsSize); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreIndexedBy(int64_t id, const char* field); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreLessThanOrEqualTo(int64_t id, const char* field, ValueType value); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreEqualTo(int64_t id, const char* field, ValueType value); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreGreaterThanOrEqualTo(int64_t id, const char* field, ValueType value); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreGreaterThan(int64_t id, const char* field, ValueType value); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreNotBetween(int64_t id, const char* field, ValueType lowValue, + ValueType highValue); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreLessThan(int64_t id, const char* field, ValueType value); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreBetween(int64_t id, const char* field, ValueType lowValue, + ValueType highValue); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreIn(int64_t id, const char* field, ValueType* values, int64_t valuesSize); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreNotIn(int64_t id, const char* field, ValueType* values, + int64_t valuesSize); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreNotEqualTo(int64_t id, const char* field, ValueType value); + + FFI_EXPORT int64_t FfiOHOSRelationalStoreQuery(int64_t id, int64_t predicatesId, char** columns, + int64_t columnsSize, int32_t *errCode); + + FFI_EXPORT int64_t FfiOHOSRelationalStoreRemoteQuery(int64_t id, char* device, int64_t predicatesId, char** columns, + int64_t columnsSize); + + FFI_EXPORT int64_t FfiOHOSRelationalStoreUpdate(int64_t id, ValuesBucket valuesBucket, int64_t predicatesId, + NativeRdb::ConflictResolution conflictResolution, int32_t *errCode); + + FFI_EXPORT int64_t FfiOHOSRelationalStoreDelete(int64_t id, int64_t predicatesId, int32_t *errCode); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreSetDistributedTables(int64_t id, char** tables, int64_t tablesSize); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreSetDistributedTablesType(int64_t id, char** tables, int64_t tablesSize, + int32_t type); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreSetDistributedTablesConfig(int64_t id, char** tables, int64_t tablesSize, + int32_t type, DistributedRdb::DistributedConfig &distributedConfig); + + FFI_EXPORT char* FfiOHOSRelationalStoreObtainDistributedTableName(int64_t id, const char* device, char* table); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreRollBack(int64_t id); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreCommit(int64_t id); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreBeginTransaction(int64_t id); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreBackUp(int64_t id, const char* destName); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreReStore(int64_t id, const char* srcName); + + FFI_EXPORT int64_t FfiOHOSRelationalStoreInsert(int64_t id, const char* table, ValuesBucket valuesBucket, + int32_t conflict, int32_t *errCode); + + FFI_EXPORT void FfiOHOSRelationalStoreExecuteSql(int64_t id, const char* sql, int32_t *errCode); + + FFI_EXPORT CArrSyncResult FfiOHOSRelationalStoreSync(int64_t id, int32_t mode, int64_t predicatesId, + int32_t *errCode); + + FFI_EXPORT double FfiOHOSRelationalStoreGetDouble(int64_t id, int32_t columnIndex, int32_t* rtnCode); + + FFI_EXPORT bool FfiOHOSRelationalStoreGoToRow(int64_t id, int32_t position, int32_t* rtnCode); + + FFI_EXPORT bool FfiOHOSRelationalStoreGoToPreviousRow(int64_t id, int32_t* rtnCode); + + FFI_EXPORT bool FfiOHOSRelationalStoreGoToLastRow(int64_t id, int32_t* rtnCode); + + FFI_EXPORT char* FfiOHOSRelationalStoreGetColumnName(int64_t id, int32_t columnIndex, int32_t* rtnCode); + + FFI_EXPORT bool FfiOHOSRelationalStoreIsColumnNull(int64_t id, int32_t columnIndex, int32_t* rtnCode); + + FFI_EXPORT Asset FfiOHOSRelationalStoreGetAsset(int64_t id, int32_t columnIndex, int32_t* rtnCode); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreClose(int64_t id); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreGetColumnIndex(int64_t id, char* columnName, int32_t* rtnCode); + + FFI_EXPORT char* FfiOHOSRelationalStoreGetString(int64_t id, int32_t columnIndex, int32_t* rtnCode); + + FFI_EXPORT bool FfiOHOSRelationalStoreGoToFirstRow(int64_t id, int32_t* rtnCode); + + FFI_EXPORT int64_t FfiOHOSRelationalStoreGetLong(int64_t id, int32_t columnIndex, int32_t* rtnCode); + + FFI_EXPORT bool FfiOHOSRelationalStoreGoToNextRow(int64_t id, int32_t* rtnCode); + + FFI_EXPORT CArrUI8 FfiOHOSRelationalStoreGetBlob(int64_t id, int32_t columnIndex, int32_t* rtnCode); + + FFI_EXPORT bool FfiOHOSRelationalStoreGoTo(int64_t id, int32_t offset, int32_t* rtnCode); + + FFI_EXPORT Assets FfiOHOSRelationalStoreGetAssets(int64_t id, int32_t columnIndex, int32_t* rtnCode); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreCleanDirtyData(int64_t id, const char* tableName, uint64_t cursor); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreBatchInsert(int64_t id, const char* tableName, ValuesBucket* values, + int64_t valuesSize, int64_t* insertNum); + + FFI_EXPORT int64_t FfiOHOSRelationalStoreQuerySql(int64_t id, const char *sql, ValueType *bindArgs, int64_t size, + int32_t* errCode); + + FFI_EXPORT void FfiOHOSRelationalStoreExecuteSqlBindArgs(int64_t id, char* sql, ValueType* bindArgs, + int64_t bindArgsSize, int32_t *errCode); + + FFI_EXPORT ValuesBucket FfiOHOSRelationalStoreGetRow(int64_t id, int32_t *errCode); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreOn(int64_t id, const char *event, bool interProcess, void (*callback)(), + void (*callbackRef)()); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreOff(int64_t id, const char *event, bool interProcess, void (*callback)()); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreOffAll(int64_t id, const char *event, bool interProcess); + + FFI_EXPORT int32_t FfiOHOSRelationalStoreEmit(int64_t id, const char *event); +} +} +} + +#endif \ No newline at end of file diff --git a/relational_store/frameworks/cj/include/relational_store_impl_rdbpredicatesproxy.h b/relational_store/frameworks/cj/include/relational_store_impl_rdbpredicatesproxy.h new file mode 100644 index 00000000..2e776ccc --- /dev/null +++ b/relational_store/frameworks/cj/include/relational_store_impl_rdbpredicatesproxy.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RELATIONAL_STORE_IMPL_RDBPREDICATES_FFI_H +#define RELATIONAL_STORE_IMPL_RDBPREDICATES_FFI_H + +#include "relational_store_utils.h" +#include +#include "ffi_remote_data.h" +#include "rdb_predicates.h" +#include +#include "value_object.h" + +namespace OHOS { +namespace Relational { + class RdbPredicatesImpl : public OHOS::FFI::FFIData { + public: + OHOS::FFI::RuntimeType* GetRuntimeType() override + { + return GetClassType(); + } + + explicit RdbPredicatesImpl(const char* tableName); + + explicit RdbPredicatesImpl(std::shared_ptr predicates); + + void InDevices(const char** devicesArray, int64_t devicesSize); + + void InAllDevices(); + + void BeginWrap(); + + void EndWrap(); + + void Or(); + + void And(); + + void Contains(const char* field, const char* value); + + void BeginsWith(const char* field, const char* value); + + void EndsWith(const char* field, const char* value); + + void IsNull(const char* field); + + void IsNotNull(const char* field); + + void Like(const char* field, const char* value); + + void Glob(const char* field, const char* value); + + void OrderByAsc(const char* field); + + void OrderByDesc(const char* field); + + void Distinct(); + + void LimitAs(int32_t value); + + void OffsetAs(int32_t rowOffset); + + void GroupBy(const char** fieldsArray, int64_t fieldsSize); + + void IndexedBy(const char* field); + + void LessThanOrEqualTo(const char* field, ValueType value); + + void EqualTo(const char* field, ValueType value); + + void GreaterThanOrEqualTo(const char* field, ValueType value); + + void GreaterThan(const char* field, ValueType value); + + void NotBetween(const char* field, ValueType lowValue, ValueType highValue); + + void LessThan(const char* field, ValueType value); + + void Between(const char* field, ValueType lowValue, ValueType highValue); + + void In(const char* field, ValueType* values, int64_t valuesSize); + + void NotIn(const char* field, ValueType* values, int64_t valuesSize); + + void NotEqualTo(const char* field, ValueType value); + + std::shared_ptr GetPredicates(); + private: + std::shared_ptr predicates_; + + friend class OHOS::FFI::RuntimeType; + + friend class OHOS::FFI::TypeBase; + + static OHOS::FFI::RuntimeType* GetClassType(); + }; +} +} + +#endif \ No newline at end of file diff --git a/relational_store/frameworks/cj/include/relational_store_impl_rdbstore.h b/relational_store/frameworks/cj/include/relational_store_impl_rdbstore.h new file mode 100644 index 00000000..4464dc81 --- /dev/null +++ b/relational_store/frameworks/cj/include/relational_store_impl_rdbstore.h @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RELATIONAL_STORE_IMPL_RDBSTORE_FFI_H +#define RELATIONAL_STORE_IMPL_RDBSTORE_FFI_H + +#include +#include "relational_store_impl_resultsetproxy.h" +#include "relational_store_utils.h" +#include "rdb_store_config.h" +#include "ffi_remote_data.h" +#include "napi_base_context.h" +#include "rdb_store.h" +#include "rdb_types.h" +#include "rdb_common.h" +#include "napi_rdb_js_utils.h" +#include "cj_lambda.h" + +namespace OHOS { +namespace Relational { + class RdbStoreObserverImpl : public OHOS::DistributedRdb::RdbStoreObserver { + public: + RdbStoreObserverImpl(std::function *callback, const std::function& callbackRef); + ~RdbStoreObserverImpl() override = default; + void OnChange() override; + void OnChange(const std::vector &devices) override + { + return; + }; + void OnChange(const DistributedRdb::Origin &origin, const PrimaryFields &fields, + ChangeInfo &&changeInfo) override + { + OnChange(origin.id); + }; + std::function *GetCallBack(); + private: + std::function *m_callback; + std::function m_callbackRef; + }; + + class RdbStoreImpl : public OHOS::FFI::FFIData { + public: + OHOS::FFI::RuntimeType* GetRuntimeType() override + { + return GetClassType(); + } + + explicit RdbStoreImpl(std::shared_ptr rdbStore); + + std::shared_ptr Query(RdbPredicatesImpl &predicates, char** column, int64_t columnSize); + std::shared_ptr RemoteQuery(char* device, RdbPredicatesImpl &predicates, char** column, + int64_t columnSize); + int Delete(RdbPredicatesImpl &predicates, int32_t *errCode); + void SetDistributedTables(char** tables, int64_t tablesSize); + void SetDistributedTables(char** tables, int64_t tablesSize, int32_t type); + void SetDistributedTables(char** tables, int64_t tablesSize, int32_t type, + DistributedRdb::DistributedConfig &distributedConfig); + int32_t Commit(); + int32_t RollBack(); + int32_t BeginTransaction(); + int32_t Backup(const char* destName); + int32_t Restore(const char* srcName); + char* ObtainDistributedTableName(const char* device, const char* table); + int32_t Emit(const char* event); + int64_t Insert(const char* table, ValuesBucket valuesBucket, int32_t conflict, int32_t *errCode); + int32_t BatchInsert(int64_t &insertNum, const char* tableName, ValuesBucket* valuesBuckets, int64_t valuesSize); + void ExecuteSql(const char* sql, int32_t *errCode); + int32_t CleanDirtyData(const char* tableName, uint64_t cursor); + CArrSyncResult Sync(int32_t mode, RdbPredicatesImpl &predicates); + int32_t Update(ValuesBucket valuesBucket, RdbPredicatesImpl &predicates, + NativeRdb::ConflictResolution conflictResolution, int32_t *errCode); + std::shared_ptr QuerySql(const char *sql, ValueType *bindArgs, int64_t size); + void ExecuteSql(const char* sql, ValueType* bindArgs, int64_t bindArgsSize, int32_t *errCode); + int32_t RegisterObserver(const char *event, bool interProcess, std::function *callback, + const std::function& callbackRef); + int32_t RegisteredObserver(DistributedRdb::SubscribeOption option, std::map>> &observers, + std::function *callback, const std::function& callbackRef); + bool HasRegisteredObserver(std::function *callback, + std::list> &observers); + int32_t UnRegisterObserver(const char *event, bool interProcess, std::function *callback); + int32_t UnRegisterAllObserver(const char *event, bool interProcess); + int32_t UnRegisteredObserver(DistributedRdb::SubscribeOption option, std::map>> &observers, + std::function *callback); + int32_t UnRegisteredAllObserver(DistributedRdb::SubscribeOption option, std::map>> &observers); + + std::vector bindArgs; + std::shared_ptr rdbStore_; + std::vector newKey; + std::map>> localObservers_; + std::map>> localSharedObservers_; + private: + friend class OHOS::FFI::RuntimeType; + friend class OHOS::FFI::TypeBase; + static OHOS::FFI::RuntimeType* GetClassType(); + }; + + int64_t GetRdbStore(OHOS::AbilityRuntime::Context* context, StoreConfig config, + int32_t *errCode); + + void DeleteRdbStore(OHOS::AbilityRuntime::Context* context, const char* name, + int32_t *errCode); + + void DeleteRdbStoreConfig(OHOS::AbilityRuntime::Context* context, StoreConfig config, + int32_t *errCode); +} +} + +#endif + diff --git a/relational_store/frameworks/cj/include/relational_store_impl_resultsetproxy.h b/relational_store/frameworks/cj/include/relational_store_impl_resultsetproxy.h new file mode 100644 index 00000000..73d1f154 --- /dev/null +++ b/relational_store/frameworks/cj/include/relational_store_impl_resultsetproxy.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RELATIONAL_STORE_IMPL_RESULTSET_FFI_H +#define RELATIONAL_STORE_IMPL_RESULTSET_FFI_H + +#include "relational_store_impl_rdbpredicatesproxy.h" +#include "relational_store_utils.h" +#include "ffi_remote_data.h" +#include "result_set.h" +#include + +namespace OHOS { +namespace Relational { + +class ResultSetImpl : public OHOS::FFI::FFIData { +public: + OHOS::FFI::RuntimeType* GetRuntimeType() override + { + return GetClassType(); + } + + explicit ResultSetImpl(std::shared_ptr resultSet); + + CArrStr GetAllColumnNames(); + + int32_t GetColumnCount(); + + int32_t GetRowCount(); + + int32_t GetRowIndex(); + + bool IsAtFirstRow(); + + bool IsAtLastRow(); + + bool IsEnded(); + + bool IsStarted(); + + bool IsClosed(); + + double GetDouble(int32_t columnIndex, int32_t* rtnCode); + + bool GoToRow(int32_t position, int32_t* rtnCode); + + bool GoToPreviousRow(int32_t* rtnCode); + + bool GoToLastRow(int32_t* rtnCode); + + char* GetColumnName(int32_t columnIndex, int32_t* rtnCode); + + bool IsColumnNull(int32_t columnIndex, int32_t* rtnCode); + + Asset GetAsset(int32_t columnIndex, int32_t* rtnCode); + + int32_t Close(); + + int32_t GetColumnIndex(char* columnName, int32_t* rtnCode); + + char* GetString(int32_t columnIndex, int32_t* rtnCode); + + bool GoToFirstRow(int32_t* rtnCode); + + int64_t GetLong(int32_t columnIndex, int32_t* rtnCode); + + bool GoToNextRow(int32_t* rtnCode); + + CArrUI8 GetBlob(int32_t columnIndex, int32_t* rtnCode); + + bool GoTo(int32_t offset, int32_t* rtnCode); + + Assets GetAssets(int32_t columnIndex, int32_t* rtnCode); + + ValuesBucket GetRow(int32_t* rtnCode); + + std::shared_ptr resultSetValue; + +private: + friend class OHOS::FFI::RuntimeType; + friend class OHOS::FFI::TypeBase; + static OHOS::FFI::RuntimeType* GetClassType(); +}; +} +} + +#endif \ No newline at end of file diff --git a/relational_store/frameworks/cj/include/relational_store_utils.h b/relational_store/frameworks/cj/include/relational_store_utils.h new file mode 100644 index 00000000..f1c4324a --- /dev/null +++ b/relational_store/frameworks/cj/include/relational_store_utils.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RELATIONAL_STORE_UTILS_H +#define RELATIONAL_STORE_UTILS_H + +#include "value_object.h" +#include "securec.h" + +namespace OHOS { +namespace Relational { + char* MallocCString(const std::string& origin); + + struct StoreConfig { + char* name; + int32_t securityLevel; + bool encrypt; + char* dataGroupId; + char* customDir; + bool isSearchable; + bool autoCleanDirtyData; + }; + + struct Asset { + const char* name; + const char* uri; + const char* path; + const char* createTime; + const char* modifyTime; + const char* size; + int32_t status; + }; + + struct Assets { + Asset* head; + int64_t size; + }; + + struct CArrUI8 { + uint8_t* head; + int64_t size; + }; + + struct CArrStr { + char** head; + int64_t size; + }; + + struct ValueType { + int64_t integer; + double dou; + char* string; + bool boolean; + CArrUI8 Uint8Array; + Asset asset; + Assets assets; + uint8_t tag; + }; + + enum TagType { + TYPE_NULL, TYPE_INT, TYPE_DOU, TYPE_STR, TYPE_BOOL, TYPE_BLOB, TYPE_ASSET, TYPE_ASSETS + }; + + struct ValuesBucket { + char** key; + ValueType* value; + int64_t size; + }; + + NativeRdb::ValueObject ValueTypeToValueObject(const ValueType& value); + + struct CArrInt32 { + int32_t* head; + int64_t size; + }; + + struct CArrSyncResult { + char** str; + int32_t* num; + int64_t size; + }; + + ValueType ValueObjectToValueType(const NativeRdb::ValueObject& object); +} +} +#endif \ No newline at end of file diff --git a/relational_store/frameworks/cj/mock/relational_store_mock.cpp b/relational_store/frameworks/cj/mock/relational_store_mock.cpp new file mode 100644 index 00000000..1bd86155 --- /dev/null +++ b/relational_store/frameworks/cj/mock/relational_store_mock.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cj_common_ffi.h" + +extern "C" { +FFI_EXPORT int FfiOHOSRelationalStoreGetRdbStore = 0; +FFI_EXPORT int FfiOHOSRelationalStoreDeleteRdbStore = 0; +FFI_EXPORT int FfiOHOSRelationalStoreDeleteRdbStoreConfig = 0; +FFI_EXPORT int FfiOHOSRelationalStoreRdbPredicatesConstructor = 0; +FFI_EXPORT int FfiOHOSRelationalStoreInDevices = 0; +FFI_EXPORT int FfiOHOSRelationalStoreGetAllColumnNames = 0; +FFI_EXPORT int FfiOHOSRelationalStoreGetColumnCount = 0; +FFI_EXPORT int FfiOHOSRelationalStoreGetRowCount = 0; +FFI_EXPORT int FfiOHOSRelationalStoreGetRowIndex = 0; +FFI_EXPORT int FfiOHOSRelationalStoreIsAtFirstRow = 0; +FFI_EXPORT int FfiOHOSRelationalStoreIsAtLastRow = 0; +FFI_EXPORT int FfiOHOSRelationalStoreIsEnded = 0; +FFI_EXPORT int FfiOHOSRelationalStoreIsStarted = 0; +FFI_EXPORT int FfiOHOSRelationalStoreIsClosed = 0; +FFI_EXPORT int FfiOHOSRelationalStoreInAllDevices = 0; +FFI_EXPORT int FfiOHOSRelationalStoreBeginWrap = 0; +FFI_EXPORT int FfiOHOSRelationalStoreEndWrap = 0; +FFI_EXPORT int FfiOHOSRelationalStoreOr = 0; +FFI_EXPORT int FfiOHOSRelationalStoreAnd = 0; +FFI_EXPORT int FfiOHOSRelationalStoreContains = 0; +FFI_EXPORT int FfiOHOSRelationalStoreBeginsWith = 0; +FFI_EXPORT int FfiOHOSRelationalStoreEndsWith = 0; +FFI_EXPORT int FfiOHOSRelationalStoreIsNull = 0; +FFI_EXPORT int FfiOHOSRelationalStoreIsNotNull = 0; +FFI_EXPORT int FfiOHOSRelationalStoreLike = 0; +FFI_EXPORT int FfiOHOSRelationalStoreGlob = 0; +FFI_EXPORT int FfiOHOSRelationalStoreOrderByAsc = 0; +FFI_EXPORT int FfiOHOSRelationalStoreOrderByDesc = 0; +FFI_EXPORT int FfiOHOSRelationalStoreDistinct = 0; +FFI_EXPORT int FfiOHOSRelationalStoreLimitAs = 0; +FFI_EXPORT int FfiOHOSRelationalStoreOffsetAs = 0; +FFI_EXPORT int FfiOHOSRelationalStoreGroupBy = 0; +FFI_EXPORT int FfiOHOSRelationalStoreIndexedBy = 0; +FFI_EXPORT int FfiOHOSRelationalStoreLessThanOrEqualTo = 0; +FFI_EXPORT int FfiOHOSRelationalStoreEqualTo = 0; +FFI_EXPORT int FfiOHOSRelationalStoreGreaterThanOrEqualTo = 0; +FFI_EXPORT int FfiOHOSRelationalStoreGreaterThan = 0; +FFI_EXPORT int FfiOHOSRelationalStoreNotBetween = 0; +FFI_EXPORT int FfiOHOSRelationalStoreLessThan = 0; +FFI_EXPORT int FfiOHOSRelationalStoreBetween = 0; +FFI_EXPORT int FfiOHOSRelationalStoreIn = 0; +FFI_EXPORT int FfiOHOSRelationalStoreNotIn = 0; +FFI_EXPORT int FfiOHOSRelationalStoreNotEqualTo = 0; +FFI_EXPORT int FfiOHOSRelationalStoreQuery = 0; +FFI_EXPORT int FfiOHOSRelationalStoreRemoteQuery = 0; +FFI_EXPORT int FfiOHOSRelationalStoreUpdate = 0; +FFI_EXPORT int FfiOHOSRelationalStoreDelete = 0; +FFI_EXPORT int FfiOHOSRelationalStoreSetDistributedTables = 0; +FFI_EXPORT int FfiOHOSRelationalStoreSetDistributedTablesType = 0; +FFI_EXPORT int FfiOHOSRelationalStoreSetDistributedTablesConfig = 0; +FFI_EXPORT int FfiOHOSRelationalStoreObtainDistributedTableName = 0; +FFI_EXPORT int FfiOHOSRelationalStoreRollBack = 0; +FFI_EXPORT int FfiOHOSRelationalStoreCommit = 0; +FFI_EXPORT int FfiOHOSRelationalStoreBeginTransaction = 0; +FFI_EXPORT int FfiOHOSRelationalStoreBackUp = 0; +FFI_EXPORT int FfiOHOSRelationalStoreReStore = 0; +FFI_EXPORT int FfiOHOSRelationalStoreInsert = 0; +FFI_EXPORT int FfiOHOSRelationalStoreExecuteSql = 0; +FFI_EXPORT int FfiOHOSRelationalStoreSync = 0; +FFI_EXPORT int FfiOHOSRelationalStoreGetDouble = 0; +FFI_EXPORT int FfiOHOSRelationalStoreGoToRow = 0; +FFI_EXPORT int FfiOHOSRelationalStoreGoToPreviousRow = 0; +FFI_EXPORT int FfiOHOSRelationalStoreGoToLastRow = 0; +FFI_EXPORT int FfiOHOSRelationalStoreGetColumnName = 0; +FFI_EXPORT int FfiOHOSRelationalStoreIsColumnNull = 0; +FFI_EXPORT int FfiOHOSRelationalStoreGetAsset = 0; +FFI_EXPORT int FfiOHOSRelationalStoreClose = 0; +FFI_EXPORT int FfiOHOSRelationalStoreGetColumnIndex = 0; +FFI_EXPORT int FfiOHOSRelationalStoreGetString = 0; +FFI_EXPORT int FfiOHOSRelationalStoreGoToFirstRow = 0; +FFI_EXPORT int FfiOHOSRelationalStoreGetLong = 0; +FFI_EXPORT int FfiOHOSRelationalStoreGoToNextRow = 0; +FFI_EXPORT int FfiOHOSRelationalStoreGetBlob = 0; +FFI_EXPORT int FfiOHOSRelationalStoreGoTo = 0; +FFI_EXPORT int FfiOHOSRelationalStoreGetAssets = 0; +FFI_EXPORT int FfiOHOSRelationalStoreCleanDirtyData = 0; +FFI_EXPORT int FfiOHOSRelationalStoreBatchInsert = 0; +FFI_EXPORT int FfiOHOSRelationalStoreQuerySql = 0; +FFI_EXPORT int FfiOHOSRelationalStoreExecuteSqlBindArgs = 0; +FFI_EXPORT int FfiOHOSRelationalStoreGetRow = 0; +FFI_EXPORT int FfiOHOSRelationalStoreOn = 0; +FFI_EXPORT int FfiOHOSRelationalStoreOff = 0; +FFI_EXPORT int FfiOHOSRelationalStoreOffAll = 0; +FFI_EXPORT int FfiOHOSRelationalStoreEmit = 0; +} \ No newline at end of file diff --git a/relational_store/frameworks/cj/src/relational_store_ffi.cpp b/relational_store/frameworks/cj/src/relational_store_ffi.cpp new file mode 100644 index 00000000..58af1b9c --- /dev/null +++ b/relational_store/frameworks/cj/src/relational_store_ffi.cpp @@ -0,0 +1,904 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "relational_store_ffi.h" +#include "relational_store_utils.h" +#include "napi_rdb_js_utils.h" +#include "rdb_errno.h" +#include "cj_lambda.h" +#include +#include + +using namespace OHOS::FFI; + +namespace OHOS { +namespace Relational { +extern "C" { + int64_t FfiOHOSRelationalStoreGetRdbStore(OHOS::AbilityRuntime::Context* context, StoreConfig config, + int32_t *errCode) + { + return GetRdbStore(context, config, errCode); + } + + void FfiOHOSRelationalStoreDeleteRdbStore(OHOS::AbilityRuntime::Context* context, const char* name, + int32_t *errCode) + { + DeleteRdbStore(context, name, errCode); + } + + void FfiOHOSRelationalStoreDeleteRdbStoreConfig(OHOS::AbilityRuntime::Context* context, StoreConfig config, + int32_t *errCode) + { + DeleteRdbStoreConfig(context, config, errCode); + } + + int64_t FfiOHOSRelationalStoreRdbPredicatesConstructor(const char* tableName) + { + auto nativeRdbPredicates = FFIData::Create(tableName); + if (nativeRdbPredicates == nullptr) { + return -1; + } + return nativeRdbPredicates->GetID(); + } + + int32_t FfiOHOSRelationalStoreInDevices(int64_t id, const char** devicesArray, int64_t devicesSize) + { + auto nativeRdbPredicates = FFIData::GetData(id); + if (nativeRdbPredicates == nullptr) { + return -1; + } + nativeRdbPredicates->InDevices(devicesArray, devicesSize); + return 0; + } + + int32_t FfiOHOSRelationalStoreInAllDevices(int64_t id) + { + auto nativeRdbPredicates = FFIData::GetData(id); + if (nativeRdbPredicates == nullptr) { + return -1; + } + nativeRdbPredicates->InAllDevices(); + return 0; + } + + int32_t FfiOHOSRelationalStoreBeginWrap(int64_t id) + { + auto nativeRdbPredicates = FFIData::GetData(id); + if (nativeRdbPredicates == nullptr) { + return -1; + } + nativeRdbPredicates->BeginWrap(); + return 0; + } + + int32_t FfiOHOSRelationalStoreEndWrap(int64_t id) + { + auto nativeRdbPredicates = FFIData::GetData(id); + if (nativeRdbPredicates == nullptr) { + return -1; + } + nativeRdbPredicates->EndWrap(); + return 0; + } + + int32_t FfiOHOSRelationalStoreOr(int64_t id) + { + auto nativeRdbPredicates = FFIData::GetData(id); + if (nativeRdbPredicates == nullptr) { + return -1; + } + nativeRdbPredicates->Or(); + return 0; + } + + int32_t FfiOHOSRelationalStoreAnd(int64_t id) + { + auto nativeRdbPredicates = FFIData::GetData(id); + if (nativeRdbPredicates == nullptr) { + return -1; + } + nativeRdbPredicates->And(); + return 0; + } + + int32_t FfiOHOSRelationalStoreContains(int64_t id, const char* field, const char* value) + { + auto nativeRdbPredicates = FFIData::GetData(id); + if (nativeRdbPredicates == nullptr) { + return -1; + } + nativeRdbPredicates->Contains(field, value); + return 0; + } + + int32_t FfiOHOSRelationalStoreBeginsWith(int64_t id, const char* field, const char* value) + { + auto nativeRdbPredicates = FFIData::GetData(id); + if (nativeRdbPredicates == nullptr) { + return -1; + } + nativeRdbPredicates->BeginsWith(field, value); + return 0; + } + + int32_t FfiOHOSRelationalStoreEndsWith(int64_t id, const char* field, const char* value) + { + auto nativeRdbPredicates = FFIData::GetData(id); + if (nativeRdbPredicates == nullptr) { + return -1; + } + nativeRdbPredicates->EndsWith(field, value); + return 0; + } + + int32_t FfiOHOSRelationalStoreIsNull(int64_t id, const char* field) + { + auto nativeRdbPredicates = FFIData::GetData(id); + if (nativeRdbPredicates == nullptr) { + return -1; + } + nativeRdbPredicates->IsNull(field); + return 0; + } + + int32_t FfiOHOSRelationalStoreIsNotNull(int64_t id, const char* field) + { + auto nativeRdbPredicates = FFIData::GetData(id); + if (nativeRdbPredicates == nullptr) { + return -1; + } + nativeRdbPredicates->IsNotNull(field); + return 0; + } + + int32_t FfiOHOSRelationalStoreLike(int64_t id, const char* field, const char* value) + { + auto nativeRdbPredicates = FFIData::GetData(id); + if (nativeRdbPredicates == nullptr) { + return -1; + } + nativeRdbPredicates->Like(field, value); + return 0; + } + + int32_t FfiOHOSRelationalStoreGlob(int64_t id, const char* field, const char* value) + { + auto nativeRdbPredicates = FFIData::GetData(id); + if (nativeRdbPredicates == nullptr) { + return -1; + } + nativeRdbPredicates->Glob(field, value); + return 0; + } + + int32_t FfiOHOSRelationalStoreOrderByAsc(int64_t id, const char* field) + { + auto nativeRdbPredicates = FFIData::GetData(id); + if (nativeRdbPredicates == nullptr) { + return -1; + } + nativeRdbPredicates->OrderByAsc(field); + return 0; + } + + int32_t FfiOHOSRelationalStoreOrderByDesc(int64_t id, const char* field) + { + auto nativeRdbPredicates = FFIData::GetData(id); + if (nativeRdbPredicates == nullptr) { + return -1; + } + nativeRdbPredicates->OrderByDesc(field); + return 0; + } + + int32_t FfiOHOSRelationalStoreDistinct(int64_t id) + { + auto nativeRdbPredicates = FFIData::GetData(id); + if (nativeRdbPredicates == nullptr) { + return -1; + } + nativeRdbPredicates->Distinct(); + return 0; + } + + int32_t FfiOHOSRelationalStoreLimitAs(int64_t id, int32_t value) + { + auto nativeRdbPredicates = FFIData::GetData(id); + if (nativeRdbPredicates == nullptr) { + return -1; + } + nativeRdbPredicates->LimitAs(value); + return 0; + } + + int32_t FfiOHOSRelationalStoreOffsetAs(int64_t id, int32_t rowOffset) + { + auto nativeRdbPredicates = FFIData::GetData(id); + if (nativeRdbPredicates == nullptr) { + return -1; + } + nativeRdbPredicates->OffsetAs(rowOffset); + return 0; + } + + int32_t FfiOHOSRelationalStoreGroupBy(int64_t id, const char** fieldsArray, int64_t fieldsSize) + { + auto nativeRdbPredicates = FFIData::GetData(id); + if (nativeRdbPredicates == nullptr) { + return -1; + } + nativeRdbPredicates->GroupBy(fieldsArray, fieldsSize); + return 0; + } + + int32_t FfiOHOSRelationalStoreIndexedBy(int64_t id, const char* field) + { + auto nativeRdbPredicates = FFIData::GetData(id); + if (nativeRdbPredicates == nullptr) { + return -1; + } + nativeRdbPredicates->IndexedBy(field); + return 0; + } + + int32_t FfiOHOSRelationalStoreLessThanOrEqualTo(int64_t id, const char* field, ValueType value) + { + auto nativeRdbPredicates = FFIData::GetData(id); + if (nativeRdbPredicates == nullptr) { + return -1; + } + nativeRdbPredicates->LessThanOrEqualTo(field, value); + return 0; + } + + int32_t FfiOHOSRelationalStoreEqualTo(int64_t id, const char* field, ValueType value) + { + auto nativeRdbPredicates = FFIData::GetData(id); + if (nativeRdbPredicates == nullptr) { + return -1; + } + nativeRdbPredicates->EqualTo(field, value); + return 0; + } + + + int32_t FfiOHOSRelationalStoreGreaterThanOrEqualTo(int64_t id, const char* field, ValueType value) + { + auto nativeRdbPredicates = FFIData::GetData(id); + if (nativeRdbPredicates == nullptr) { + return -1; + } + nativeRdbPredicates->GreaterThanOrEqualTo(field, value); + return 0; + } + + int32_t FfiOHOSRelationalStoreGreaterThan(int64_t id, const char* field, ValueType value) + { + auto nativeRdbPredicates = FFIData::GetData(id); + if (nativeRdbPredicates == nullptr) { + return -1; + } + nativeRdbPredicates->GreaterThan(field, value); + return 0; + } + + int32_t FfiOHOSRelationalStoreNotBetween(int64_t id, const char* field, ValueType lowValue, ValueType highValue) + { + auto nativeRdbPredicates = FFIData::GetData(id); + if (nativeRdbPredicates == nullptr) { + return -1; + } + nativeRdbPredicates->NotBetween(field, lowValue, highValue); + return 0; + } + + int32_t FfiOHOSRelationalStoreLessThan(int64_t id, const char* field, ValueType value) + { + auto nativeRdbPredicates = FFIData::GetData(id); + if (nativeRdbPredicates == nullptr) { + return -1; + } + nativeRdbPredicates->LessThan(field, value); + return 0; + } + + int32_t FfiOHOSRelationalStoreBetween(int64_t id, const char* field, ValueType lowValue, ValueType highValue) + { + auto nativeRdbPredicates = FFIData::GetData(id); + if (nativeRdbPredicates == nullptr) { + return -1; + } + nativeRdbPredicates->Between(field, lowValue, highValue); + return 0; + } + + int32_t FfiOHOSRelationalStoreIn(int64_t id, const char* field, ValueType* values, int64_t valuesSize) + { + auto nativeRdbPredicates = FFIData::GetData(id); + if (nativeRdbPredicates == nullptr) { + return -1; + } + nativeRdbPredicates->In(field, values, valuesSize); + return 0; + } + + int32_t FfiOHOSRelationalStoreNotIn(int64_t id, const char* field, ValueType* values, int64_t valuesSize) + { + auto nativeRdbPredicates = FFIData::GetData(id); + if (nativeRdbPredicates == nullptr) { + return -1; + } + nativeRdbPredicates->NotIn(field, values, valuesSize); + return 0; + } + + int32_t FfiOHOSRelationalStoreNotEqualTo(int64_t id, const char* field, ValueType value) + { + auto nativeRdbPredicates = FFIData::GetData(id); + if (nativeRdbPredicates == nullptr) { + return -1; + } + nativeRdbPredicates->NotEqualTo(field, value); + return 0; + } + + int64_t FfiOHOSRelationalStoreQuery(int64_t id, int64_t predicatesId, char** columns, int64_t columnsSize, + int32_t *errCode) + { + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + *errCode = -1; + return -1; + } + auto nativeRdbPredicates = FFIData::GetData(predicatesId); + if (nativeRdbPredicates == nullptr) { + *errCode = -1; + return -1; + } + auto resultSet = nativeRdbStore->Query(*nativeRdbPredicates, columns, columnsSize); + if (resultSet == nullptr) { + *errCode = RelationalStoreJsKit::E_INNER_ERROR; + return -1; + } else { + *errCode = RelationalStoreJsKit::OK; + } + auto nativeResultSet = FFIData::Create(resultSet); + if (nativeResultSet == nullptr) { + *errCode = -1; + return -1; + } + return nativeResultSet->GetID(); + } + + int64_t FfiOHOSRelationalStoreRemoteQuery(int64_t id, char* device, int64_t predicatesId, char** columns, + int64_t columnsSize) + { + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + return -1; + } + auto nativeRdbPredicates = FFIData::GetData(predicatesId); + if (nativeRdbPredicates == nullptr) { + return -1; + } + auto resultSet = nativeRdbStore->RemoteQuery(device, *nativeRdbPredicates, columns, columnsSize); + if (resultSet == nullptr) { + return -1; + } + auto nativeResultSet = FFIData::Create(resultSet); + if (nativeResultSet == nullptr) { + return -1; + } + return nativeResultSet->GetID(); + } + + int64_t FfiOHOSRelationalStoreDelete(int64_t id, int64_t predicatesId, int32_t *errCode) + { + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + *errCode = -1; + return -1; + } + auto nativeRdbPredicates = FFIData::GetData(predicatesId); + if (nativeRdbPredicates == nullptr) { + *errCode = -1; + return -1; + } + return nativeRdbStore->Delete(*nativeRdbPredicates, errCode); + } + + int32_t FfiOHOSRelationalStoreSetDistributedTables(int64_t id, char** tables, int64_t tablesSize) + { + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + return -1; + } + nativeRdbStore->SetDistributedTables(tables, tablesSize); + return 0; + } + + int32_t FfiOHOSRelationalStoreSetDistributedTablesType(int64_t id, char** tables, int64_t tablesSize, int32_t type) + { + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + return -1; + } + nativeRdbStore->SetDistributedTables(tables, tablesSize, type); + return 0; + } + + int32_t FfiOHOSRelationalStoreSetDistributedTablesConfig(int64_t id, char** tables, int64_t tablesSize, + int32_t type, DistributedRdb::DistributedConfig &distributedConfig) + { + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + return -1; + } + nativeRdbStore->SetDistributedTables(tables, tablesSize, type, distributedConfig); + return 0; + } + + char* FfiOHOSRelationalStoreObtainDistributedTableName(int64_t id, const char* device, char* table) + { + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + return nullptr; + } + return nativeRdbStore->ObtainDistributedTableName(device, table); + } + + int32_t FfiOHOSRelationalStoreBackUp(int64_t id, const char* destName) + { + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + return -1; + } + return nativeRdbStore->Backup(destName); + } + + int32_t FfiOHOSRelationalStoreReStore(int64_t id, const char* srcName) + { + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + return -1; + } + return nativeRdbStore->Restore(srcName); + } + + int32_t FfiOHOSRelationalStoreCommit(int64_t id) + { + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + return -1; + } + return nativeRdbStore->Commit(); + } + + int32_t FfiOHOSRelationalStoreRollBack(int64_t id) + { + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + return -1; + } + return nativeRdbStore->RollBack(); + } + + int32_t FfiOHOSRelationalStoreBeginTransaction(int64_t id) + { + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + return -1; + } + return nativeRdbStore->BeginTransaction(); + } + + int64_t FfiOHOSRelationalStoreInsert(int64_t id, const char* table, ValuesBucket valuesBucket, int32_t conflict, + int32_t *errCode) + { + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + *errCode = -1; + return -1; + } + return nativeRdbStore->Insert(table, valuesBucket, conflict, errCode); + } + + int64_t FfiOHOSRelationalStoreUpdate(int64_t id, ValuesBucket valuesBucket, int64_t predicatesId, + NativeRdb::ConflictResolution conflictResolution, int32_t *errCode) + { + auto nativeRdbStore = FFIData::GetData(id); + auto nativeRdbSPredicates = FFIData::GetData(predicatesId); + if (nativeRdbStore == nullptr || nativeRdbSPredicates == nullptr) { + *errCode = -1; + return -1; + } + return nativeRdbStore->Update(valuesBucket, *nativeRdbSPredicates, conflictResolution, errCode); + } + + void FfiOHOSRelationalStoreExecuteSql(int64_t id, const char* sql, int32_t *errCode) + { + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + *errCode = -1; + return; + } + nativeRdbStore->ExecuteSql(sql, errCode); + } + + CArrSyncResult FfiOHOSRelationalStoreSync(int64_t id, int32_t mode, int64_t predicatesId, int32_t *errCode) + { + auto nativeRdbStore = FFIData::GetData(id); + auto nativeRdbPredicates = FFIData::GetData(predicatesId); + if (nativeRdbStore == nullptr || nativeRdbPredicates == nullptr) { + *errCode = -1; + return CArrSyncResult{nullptr, nullptr, 0}; + } + return nativeRdbStore->Sync(mode, *nativeRdbPredicates); + } + + CArrStr FfiOHOSRelationalStoreGetAllColumnNames(int64_t id) + { + auto nativeResultSet = FFIData::GetData(id); + if (nativeResultSet == nullptr) { + return CArrStr{nullptr, 0}; + } + return nativeResultSet->GetAllColumnNames(); + } + + int32_t FfiOHOSRelationalStoreGetColumnCount(int64_t id) + { + auto nativeResultSet = FFIData::GetData(id); + if (nativeResultSet == nullptr) { + return -1; + } + return nativeResultSet->GetColumnCount(); + } + + int32_t FfiOHOSRelationalStoreGetRowCount(int64_t id) + { + auto nativeResultSet = FFIData::GetData(id); + if (nativeResultSet == nullptr) { + return -1; + } + return nativeResultSet->GetRowCount(); + } + + int32_t FfiOHOSRelationalStoreGetRowIndex(int64_t id) + { + auto nativeResultSet = FFIData::GetData(id); + if (nativeResultSet == nullptr) { + return -1; + } + return nativeResultSet->GetRowIndex(); + } + + bool FfiOHOSRelationalStoreIsAtFirstRow(int64_t id, int32_t *errCode) + { + auto nativeResultSet = FFIData::GetData(id); + if (nativeResultSet == nullptr) { + *errCode = -1; + return false; + } + *errCode = 0; + return nativeResultSet->IsAtFirstRow(); + } + + bool FfiOHOSRelationalStoreIsAtLastRow(int64_t id, int32_t *errCode) + { + auto nativeResultSet = FFIData::GetData(id); + if (nativeResultSet == nullptr) { + *errCode = -1; + return false; + } + *errCode = 0; + return nativeResultSet->IsAtLastRow(); + } + + bool FfiOHOSRelationalStoreIsEnded(int64_t id, int32_t *errCode) + { + auto nativeResultSet = FFIData::GetData(id); + if (nativeResultSet == nullptr) { + *errCode = -1; + return false; + } + *errCode = 0; + return nativeResultSet->IsEnded(); + } + + bool FfiOHOSRelationalStoreIsStarted(int64_t id, int32_t *errCode) + { + auto nativeResultSet = FFIData::GetData(id); + if (nativeResultSet == nullptr) { + *errCode = -1; + return false; + } + *errCode = 0; + return nativeResultSet->IsStarted(); + } + + bool FfiOHOSRelationalStoreIsClosed(int64_t id, int32_t *errCode) + { + auto nativeResultSet = FFIData::GetData(id); + if (nativeResultSet == nullptr) { + *errCode = -1; + return false; + } + *errCode = 0; + return nativeResultSet->IsClosed(); + } + + + double FfiOHOSRelationalStoreGetDouble(int64_t id, int32_t columnIndex, int32_t* rtnCode) + { + auto nativeResultSet = FFIData::GetData(id); + if (nativeResultSet == nullptr) { + *rtnCode = -1; + return -1; + } + return nativeResultSet->GetDouble(columnIndex, rtnCode); + } + + bool FfiOHOSRelationalStoreGoToRow(int64_t id, int32_t position, int32_t* rtnCode) + { + auto nativeResultSet = FFIData::GetData(id); + if (nativeResultSet == nullptr) { + *rtnCode = -1; + return false; + } + return nativeResultSet->GoToRow(position, rtnCode); + } + + bool FfiOHOSRelationalStoreGoToPreviousRow(int64_t id, int32_t* rtnCode) + { + auto nativeResultSet = FFIData::GetData(id); + if (nativeResultSet == nullptr) { + *rtnCode = -1; + return false; + } + return nativeResultSet->GoToPreviousRow(rtnCode); + } + + bool FfiOHOSRelationalStoreGoToLastRow(int64_t id, int32_t* rtnCode) + { + auto nativeResultSet = FFIData::GetData(id); + if (nativeResultSet == nullptr) { + *rtnCode = -1; + return false; + } + return nativeResultSet->GoToLastRow(rtnCode); + } + + char* FfiOHOSRelationalStoreGetColumnName(int64_t id, int32_t columnIndex, int32_t* rtnCode) + { + auto nativeResultSet = FFIData::GetData(id); + if (nativeResultSet == nullptr) { + *rtnCode = -1; + return nullptr; + } + return nativeResultSet->GetColumnName(columnIndex, rtnCode); + } + + bool FfiOHOSRelationalStoreIsColumnNull(int64_t id, int32_t columnIndex, int32_t* rtnCode) + { + auto nativeResultSet = FFIData::GetData(id); + if (nativeResultSet == nullptr) { + *rtnCode = -1; + return false; + } + return nativeResultSet->IsColumnNull(columnIndex, rtnCode); + } + + Asset FfiOHOSRelationalStoreGetAsset(int64_t id, int32_t columnIndex, int32_t* rtnCode) + { + auto nativeResultSet = FFIData::GetData(id); + if (nativeResultSet == nullptr) { + *rtnCode = -1; + return Asset{nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, 0}; + } + return nativeResultSet->GetAsset(columnIndex, rtnCode); + } + + int32_t FfiOHOSRelationalStoreClose(int64_t id) + { + auto nativeResultSet = FFIData::GetData(id); + if (nativeResultSet == nullptr) { + return -1; + } + return nativeResultSet->Close(); + } + + int32_t FfiOHOSRelationalStoreGetColumnIndex(int64_t id, char* columnName, int32_t* rtnCode) + { + auto nativeResultSet = FFIData::GetData(id); + if (nativeResultSet == nullptr) { + *rtnCode = -1; + return -1; + } + return nativeResultSet->GetColumnIndex(columnName, rtnCode); + } + + char* FfiOHOSRelationalStoreGetString(int64_t id, int32_t columnIndex, int32_t* rtnCode) + { + auto nativeResultSet = FFIData::GetData(id); + if (nativeResultSet == nullptr) { + *rtnCode = -1; + return nullptr; + } + return nativeResultSet->GetString(columnIndex, rtnCode); + } + + bool FfiOHOSRelationalStoreGoToFirstRow(int64_t id, int32_t* rtnCode) + { + auto nativeResultSet = FFIData::GetData(id); + if (nativeResultSet == nullptr) { + *rtnCode = -1; + return false; + } + return nativeResultSet->GoToFirstRow(rtnCode); + } + + int64_t FfiOHOSRelationalStoreGetLong(int64_t id, int32_t columnIndex, int32_t* rtnCode) + { + auto nativeResultSet = FFIData::GetData(id); + if (nativeResultSet == nullptr) { + *rtnCode = -1; + return -1; + } + return nativeResultSet->GetLong(columnIndex, rtnCode); + } + + bool FfiOHOSRelationalStoreGoToNextRow(int64_t id, int32_t* rtnCode) + { + auto nativeResultSet = FFIData::GetData(id); + if (nativeResultSet == nullptr) { + *rtnCode = -1; + return false; + } + return nativeResultSet->GoToNextRow(rtnCode); + } + + CArrUI8 FfiOHOSRelationalStoreGetBlob(int64_t id, int32_t columnIndex, int32_t* rtnCode) + { + auto nativeResultSet = FFIData::GetData(id); + if (nativeResultSet == nullptr) { + *rtnCode = -1; + return CArrUI8{nullptr, 0}; + } + return nativeResultSet->GetBlob(columnIndex, rtnCode); + } + + bool FfiOHOSRelationalStoreGoTo(int64_t id, int32_t offset, int32_t* rtnCode) + { + auto nativeResultSet = FFIData::GetData(id); + if (nativeResultSet == nullptr) { + *rtnCode = -1; + return false; + } + return nativeResultSet->GoTo(offset, rtnCode); + } + + Assets FfiOHOSRelationalStoreGetAssets(int64_t id, int32_t columnIndex, int32_t* rtnCode) + { + auto nativeResultSet = FFIData::GetData(id); + if (nativeResultSet == nullptr) { + *rtnCode = -1; + return Assets{nullptr, 0}; + } + return nativeResultSet->GetAssets(columnIndex, rtnCode); + } + + ValuesBucket FfiOHOSRelationalStoreGetRow(int64_t id, int32_t *errCode) + { + auto nativeResultSet = FFIData::GetData(id); + if (nativeResultSet == nullptr) { + *errCode = -1; + return ValuesBucket{nullptr, nullptr, 0}; + } + return nativeResultSet->GetRow(errCode); + } + + int32_t FfiOHOSRelationalStoreCleanDirtyData(int64_t id, const char* tableName, uint64_t cursor) + { + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + return -1; + } + return nativeRdbStore->CleanDirtyData(tableName, cursor); + } + + int32_t FfiOHOSRelationalStoreBatchInsert(int64_t id, const char* tableName, ValuesBucket* values, + int64_t valuesSize, int64_t* insertNum) + { + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + return -1; + } + return nativeRdbStore->BatchInsert(*insertNum, tableName, values, valuesSize); + } + + int64_t FfiOHOSRelationalStoreQuerySql(int64_t id, const char *sql, ValueType *bindArgs, int64_t size, + int32_t* errCode) + { + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + *errCode = RelationalStoreJsKit::E_INNER_ERROR; + return -1; + } + auto resultSet = nativeRdbStore->QuerySql(sql, bindArgs, size); + if (resultSet == nullptr) { + *errCode = RelationalStoreJsKit::E_INNER_ERROR; + return -1; + } else { + *errCode = RelationalStoreJsKit::OK; + } + auto nativeResultSet = FFIData::Create(resultSet); + if (nativeResultSet == nullptr) { + *errCode = -1; + return -1; + } + return nativeResultSet->GetID(); + } + + void FfiOHOSRelationalStoreExecuteSqlBindArgs(int64_t id, char* sql, ValueType* bindArgs, int64_t bindArgsSize, + int32_t *errCode) + { + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + *errCode = -1; + return; + } + nativeRdbStore->ExecuteSql(sql, bindArgs, bindArgsSize, errCode); + } + + int32_t FfiOHOSRelationalStoreOn(int64_t id, const char *event, bool interProcess, + void (*callback)(), void (*callbackRef)()) + { + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + return -1; + } + auto onChange = [lambda = CJLambda::Create(callbackRef)]() -> void { lambda(); }; + return nativeRdbStore->RegisterObserver(event, interProcess, (std::function*)(callback), onChange); + } + + int32_t FfiOHOSRelationalStoreOff(int64_t id, const char *event, bool interProcess, void (*callback)()) + { + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + return -1; + } + return nativeRdbStore->UnRegisterObserver(event, interProcess, (std::function*)(callback)); + } + + int32_t FfiOHOSRelationalStoreOffAll(int64_t id, const char *event, bool interProcess) + { + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + return -1; + } + return nativeRdbStore->UnRegisterAllObserver(event, interProcess); + } + + int32_t FfiOHOSRelationalStoreEmit(int64_t id, const char *event) + { + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + return -1; + } + return nativeRdbStore->Emit(event); + } +} +} +} diff --git a/relational_store/frameworks/cj/src/relational_store_impl_rdbpredicatesproxy.cpp b/relational_store/frameworks/cj/src/relational_store_impl_rdbpredicatesproxy.cpp new file mode 100644 index 00000000..eefe118d --- /dev/null +++ b/relational_store/frameworks/cj/src/relational_store_impl_rdbpredicatesproxy.cpp @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "relational_store_impl_rdbpredicatesproxy.h" +#include "relational_store_utils.h" + +namespace OHOS { +namespace Relational { + RdbPredicatesImpl::RdbPredicatesImpl(const char* tableName) + { + std::string str = tableName; + predicates_ = std::make_shared(str); + } + + RdbPredicatesImpl::RdbPredicatesImpl(std::shared_ptr predicates) + { + predicates_ = predicates; + } + + OHOS::FFI::RuntimeType* RdbPredicatesImpl::GetClassType() + { + static OHOS::FFI::RuntimeType runtimeType = + OHOS::FFI::RuntimeType::Create("RdbPredicatesImpl"); + return &runtimeType; + } + + std::shared_ptr RdbPredicatesImpl::GetPredicates() + { + return predicates_; + } + + void RdbPredicatesImpl::InDevices(const char** devicesArray, int64_t devicesSize) + { + std::vector devices; + for (int64_t i = 0; i < devicesSize; i++) { + devices.push_back(devicesArray[i]); + } + predicates_->InDevices(devices); + } + + void RdbPredicatesImpl::InAllDevices() + { + predicates_->InAllDevices(); + } + + void RdbPredicatesImpl::BeginWrap() + { + predicates_->BeginWrap(); + } + + void RdbPredicatesImpl::EndWrap() + { + predicates_->EndWrap(); + } + + void RdbPredicatesImpl::Or() + { + predicates_->Or(); + } + + void RdbPredicatesImpl::And() + { + predicates_->And(); + } + + void RdbPredicatesImpl::Contains(const char* field, const char* value) + { + std::string cfield = field; + std::string cvalue = value; + predicates_->Contains(cfield, cvalue); + } + + void RdbPredicatesImpl::BeginsWith(const char* field, const char* value) + { + std::string cfield = field; + std::string cvalue = value; + predicates_->BeginsWith(cfield, cvalue); + } + + void RdbPredicatesImpl::EndsWith(const char* field, const char* value) + { + std::string cfield = field; + std::string cvalue = value; + predicates_->EndsWith(cfield, cvalue); + } + + void RdbPredicatesImpl::IsNull(const char* field) + { + std::string cfield = field; + predicates_->IsNull(cfield); + } + + void RdbPredicatesImpl::IsNotNull(const char* field) + { + std::string cfield = field; + predicates_->IsNotNull(cfield); + } + + void RdbPredicatesImpl::Like(const char* field, const char* value) + { + std::string cfield = field; + std::string cvalue = value; + predicates_->Like(cfield, cvalue); + } + + void RdbPredicatesImpl::Glob(const char* field, const char* value) + { + std::string cfield = field; + std::string cvalue = value; + predicates_->Glob(cfield, cvalue); + } + + void RdbPredicatesImpl::OrderByAsc(const char* field) + { + std::string cfield = field; + predicates_->OrderByAsc(cfield); + } + + void RdbPredicatesImpl::OrderByDesc(const char* field) + { + std::string cfield = field; + predicates_->OrderByDesc(cfield); + } + + void RdbPredicatesImpl::Distinct() + { + predicates_->Distinct(); + } + + void RdbPredicatesImpl::LimitAs(int32_t value) + { + predicates_->Limit(value); + } + + void RdbPredicatesImpl::OffsetAs(int32_t rowOffset) + { + predicates_->Offset(rowOffset); + } + + void RdbPredicatesImpl::GroupBy(const char** fieldsArray, int64_t fieldsSize) + { + std::vector fields; + for (int64_t i = 0; i < fieldsSize; i++) { + fields.push_back(fieldsArray[i]); + } + predicates_->GroupBy(fields); + } + + void RdbPredicatesImpl::IndexedBy(const char* field) + { + std::string cfield = field; + predicates_->IndexedBy(cfield); + } + + void RdbPredicatesImpl::LessThanOrEqualTo(const char* field, ValueType value) + { + std::string cfield = field; + NativeRdb::ValueObject valueObject = ValueTypeToValueObject(value); + predicates_->LessThanOrEqualTo(cfield, valueObject); + } + + void RdbPredicatesImpl::EqualTo(const char* field, ValueType value) + { + std::string cfield = field; + NativeRdb::ValueObject valueObject = ValueTypeToValueObject(value); + predicates_->EqualTo(cfield, valueObject); + } + + void RdbPredicatesImpl::GreaterThanOrEqualTo(const char* field, ValueType value) + { + std::string cfield = field; + NativeRdb::ValueObject valueObject = ValueTypeToValueObject(value); + predicates_->GreaterThanOrEqualTo(cfield, valueObject); + } + + void RdbPredicatesImpl::GreaterThan(const char* field, ValueType value) + { + std::string cfield = field; + NativeRdb::ValueObject valueObject = ValueTypeToValueObject(value); + predicates_->GreaterThan(cfield, valueObject); + } + + void RdbPredicatesImpl::NotBetween(const char* field, ValueType lowValue, ValueType highValue) + { + std::string cfield = field; + NativeRdb::ValueObject lowValueObject = ValueTypeToValueObject(lowValue); + NativeRdb::ValueObject highValueObject = ValueTypeToValueObject(highValue); + predicates_->NotBetween(cfield, lowValueObject, highValueObject); + } + + void RdbPredicatesImpl::Between(const char* field, ValueType lowValue, ValueType highValue) + { + std::string cfield = field; + NativeRdb::ValueObject lowValueObject = ValueTypeToValueObject(lowValue); + NativeRdb::ValueObject highValueObject = ValueTypeToValueObject(highValue); + predicates_->Between(cfield, lowValueObject, highValueObject); + } + + void RdbPredicatesImpl::LessThan(const char* field, ValueType value) + { + std::string cfield = field; + NativeRdb::ValueObject valueObject = ValueTypeToValueObject(value); + predicates_->LessThan(cfield, valueObject); + } + + void RdbPredicatesImpl::In(const char* field, ValueType* values, int64_t valuesSize) + { + std::string cfield = field; + std::vector valueObjects = std::vector(); + for (int64_t i = 0; i < valuesSize; i++) { + valueObjects.push_back(ValueTypeToValueObject(values[i])); + } + predicates_->In(cfield, valueObjects); + } + + void RdbPredicatesImpl::NotIn(const char* field, ValueType* values, int64_t valuesSize) + { + std::string cfield = field; + std::vector valueObjects = std::vector(); + for (int64_t i = 0; i < valuesSize; i++) { + valueObjects.push_back(ValueTypeToValueObject(values[i])); + } + predicates_->NotIn(cfield, valueObjects); + } + + void RdbPredicatesImpl::NotEqualTo(const char* field, ValueType value) + { + std::string cfield = field; + NativeRdb::ValueObject valueObject = ValueTypeToValueObject(value); + predicates_->NotEqualTo(cfield, valueObject); + } +} +} \ No newline at end of file diff --git a/relational_store/frameworks/cj/src/relational_store_impl_rdbstore.cpp b/relational_store/frameworks/cj/src/relational_store_impl_rdbstore.cpp new file mode 100644 index 00000000..03040f64 --- /dev/null +++ b/relational_store/frameworks/cj/src/relational_store_impl_rdbstore.cpp @@ -0,0 +1,557 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "relational_store_utils.h" +#include "rdb_open_callback.h" +#include "rdb_store_config.h" +#include "rdb_helper.h" +#include "abs_rdb_predicates.h" +#include "logger.h" +#include "rdb_errno.h" +#include "rdb_open_callback.h" +#include "rdb_sql_utils.h" +#include "rdb_store_config.h" +#include "unistd.h" +#include "js_ability.h" +#include "native_log.h" +#include "value_object.h" +#include "rdb_common.h" +#include "native_log.h" +#include "relational_store_impl_rdbstore.h" + +#ifndef PATH_SPLIT +#define PATH_SPLIT '/' +#endif + +using ContextParam = OHOS::AppDataMgrJsKit::JSUtils::ContextParam; +using RdbConfig = OHOS::AppDataMgrJsKit::JSUtils::RdbConfig; + +using namespace OHOS::FFI; + +namespace OHOS { +namespace Relational { + class DefaultOpenCallback : public NativeRdb::RdbOpenCallback { + public: + int OnCreate(NativeRdb::RdbStore &rdbStore) override + { + return RelationalStoreJsKit::OK; + } + + int OnUpgrade(NativeRdb::RdbStore &rdbStore, int oldVersion, int newVersion) override + { + return RelationalStoreJsKit::OK; + } + }; + + RdbStoreImpl::RdbStoreImpl(std::shared_ptr rdbStore) + { + rdbStore_ = rdbStore; + } + + OHOS::FFI::RuntimeType* RdbStoreImpl::GetClassType() + { + static OHOS::FFI::RuntimeType runtimeType = OHOS::FFI::RuntimeType::Create("RdbStoreImpl"); + return &runtimeType; + } + + NativeRdb::ValuesBucket ConvertFromValueBucket(ValuesBucket valuesBucket) + { + int64_t mapSize = valuesBucket.size; + NativeRdb::ValuesBucket nativeValuesBucket = NativeRdb::ValuesBucket(); + + for (int64_t i = 0; i < mapSize; i++) { + NativeRdb::ValueObject valueObject = ValueTypeToValueObject(valuesBucket.value[i]); + std::string keyStr = valuesBucket.key[i]; + nativeValuesBucket.Put(keyStr, valueObject); + } + return nativeValuesBucket; + } + + std::shared_ptr RdbStoreImpl::Query(RdbPredicatesImpl &predicates, char** column, + int64_t columnSize) + { + std::vector columnsVector = std::vector(); + for (int64_t i = 0; i < columnSize; i++) { + columnsVector.push_back(std::string(column[i])); + } + auto resultSet = rdbStore_->Query(*(predicates.GetPredicates()), columnsVector); + return resultSet; + } + + std::shared_ptr RdbStoreImpl::RemoteQuery(char* device, RdbPredicatesImpl &predicates, + char** column, int64_t columnSize) + { + std::vector columnsVector; + for (int64_t i = 0; i < columnSize; i++) { + columnsVector.push_back(std::string(column[i])); + } + int32_t errCode; + auto resultSet = rdbStore_->RemoteQuery(std::string(device), *(predicates.GetPredicates()), columnsVector, + errCode); + return resultSet; + } + + int32_t RdbStoreImpl::Update(ValuesBucket valuesBucket, RdbPredicatesImpl &predicates, + NativeRdb::ConflictResolution conflictResolution, int32_t *errCode) + { + int32_t affectedRows; + NativeRdb::ValuesBucket nativeValuesBucket = ConvertFromValueBucket(valuesBucket); + *errCode = rdbStore_->UpdateWithConflictResolution(affectedRows, predicates.GetPredicates()->GetTableName(), + nativeValuesBucket, predicates.GetPredicates()->GetWhereClause(), predicates.GetPredicates()->GetBindArgs(), + conflictResolution); + return affectedRows; + } + + int RdbStoreImpl::Delete(RdbPredicatesImpl &predicates, int32_t *errCode) + { + int deletedRows = 0; + *errCode = rdbStore_->Delete(deletedRows, *(predicates.GetPredicates())); + return deletedRows; + } + + void RdbStoreImpl::SetDistributedTables(char** tables, int64_t tablesSize) + { + std::vector tablesVector; + for (int64_t i = 0; i < tablesSize; i++) { + tablesVector.push_back(std::string(tables[i])); + } + rdbStore_->SetDistributedTables(tablesVector); + } + + void RdbStoreImpl::SetDistributedTables(char** tables, int64_t tablesSize, int32_t type) + { + std::vector tablesVector; + for (int64_t i = 0; i < tablesSize; i++) { + tablesVector.push_back(std::string(tables[i])); + } + rdbStore_->SetDistributedTables(tablesVector, type); + } + + void RdbStoreImpl::SetDistributedTables(char** tables, int64_t tablesSize, int32_t type, + DistributedRdb::DistributedConfig &distributedConfig) + { + std::vector tablesVector; + for (int64_t i = 0; i < tablesSize; i++) { + tablesVector.push_back(std::string(tables[i])); + } + rdbStore_->SetDistributedTables(tablesVector, type, distributedConfig); + } + + int32_t RdbStoreImpl::RollBack() + { + return rdbStore_->RollBack(); + } + + int32_t RdbStoreImpl::Commit() + { + return rdbStore_->Commit(); + } + + int32_t RdbStoreImpl::BeginTransaction() + { + return rdbStore_->BeginTransaction(); + } + + int32_t RdbStoreImpl::Backup(const char* destName) + { + return rdbStore_->Backup(destName, newKey); + } + + int32_t RdbStoreImpl::Restore(const char* srcName) + { + return rdbStore_->Restore(srcName, newKey); + } + + char* RdbStoreImpl::ObtainDistributedTableName(const char* device, const char* table) + { + int errCode = RelationalStoreJsKit::E_INNER_ERROR; + std::string tableName = rdbStore_->ObtainDistributedTableName(device, table, errCode); + return MallocCString(tableName); + } + + int32_t RdbStoreImpl::Emit(const char* event) + { + return rdbStore_->Notify(event); + } + + int64_t RdbStoreImpl::Insert(const char* table, ValuesBucket valuesBucket, int32_t conflict, int32_t *errCode) + { + std::string tableName = table; + int64_t result; + NativeRdb::ValuesBucket nativeValuesBucket = ConvertFromValueBucket(valuesBucket); + *errCode = rdbStore_->InsertWithConflictResolution(result, tableName, + nativeValuesBucket, NativeRdb::ConflictResolution(conflict)); + return result; + } + + void RdbStoreImpl::ExecuteSql(const char* sql, int32_t *errCode) + { + *errCode = rdbStore_->ExecuteSql(sql, bindArgs); + } + + + int32_t RdbStoreImpl::CleanDirtyData(const char* tableName, uint64_t cursor) + { + int32_t rtnCode = rdbStore_->CleanDirtyData(tableName, cursor); + return rtnCode; + } + + int32_t RdbStoreImpl::BatchInsert(int64_t &insertNum, const char* tableName, ValuesBucket* valuesBuckets, + int64_t valuesSize) + { + std::vector valuesVector; + std::string tableNameStr = tableName; + for (int64_t i = 0; i < valuesSize; i++) { + NativeRdb::ValuesBucket nativeValuesBucket = ConvertFromValueBucket(valuesBuckets[i]); + valuesVector.push_back(nativeValuesBucket); + } + int32_t rtnCode = rdbStore_->BatchInsert(insertNum, tableNameStr, valuesVector); + return rtnCode; + } + + CArrSyncResult RdbStoreImpl::Sync(int32_t mode, RdbPredicatesImpl &predicates) + { + DistributedRdb::SyncOption option; + option.mode = static_cast(mode); + option.isBlock = true; + DistributedRdb::SyncResult resMap; + rdbStore_->Sync(option, *(predicates.GetPredicates()), + [&resMap](const DistributedRdb::SyncResult &result) { resMap = result; }); + char** resultStr = static_cast(malloc(resMap.size() * sizeof(char*))); + int32_t* resultNum = static_cast(malloc(resMap.size() * sizeof(int32_t))); + if (resultStr == nullptr || resultNum == nullptr) { + free(resultStr); + free(resultNum); + return CArrSyncResult{nullptr, nullptr, -1}; + } + size_t i = 0; + for (auto it = resMap.begin(); it != resMap.end(); ++it) { + resultStr[i] = MallocCString(it->first); + resultNum[i] = it->second; + i++; + } + return CArrSyncResult{resultStr, resultNum, int64_t(resMap.size())}; + } + + std::shared_ptr RdbStoreImpl::QuerySql(const char *sql, ValueType *bindArgs, int64_t size) + { + std::string tmpSql = sql; + std::vector tmpBindArgs = std::vector(); + for (int64_t i = 0; i < size; i++) { + tmpBindArgs.push_back(ValueTypeToValueObject(bindArgs[i])); + } + auto result = rdbStore_->QueryByStep(tmpSql, tmpBindArgs); + return result; + } + + void RdbStoreImpl::ExecuteSql(const char* sql, ValueType* bindArgs, int64_t bindArgsSize, int32_t *errCode) + { + std::vector bindArgsObjects = std::vector(); + for (int64_t i = 0; i < bindArgsSize; i++) { + bindArgsObjects.push_back(ValueTypeToValueObject(bindArgs[i])); + } + *errCode = rdbStore_->ExecuteSql(sql, bindArgsObjects); + } + + int32_t RdbStoreImpl::RegisterObserver(const char *event, bool interProcess, std::function *callback, + const std::function& callbackRef) + { + DistributedRdb::SubscribeOption option; + option.event = event; + interProcess ? option.mode = DistributedRdb::SubscribeMode::LOCAL_SHARED : option.mode = + DistributedRdb::SubscribeMode::LOCAL; + if (option.mode == DistributedRdb::SubscribeMode::LOCAL) { + return RegisteredObserver(option, localObservers_, callback, callbackRef); + } + return RegisteredObserver(option, localSharedObservers_, callback, callbackRef); + } + + bool isSameFunction(const std::function *f1, const std::function *f2) + { + return f1 == f2; + } + + bool RdbStoreImpl::HasRegisteredObserver( + std::function *callback, + std::list> &observers) + { + for (auto &it : observers) { + if (isSameFunction(callback, it->GetCallBack())) { + return true; + } + } + return false; + } + + RdbStoreObserverImpl::RdbStoreObserverImpl(std::function *callback, + const std::function& callbackRef) + { + m_callback = callback; + m_callbackRef = callbackRef; + } + + std::function *RdbStoreObserverImpl::GetCallBack() + { + return m_callback; + } + + int32_t RdbStoreImpl::RegisteredObserver( + DistributedRdb::SubscribeOption option, + std::map>> &observers, + std::function *callback, const std::function& callbackRef) + { + observers.try_emplace(option.event); + if (!HasRegisteredObserver(callback, observers[option.event])) { + auto localObserver = std::make_shared(callback, callbackRef); + int32_t errCode = rdbStore_->Subscribe(option, localObserver.get()); + if (errCode != NativeRdb::E_OK) { + return errCode; + } + observers[option.event].push_back(localObserver); + LOGI("subscribe success event: %{public}s", option.event.c_str()); + } else { + LOGI("duplicate subscribe event: %{public}s", option.event.c_str()); + } + return RelationalStoreJsKit::OK; + } + + void RdbStoreObserverImpl::RdbStoreObserverImpl::OnChange() + { + m_callbackRef(); + } + + int32_t RdbStoreImpl::UnRegisterObserver(const char *event, bool interProcess, std::function *callback) + { + DistributedRdb::SubscribeOption option; + option.event = event; + interProcess ? option.mode = DistributedRdb::SubscribeMode::LOCAL_SHARED : option.mode = + DistributedRdb::SubscribeMode::LOCAL; + if (option.mode == DistributedRdb::SubscribeMode::LOCAL) { + return UnRegisteredObserver(option, localObservers_, callback); + } + return UnRegisteredObserver(option, localSharedObservers_, callback); + } + + int32_t RdbStoreImpl::UnRegisteredObserver(DistributedRdb::SubscribeOption option, std::map>> &observers, std::function *callback) + { + auto obs = observers.find(option.event); + if (obs == observers.end()) { + LOGI("observer not found, event: %{public}s", option.event.c_str()); + return RelationalStoreJsKit::OK; + } + + auto &list = obs->second; + for (auto it = list.begin(); it != list.end(); it++) { + if (isSameFunction(callback, (*it)->GetCallBack())) { + int errCode = rdbStore_->UnSubscribe(option, it->get()); + if (errCode != RelationalStoreJsKit::OK) { + return errCode; + } + list.erase(it); + break; + } + } + if (list.empty()) { + observers.erase(option.event); + } + LOGI("unsubscribe success, event: %{public}s", option.event.c_str()); + return RelationalStoreJsKit::OK; + } + + int32_t RdbStoreImpl::UnRegisterAllObserver(const char *event, bool interProcess) + { + DistributedRdb::SubscribeOption option; + option.event = event; + interProcess ? option.mode = DistributedRdb::SubscribeMode::LOCAL_SHARED : option.mode = + DistributedRdb::SubscribeMode::LOCAL; + if (option.mode == DistributedRdb::SubscribeMode::LOCAL) { + return UnRegisteredAllObserver(option, localObservers_); + } + return UnRegisteredAllObserver(option, localSharedObservers_); + } + + int32_t RdbStoreImpl::UnRegisteredAllObserver(DistributedRdb::SubscribeOption option, std::map>> &observers) + { + auto obs = observers.find(option.event); + if (obs == observers.end()) { + LOGI("observer not found, event: %{public}s", option.event.c_str()); + return RelationalStoreJsKit::OK; + } + + int errCode = rdbStore_->UnSubscribe(option, nullptr); + if (errCode != RelationalStoreJsKit::OK) { + return errCode; + } + observers.erase(option.event); + LOGI("unsubscribe success, event: %{public}s", option.event.c_str()); + return RelationalStoreJsKit::OK; + } + + int32_t GetRealPath(AppDataMgrJsKit::JSUtils::RdbConfig &rdbConfig, + const AppDataMgrJsKit::JSUtils::ContextParam ¶m, + std::shared_ptr abilitycontext) + { + if (rdbConfig.name.find(PATH_SPLIT) != std::string::npos) { + LOGE("Parameter error. The StoreConfig.name must be a file name without path."); + return RelationalStoreJsKit::E_PARAM_ERROR; + } + + if (!rdbConfig.customDir.empty()) { + // determine if the first character of customDir is '/' + if (rdbConfig.customDir.find_first_of(PATH_SPLIT) == 0) { + LOGE("Parameter error. The customDir must be a relative directory."); + return RelationalStoreJsKit::E_PARAM_ERROR; + } + // customDir length is limited to 128 bytes + if (rdbConfig.customDir.length() > 128) { + LOGE("Parameter error. The customDir length must be less than or equal to 128 bytes."); + return RelationalStoreJsKit::E_PARAM_ERROR; + } + } + + std::string baseDir = param.baseDir; + if (!rdbConfig.dataGroupId.empty()) { + if (!param.isStageMode) { + return RelationalStoreJsKit::E_NOT_STAGE_MODE; + } + std::string groupDir; + int errCode = abilitycontext->GetSystemDatabaseDir(rdbConfig.dataGroupId, groupDir); + if (errCode != NativeRdb::E_OK && groupDir.empty()) { + return RelationalStoreJsKit::E_DATA_GROUP_ID_INVALID; + } + baseDir = groupDir; + } + + auto [realPath, errorCode] = + NativeRdb::RdbSqlUtils::GetDefaultDatabasePath(baseDir, rdbConfig.name, rdbConfig.customDir); + // realPath length is limited to 1024 bytes + if (errorCode != NativeRdb::E_OK || realPath.length() > 1024) { + LOGE("Parameter error. The database path must be a valid path."); + return RelationalStoreJsKit::E_PARAM_ERROR; + } + rdbConfig.path = realPath; + return NativeRdb::E_OK; + } + + void initContextParam(AppDataMgrJsKit::JSUtils::ContextParam ¶m, + std::shared_ptr abilitycontext) + { + param.bundleName = abilitycontext->GetBundleName(); + param.moduleName = abilitycontext->GetModuleName(); + param.baseDir = abilitycontext->GetDatabaseDir(); + param.area = abilitycontext->GetArea(); + param.isSystemApp = abilitycontext->IsSystemAppCalled(); + param.isStageMode = abilitycontext->IsStageMode(); + } + + void initRdbConfig(AppDataMgrJsKit::JSUtils::RdbConfig &rdbConfig, StoreConfig &config) + { + rdbConfig.isEncrypt = config.encrypt; + rdbConfig.isSearchable = config.isSearchable; + rdbConfig.isAutoClean = config.autoCleanDirtyData; + rdbConfig.securityLevel = static_cast(config.securityLevel); + rdbConfig.dataGroupId = config.dataGroupId; + rdbConfig.name = config.name; + rdbConfig.customDir = config.customDir; + } + + NativeRdb::RdbStoreConfig getRdbStoreConfig(const AppDataMgrJsKit::JSUtils::RdbConfig &rdbConfig, + const AppDataMgrJsKit::JSUtils::ContextParam ¶m) + { + NativeRdb::RdbStoreConfig rdbStoreConfig(rdbConfig.path); + rdbStoreConfig.SetEncryptStatus(rdbConfig.isEncrypt); + rdbStoreConfig.SetSearchable(rdbConfig.isSearchable); + rdbStoreConfig.SetIsVector(rdbConfig.vector); + rdbStoreConfig.SetAutoClean(rdbConfig.isAutoClean); + rdbStoreConfig.SetSecurityLevel(rdbConfig.securityLevel); + rdbStoreConfig.SetDataGroupId(rdbConfig.dataGroupId); + rdbStoreConfig.SetName(rdbConfig.name); + rdbStoreConfig.SetCustomDir(rdbConfig.customDir); + rdbStoreConfig.SetAllowRebuild(rdbConfig.allowRebuild); + + if (!param.bundleName.empty()) { + rdbStoreConfig.SetBundleName(param.bundleName); + } + rdbStoreConfig.SetModuleName(param.moduleName); + rdbStoreConfig.SetArea(param.area); + return rdbStoreConfig; + } + + int64_t GetRdbStore(OHOS::AbilityRuntime::Context* context, StoreConfig config, + int32_t *errCode) + { + auto abilitycontext = std::make_shared(context->shared_from_this()); + AppDataMgrJsKit::JSUtils::ContextParam param; + initContextParam(param, abilitycontext); + AppDataMgrJsKit::JSUtils::RdbConfig rdbConfig; + initRdbConfig(rdbConfig, config); + + *errCode = GetRealPath(rdbConfig, param, abilitycontext); + if (*errCode != NativeRdb::E_OK) { + return -1; + } + + DefaultOpenCallback callback; + auto rdbStore = + NativeRdb::RdbHelper::GetRdbStore(getRdbStoreConfig(rdbConfig, param), -1, callback, *errCode); + if (*errCode != 0) { + return -1; + } + auto nativeRdbStore = FFIData::Create(rdbStore); + if (nativeRdbStore == nullptr) { + *errCode = -1; + return -1; + } + return nativeRdbStore->GetID(); + } + + void DeleteRdbStore(OHOS::AbilityRuntime::Context* context, const char* name, + int32_t *errCode) + { + auto abilitycontext = std::make_shared(context->shared_from_this()); + AppDataMgrJsKit::JSUtils::ContextParam param; + initContextParam(param, abilitycontext); + AppDataMgrJsKit::JSUtils::RdbConfig rdbConfig; + rdbConfig.name = name; + + *errCode = GetRealPath(rdbConfig, param, abilitycontext); + if (*errCode != NativeRdb::E_OK) { + return; + } + *errCode = NativeRdb::RdbHelper::DeleteRdbStore(rdbConfig.path); + return; + } + + void DeleteRdbStoreConfig(OHOS::AbilityRuntime::Context* context, StoreConfig config, + int32_t *errCode) + { + auto abilitycontext = std::make_shared(context->shared_from_this()); + AppDataMgrJsKit::JSUtils::ContextParam param; + initContextParam(param, abilitycontext); + AppDataMgrJsKit::JSUtils::RdbConfig rdbConfig; + initRdbConfig(rdbConfig, config); + + *errCode = GetRealPath(rdbConfig, param, abilitycontext); + if (*errCode != NativeRdb::E_OK) { + return; + } + *errCode = NativeRdb::RdbHelper::DeleteRdbStore(rdbConfig.path); + return; + } +} +} \ No newline at end of file diff --git a/relational_store/frameworks/cj/src/relational_store_impl_resultsetproxy.cpp b/relational_store/frameworks/cj/src/relational_store_impl_resultsetproxy.cpp new file mode 100644 index 00000000..f4437179 --- /dev/null +++ b/relational_store/frameworks/cj/src/relational_store_impl_resultsetproxy.cpp @@ -0,0 +1,315 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "relational_store_impl_resultsetproxy.h" +#include "relational_store_utils.h" +#include "napi_rdb_error.h" +#include "value_object.h" +#include "native_log.h" + +namespace OHOS { +namespace Relational { + static const int E_OK = 0; + + ResultSetImpl::ResultSetImpl(std::shared_ptr resultSet) + { + resultSetValue = resultSet; + } + + OHOS::FFI::RuntimeType* ResultSetImpl::GetClassType() + { + static OHOS::FFI::RuntimeType runtimeType = OHOS::FFI::RuntimeType::Create("ResultSetImpl"); + return &runtimeType; + } + + CArrStr ResultSetImpl::GetAllColumnNames() + { + std::vector colNames; + int errCode = resultSetValue->GetAllColumnNames(colNames); + if (errCode != RelationalStoreJsKit::OK) { + LOGE("GetAllColumnNames failed code: %{public}d", errCode); + return CArrStr{nullptr, 0}; + } + if (colNames.size() == 0) { + return CArrStr{nullptr, 0}; + } + char** result = static_cast(malloc(colNames.size() * sizeof(char*))); + if (result == nullptr) { + return CArrStr{nullptr, -1}; + } + for (size_t i = 0; i < colNames.size(); i++) { + result[i] = MallocCString(colNames[i]); + if (result[i] == nullptr) { + for (size_t j = 0; j < i; j++) { + free(result[j]); + } + free(result); + return CArrStr{nullptr, -1}; + } + } + return CArrStr{result, int64_t(colNames.size())}; + } + + int32_t ResultSetImpl::GetColumnCount() + { + int32_t count = 0; + int errCode = resultSetValue->GetColumnCount(count); + if (errCode != RelationalStoreJsKit::OK) { + LOGE("GetColumnCount failed code:%{public}d", errCode); + } + return count; + } + + int32_t ResultSetImpl::GetRowCount() + { + int32_t result; + int errCode = resultSetValue->GetRowCount(result); + if (errCode != RelationalStoreJsKit::OK) { + LOGE("GetRowCount failed code:%{public}d", errCode); + } + return result; + } + + int32_t ResultSetImpl::GetRowIndex() + { + int32_t result; + int errCode = resultSetValue->GetRowIndex(result); + if (errCode != RelationalStoreJsKit::OK) { + LOGE("GetRowIndex failed code:%{public}d", errCode); + } + return result; + } + + bool ResultSetImpl::IsAtFirstRow() + { + bool result = false; + int errCode = resultSetValue->IsAtFirstRow(result); + if (errCode != RelationalStoreJsKit::OK) { + LOGE("IsAtFirstRow failed code:%{public}d", errCode); + } + return result; + } + + bool ResultSetImpl::IsAtLastRow() + { + bool result = false; + int errCode = resultSetValue->IsAtLastRow(result); + if (errCode != RelationalStoreJsKit::OK) { + LOGE("IsAtLastRow failed code:%{public}d", errCode); + } + return result; + } + + bool ResultSetImpl::IsEnded() + { + bool result = false; + int errCode = resultSetValue->IsEnded(result); + if (errCode != RelationalStoreJsKit::OK) { + LOGE("IsEnded failed code:%{public}d", errCode); + } + return result; + } + + bool ResultSetImpl::IsStarted() + { + bool result = false; + int errCode = resultSetValue->IsStarted(result); + if (errCode != RelationalStoreJsKit::OK) { + LOGE("IsBegin failed code:%{public}d", errCode); + } + return result; + } + + bool ResultSetImpl::IsClosed() + { + return resultSetValue->IsClosed(); + } + + double ResultSetImpl::GetDouble(int32_t columnIndex, int32_t* rtnCode) + { + double result = 0.0; + *rtnCode = resultSetValue->GetDouble(columnIndex, result); + return result; + } + + bool ResultSetImpl::GoToRow(int32_t position, int32_t* rtnCode) + { + *rtnCode = resultSetValue->GoToRow(position); + return *rtnCode == RelationalStoreJsKit::OK; + } + + bool ResultSetImpl::GoToPreviousRow(int32_t* rtnCode) + { + *rtnCode = resultSetValue->GoToPreviousRow(); + return *rtnCode == RelationalStoreJsKit::OK; + } + + bool ResultSetImpl::GoToLastRow(int32_t* rtnCode) + { + *rtnCode = resultSetValue->GoToLastRow(); + return *rtnCode == RelationalStoreJsKit::OK; + } + + char* ResultSetImpl::GetColumnName(int32_t columnIndex, int32_t* rtnCode) + { + std::string result; + *rtnCode = resultSetValue->GetColumnName(columnIndex, result); + if (*rtnCode != RelationalStoreJsKit::OK) { + LOGE("IsAtLastRow failed code:%{public}d", *rtnCode); + } + return MallocCString(result); + } + + bool ResultSetImpl::IsColumnNull(int32_t columnIndex, int32_t* rtnCode) + { + bool result; + *rtnCode = resultSetValue->IsColumnNull(columnIndex, result); + return result; + } + + Asset ResultSetImpl::GetAsset(int32_t columnIndex, int32_t* rtnCode) + { + NativeRdb::ValueObject::Asset asset; + *rtnCode = resultSetValue->GetAsset(columnIndex, asset); + Asset result = { + .name= MallocCString(asset.name), + .uri= MallocCString(asset.uri), + .path= MallocCString(asset.path), + .createTime= MallocCString(asset.createTime), + .modifyTime= MallocCString(asset.modifyTime), + .size= MallocCString(asset.size), + .status= (int32_t)asset.status + }; + return result; + } + + int32_t ResultSetImpl::Close() + { + return resultSetValue->Close(); + } + + int32_t ResultSetImpl::GetColumnIndex(char* columnName, int32_t* rtnCode) + { + int32_t result; + *rtnCode = resultSetValue->GetColumnIndex(columnName, result); + return result; + } + + char* ResultSetImpl::GetString(int32_t columnIndex, int32_t* rtnCode) + { + std::string result; + *rtnCode = resultSetValue->GetString(columnIndex, result); + return MallocCString(result); + } + + bool ResultSetImpl::GoToFirstRow(int32_t* rtnCode) + { + *rtnCode = resultSetValue->GoToFirstRow(); + return *rtnCode == RelationalStoreJsKit::OK; + } + + int64_t ResultSetImpl::GetLong(int32_t columnIndex, int32_t* rtnCode) + { + int64_t result; + *rtnCode = resultSetValue->GetLong(columnIndex, result); + return result; + } + + bool ResultSetImpl::GoToNextRow(int32_t* rtnCode) + { + *rtnCode = resultSetValue->GoToNextRow(); + return *rtnCode == RelationalStoreJsKit::OK; + } + + CArrUI8 ResultSetImpl::GetBlob(int32_t columnIndex, int32_t* rtnCode) + { + std::vector vec; + *rtnCode = resultSetValue->GetBlob(columnIndex, vec); + if (*rtnCode != RelationalStoreJsKit::OK || vec.size() == 0) { + return CArrUI8{nullptr, 0}; + } + uint8_t* result = static_cast(malloc(vec.size() * sizeof(uint8_t))); + if (result == nullptr) { + return CArrUI8{nullptr, -1}; + } + for (size_t i = 0; i < vec.size(); i++) { + result[i] = vec[i]; + } + return CArrUI8{result, int64_t(vec.size())}; + } + + bool ResultSetImpl::GoTo(int32_t offset, int32_t* rtnCode) + { + *rtnCode = resultSetValue->GoTo(offset); + return *rtnCode == RelationalStoreJsKit::OK; + } + + Assets ResultSetImpl::GetAssets(int32_t columnIndex, int32_t* rtnCode) + { + std::vector assets; + *rtnCode = resultSetValue->GetAssets(columnIndex, assets); + if (*rtnCode != RelationalStoreJsKit::OK || assets.size() == 0) { + return Assets{nullptr, 0}; + } + Asset* result = static_cast(malloc(assets.size() * sizeof(Asset))); + if (result == nullptr) { + return Assets{nullptr, -1}; + } + for (size_t i = 0; i < assets.size(); i++) { + result[i] = Asset { + .name= MallocCString(assets[i].name), + .uri= MallocCString(assets[i].uri), + .path= MallocCString(assets[i].path), + .createTime= MallocCString(assets[i].createTime), + .modifyTime= MallocCString(assets[i].modifyTime), + .size= MallocCString(assets[i].size), + .status= (int32_t)assets[i].status + }; + } + return Assets{.head = result, .size = (int64_t)(assets.size())}; + } + + ValuesBucket ResultSetImpl::GetRow(int32_t* rtnCode) + { + NativeRdb::RowEntity rowEntity; + *rtnCode = resultSetValue->GetRow(rowEntity); + if (*rtnCode != E_OK) { + return ValuesBucket{nullptr, nullptr, 0}; + } + const std::map map = rowEntity.Get(); + size_t size = map.size(); + if (size == 0) { + return ValuesBucket{nullptr, nullptr, 0}; + } + ValuesBucket result = ValuesBucket { + .key = static_cast(malloc(sizeof(char*) * size)), + .value = static_cast(malloc(sizeof(ValueType) * size)), + .size = size + }; + if (result.key == nullptr || result.value == nullptr) { + free(result.key); + free(result.value); + return ValuesBucket{nullptr, nullptr, -1}; + } + int64_t i = 0; + for (auto &t : map) { + result.key[i] = MallocCString(t.first); + result.value[i] = ValueObjectToValueType(t.second); + i++; + } + return result; + } +} +} \ No newline at end of file diff --git a/relational_store/frameworks/cj/src/relational_store_utils.cpp b/relational_store/frameworks/cj/src/relational_store_utils.cpp new file mode 100644 index 00000000..3077b922 --- /dev/null +++ b/relational_store/frameworks/cj/src/relational_store_utils.cpp @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "relational_store_utils.h" +#include "native_log.h" + +namespace OHOS { +namespace Relational { + char* MallocCString(const std::string& origin) + { + if (origin.empty()) { + return nullptr; + } + auto len = origin.length() + 1; + char* res = static_cast(malloc(sizeof(char) * len)); + if (res == nullptr) { + return nullptr; + } + return std::char_traits::copy(res, origin.c_str(), len); + } + + NativeRdb::ValueObject ValueTypeToValueObjectBlob(const ValueType& value) + { + std::vector blob = std::vector(); + for (int64_t j = 0; j < value.Uint8Array.size; j++) { + blob.push_back(value.Uint8Array.head[j]); + } + return NativeRdb::ValueObject(blob); + } + + NativeRdb::ValueObject ValueTypeToValueObjectAsset(const ValueType& value) + { + std::string modifyTime = value.asset.modifyTime; + std::string size = value.asset.size; + NativeRdb::ValueObject::Asset asset = { + .status = value.asset.status, + .name = value.asset.name, + .uri = value.asset.uri, + .createTime = value.asset.createTime, + .modifyTime = modifyTime, + .size = size, + .hash = modifyTime + "_" + size, + .path = value.asset.path + }; + return NativeRdb::ValueObject(asset); + } + + NativeRdb::ValueObject ValueTypeToValueObjectAssets(const ValueType& value) + { + std::vector assets = std::vector(); + for (int64_t j = 0; j < value.assets.size; j++) { + Asset asset = value.assets.head[j]; + std::string modifyTime = asset.modifyTime; + std::string size = asset.size; + NativeRdb::ValueObject::Asset nativeAsset = { + .status = asset.status, + .name = asset.name, + .uri = asset.uri, + .createTime = asset.createTime, + .modifyTime = modifyTime, + .size = size, + .hash = modifyTime + "_" + size, + .path = asset.path + }; + assets.push_back(nativeAsset); + } + return NativeRdb::ValueObject(assets); + } + + NativeRdb::ValueObject ValueTypeToValueObject(const ValueType& value) + { + NativeRdb::ValueObject valueObject; + switch (value.tag) { + case TYPE_NULL: { + valueObject = NativeRdb::ValueObject(); + break; + } + case TYPE_INT: { + valueObject = NativeRdb::ValueObject(value.integer); + break; + } + case TYPE_DOU: { + valueObject = NativeRdb::ValueObject(value.dou); + break; + } + case TYPE_STR: { + valueObject = NativeRdb::ValueObject(value.string); + break; + } + case TYPE_BOOL: { + valueObject = NativeRdb::ValueObject(value.boolean); + break; + } + case TYPE_BLOB: { + valueObject = ValueTypeToValueObjectBlob(value); + break; + } + case TYPE_ASSET: { + valueObject = ValueTypeToValueObjectAsset(value); + break; + } + case TYPE_ASSETS: { + valueObject = ValueTypeToValueObjectAssets(value); + break; + } + default: + valueObject = NativeRdb::ValueObject(); + break; + } + return valueObject; + } + + ValueType ValueObjectToValueTypeAsset(const NativeRdb::ValueObject& object) + { + NativeRdb::ValueObject::Asset val; + object.GetAsset(val); + Asset asset = Asset { + .name = MallocCString(val.name), + .uri = MallocCString(val.uri), + .path = MallocCString(val.path), + .createTime = MallocCString(val.createTime), + .modifyTime = MallocCString(val.modifyTime), + .size = MallocCString(val.size), + .status = val.status + }; + return ValueType {.asset = asset, .tag = TYPE_ASSET}; + } + + ValueType ValueObjectToValueTypeAssets(const NativeRdb::ValueObject& object) + { + NativeRdb::ValueObject::Assets val; + object.GetAssets(val); + Assets assets = Assets {.head = static_cast(malloc(val.size() * sizeof(Asset))), .size = val.size()}; + if (assets.head == nullptr) { + return ValueType {.assets = Assets{nullptr, -1}, .tag = TYPE_ASSETS}; + } + for (std::size_t i = 0; i < val.size(); i++) { + assets.head[i] = Asset { + .name = MallocCString(val[i].name), + .uri = MallocCString(val[i].uri), + .path = MallocCString(val[i].path), + .createTime = MallocCString(val[i].createTime), + .modifyTime = MallocCString(val[i].modifyTime), + .size = MallocCString(val[i].size), + .status = static_cast(val[i].status) + }; + } + return ValueType {.assets = assets, .tag = TYPE_ASSETS}; + } + + ValueType ValueObjectToValueType(const NativeRdb::ValueObject& object) + { + switch (object.GetType()) { + case NativeRdb::ValueObject::TYPE_NULL: + return ValueType {.tag = TYPE_NULL}; + case NativeRdb::ValueObject::TYPE_INT: { + int64_t val; + object.GetLong(val); + return ValueType {.integer = val, .tag = TYPE_INT}; + } + case NativeRdb::ValueObject::TYPE_DOUBLE: { + double val; + object.GetDouble(val); + return ValueType {.dou = val, .tag = TYPE_DOU}; + } + case NativeRdb::ValueObject::TYPE_STRING: { + std::string val; + object.GetString(val); + return ValueType {.string = MallocCString(val), .tag = TYPE_STR}; + } + case NativeRdb::ValueObject::TYPE_BOOL: { + bool val; + object.GetBool(val); + return ValueType {.boolean = val, .tag = TYPE_BOOL}; + } + case NativeRdb::ValueObject::TYPE_BLOB: { + std::vector val; + object.GetBlob(val); + CArrUI8 arr = CArrUI8 {.head = static_cast(malloc(val.size() * sizeof(uint8_t))), + .size = val.size()}; + if (arr.head == nullptr) { + return ValueType {.Uint8Array = CArrUI8 {nullptr, -1}, .tag = TYPE_BLOB}; + } + return ValueType {.Uint8Array = arr, .tag = TYPE_BLOB}; + } + case NativeRdb::ValueObject::TYPE_ASSET: { + return ValueObjectToValueTypeAsset(object); + } + case NativeRdb::ValueObject::TYPE_ASSETS: { + return ValueObjectToValueTypeAssets(object); + } + case NativeRdb::ValueObject::TYPE_BUTT: + return ValueType {.tag = 128}; + default: + return ValueType {.tag = TYPE_NULL}; + } + } +} +} \ No newline at end of file diff --git a/relational_store/frameworks/js/napi/cloud_data/BUILD.gn b/relational_store/frameworks/js/napi/cloud_data/BUILD.gn index 74f85972..757b7d3e 100644 --- a/relational_store/frameworks/js/napi/cloud_data/BUILD.gn +++ b/relational_store/frameworks/js/napi/cloud_data/BUILD.gn @@ -24,6 +24,8 @@ ohos_copy("relational_store_declaration") { ohos_shared_library("clouddata") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false diff --git a/relational_store/frameworks/js/napi/cloud_extension/cloud_extension_stub.js b/relational_store/frameworks/js/napi/cloud_extension/cloud_extension_stub.js index 89fabe97..6293c476 100644 --- a/relational_store/frameworks/js/napi/cloud_extension/cloud_extension_stub.js +++ b/relational_store/frameworks/js/napi/cloud_extension/cloud_extension_stub.js @@ -19,6 +19,7 @@ let rpc = requireNapi('rpc'); const TAG = 'cloudExtension'; const INVALID_STATE = -1; const INVALID_STR = ''; +const MAX_SIZE = 4 * 1024 * 1024 * 1024 - 1; export var cloudExtension; (function (a) { @@ -212,6 +213,9 @@ export var cloudExtension; let c1 = {}; let z1 = t.readInt(); c1[z] = []; + if (z1 < 0 || z1 > MAX_SIZE) { + return c1; + } for (let a2 = 0; a2 < z1; a2++) { c1[z].push(this.unMarshallingDatabase(t)); } @@ -221,10 +225,16 @@ export var cloudExtension; unMarshallingUnSubInfo(t) { let e1 = {}; let b2 = t.readInt(); + if (b2 < 0 || b2 > MAX_SIZE) { + return e1; + } for (let c2 = 0; c2 < b2; c2++) { let d2 = t.readString(); e1[d2] = []; let e2 = t.readInt(); + if (e2 < 0 || e2 > MAX_SIZE) { + continue; + } for (let f2 = 0; f2 < e2; f2++) { e1[d2].push(t.readString()); } @@ -242,6 +252,9 @@ export var cloudExtension; h1.alias = t.readString(); h1.tables = []; let g2 = t.readInt(); + if (g2 < 0 || g2 > MAX_SIZE) { + return h1; + } for (let c2 = 0; c2 < g2; c2++) { let h2 = t.readString(); let i2 = t.readString(); @@ -252,6 +265,9 @@ export var cloudExtension; }; h1.tables.push(v1); let j2 = t.readInt(); + if (j2 < 0 || j2 > MAX_SIZE) { + continue; + } for (let k2 = 0; k2 < j2; k2++) { let w1 = { alias: t.readString(), @@ -385,6 +401,9 @@ export var cloudExtension; unMarshallingFiledArray(t) { let v2 = []; let h3 = t.readInt(); + if (h3 < 0 || h3 > MAX_SIZE) { + return v2; + } for (let f2 = 0; f2 < h3; f2++) { v2.push(t.readString()); } @@ -398,6 +417,9 @@ export var cloudExtension; } marshallingResultValueBucket(u, i3) { + if (i3.length > MAX_SIZE) { + return; + } u.writeInt(i3.length); for (let f2 = 0; f2 < i3.length; f2++) { u.writeInt(i3[f2].code); @@ -491,6 +513,9 @@ export var cloudExtension; } marshallingValuesBuckets(u, m3) { + if (m3.length > MAX_SIZE) { + return; + } u.writeInt(m3.length); for (let f2 = 0; f2 < m3.length; f2++) { this.marshallingValueBucket(u, m3[f2]); @@ -500,6 +525,9 @@ export var cloudExtension; unMarshallingValuesBuckets(t) { let n3 = t.readInt(); let m3 = []; + if (n3 < 0 || n3 > MAX_SIZE) { + return m3; + } for (let f2 = 0; f2 < n3; f2++) { m3.push(this.unMarshallingValuesBucket(t)); } @@ -509,6 +537,9 @@ export var cloudExtension; unMarshallingValuesBucket(t) { let k3 = {}; let n3 = t.readInt(); + if (n3 < 0 || n3 > MAX_SIZE) { + return k3; + } for (let f2 = 0; f2 < n3; f2++) { let s1 = t.readString(); let t1 = this.unMarshallingValueType(t); @@ -547,6 +578,9 @@ export var cloudExtension; case f.ASSETS: // Assets let p3 = t.readInt(); let q3 = []; + if (p3 < 0 || p3 > MAX_SIZE) { + return q3; + } for (let c2 = 0; c2 < p3; c2++) { q3.push({ name: t.readString(), @@ -598,6 +632,9 @@ export var cloudExtension; unmarshallingAssets(t) { let h3 = t.readInt(); let w3 = []; + if (h3 < 0 || h3 > MAX_SIZE) { + return w3; + } for (let f2 = 0; f2 < h3; f2++) { w3.push({ name: t.readString(), @@ -616,6 +653,9 @@ export var cloudExtension; marshallingAssets(u, q3) { u.writeInt(q3.length); + if (q3.length > MAX_SIZE) { + return; + } for (let f2 = 0; f2 < q3.length; f2++) { u.writeInt(q3[f2].code); u.writeString(q3[f2].value.name); @@ -739,6 +779,9 @@ export var cloudExtension; unMarshallingParticipants(t) { let i5 = []; let h3 = t.readInt(); + if (h3 < 0 || h3 > MAX_SIZE) { + return i5; + } for (let f2 = 0; f2 < h3; f2++) { i5.push(this.unMarshallingParticipant(t)); } diff --git a/relational_store/frameworks/js/napi/common/include/js_uv_queue.h b/relational_store/frameworks/js/napi/common/include/js_uv_queue.h index 9e86b9b1..0da19cf8 100644 --- a/relational_store/frameworks/js/napi/common/include/js_uv_queue.h +++ b/relational_store/frameworks/js/napi/common/include/js_uv_queue.h @@ -88,6 +88,7 @@ private: napi_value GetCallback(); napi_value GetObject(); void BindPromise(napi_value promise); + void DelReference(); Result *StealResult(); int32_t GetArgv(napi_value *argv, int32_t max); }; diff --git a/relational_store/frameworks/js/napi/common/mock/include/event_handler.h b/relational_store/frameworks/js/napi/common/mock/include/event_handler.h new file mode 100644 index 00000000..7b4c425a --- /dev/null +++ b/relational_store/frameworks/js/napi/common/mock/include/event_handler.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef DISTRIBUTEDDATAMGR_APPDATAMGR_EVENT_HANDLER_H +#define DISTRIBUTEDDATAMGR_APPDATAMGR_EVENT_HANDLER_H + +#include +#include +namespace OHOS { +namespace AppExecFwk { +using Callback = std::function; +class EventHandler { +public: + static std::shared_ptr Current() + { + return nullptr; + } + + inline bool PostTask(const Callback &callback) + { + return false; + } +}; +} +} // namespace OHOS::AppDataMgrJsKit +#endif // DISTRIBUTEDDATAMGR_APPDATAMGR_EVENT_HANDLER_H diff --git a/relational_store/frameworks/js/napi/common/src/js_uv_queue.cpp b/relational_store/frameworks/js/napi/common/src/js_uv_queue.cpp index 574c2d42..1f10fe48 100644 --- a/relational_store/frameworks/js/napi/common/src/js_uv_queue.cpp +++ b/relational_store/frameworks/js/napi/common/src/js_uv_queue.cpp @@ -12,11 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "event_handler.h" #define LOG_TAG "UvQueue" -#include "js_uv_queue.h" #include + #include "js_scope.h" +#include "js_uv_queue.h" #include "logger.h" namespace OHOS::AppDataMgrJsKit { using namespace OHOS::Rdb; @@ -71,7 +71,10 @@ void UvQueue::AsyncCall(UvCallback callback, Args args, Result result) void UvQueue::AsyncCallInOrder(UvCallback callback, Args args, Result result) { - if (handler_ == nullptr || callback.IsNull()) { + if (handler_ == nullptr) { + AsyncCall(std::move(callback), std::move(args), std::move(result)); + } + if (callback.IsNull()) { LOG_ERROR("handler_ or callback is nullptr"); return; } @@ -230,6 +233,7 @@ UvQueue::Task UvQueue::GenCallbackTask(std::shared_ptr entry) Scope scope(entry->env_); napi_value method = entry->GetCallback(); if (method == nullptr) { + entry->DelReference(); LOG_ERROR("the callback is invalid, maybe is cleared!"); return; } @@ -238,6 +242,7 @@ UvQueue::Task UvQueue::GenCallbackTask(std::shared_ptr entry) auto object = entry->GetObject(); napi_value promise = nullptr; auto status = napi_call_function(entry->env_, object, method, argc, argv, &promise); + entry->DelReference(); if (status != napi_ok) { LOG_ERROR("notify data change failed status:%{public}d.", status); return; @@ -248,11 +253,14 @@ UvQueue::Task UvQueue::GenCallbackTask(std::shared_ptr entry) UvQueue::UvEntry::~UvEntry() { - if (callback_ == nullptr || repeat_) { - return; +} + +void UvQueue::UvEntry::DelReference() +{ + if (callback_ != nullptr && !repeat_) { + napi_delete_reference(env_, callback_); + callback_ = nullptr; } - napi_delete_reference(env_, callback_); - callback_ = nullptr; if (object_ != nullptr) { napi_delete_reference(env_, object_); object_ = nullptr; diff --git a/relational_store/frameworks/js/napi/dataability/BUILD.gn b/relational_store/frameworks/js/napi/dataability/BUILD.gn index 51d68243..a958a401 100644 --- a/relational_store/frameworks/js/napi/dataability/BUILD.gn +++ b/relational_store/frameworks/js/napi/dataability/BUILD.gn @@ -24,6 +24,8 @@ ohos_copy("relational_store_declaration") { ohos_shared_library("dataability") { branch_protector_ret = "pac_ret" sanitize = { + boundary_sanitize = true + ubsan = true cfi = true cfi_cross_dso = true debug = false diff --git a/relational_store/frameworks/js/napi/rdb/BUILD.gn b/relational_store/frameworks/js/napi/rdb/BUILD.gn index 62e326ec..12f82241 100644 --- a/relational_store/frameworks/js/napi/rdb/BUILD.gn +++ b/relational_store/frameworks/js/napi/rdb/BUILD.gn @@ -67,6 +67,8 @@ ohos_shared_library("napi_rdb") { if (is_ohos) { branch_protector_ret = "pac_ret" sanitize = { + boundary_sanitize = true + ubsan = true cfi = true cfi_cross_dso = true debug = false @@ -95,6 +97,7 @@ ohos_shared_library("napi_rdb") { external_deps = [ "ability_runtime:abilitykit_native", + "ability_runtime:extensionkit_native", "ability_runtime:napi_base_context", "c_utils:utils", "common_event_service:cesfwk_innerkits", @@ -144,6 +147,8 @@ ohos_shared_library("rdb") { if (is_ohos) { branch_protector_ret = "pac_ret" sanitize = { + boundary_sanitize = true + ubsan = true cfi = true cfi_cross_dso = true debug = false diff --git a/relational_store/frameworks/js/napi/rdb/src/napi_rdb_store.cpp b/relational_store/frameworks/js/napi/rdb/src/napi_rdb_store.cpp index e162140a..937bf8c9 100644 --- a/relational_store/frameworks/js/napi/rdb/src/napi_rdb_store.cpp +++ b/relational_store/frameworks/js/napi/rdb/src/napi_rdb_store.cpp @@ -1097,7 +1097,7 @@ napi_value RdbStoreProxy::SetDistributedTables(napi_env env, napi_callback_info } int res = obj->rdbStore_->SetDistributedTables(context->tablesName); LOG_DEBUG("RdbStoreProxy::SetDistributedTables res is : %{public}d", res); - return (res == E_OK || res == E_NOT_SUPPORTED) ? OK : ERR; + return (res == E_OK || res == E_NOT_SUPPORT) ? OK : ERR; }; auto output = [context](napi_env env, napi_value &result) -> int { napi_status status = napi_get_undefined(env, &result); 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 faf14f8a..4979a716 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,13 @@ std::shared_ptr ResultSetProxy::GetNativeObject( std::shared_ptr ResultSetProxy::Create() { - if (GetInstance() == nullptr) { + auto instance = GetInstance(); + if (instance == nullptr) { LOG_ERROR("resultSet_ is null"); return nullptr; } - return std::make_shared(GetInstance()); + SetInstance(nullptr); + return std::make_shared(instance); } #endif diff --git a/relational_store/frameworks/js/napi/relationalstore/BUILD.gn b/relational_store/frameworks/js/napi/relationalstore/BUILD.gn index 8e15b8c8..524aad4a 100644 --- a/relational_store/frameworks/js/napi/relationalstore/BUILD.gn +++ b/relational_store/frameworks/js/napi/relationalstore/BUILD.gn @@ -41,6 +41,8 @@ if (is_ohos) { ohos_shared_library("relationalstore") { branch_protector_ret = "pac_ret" sanitize = { + boundary_sanitize = true + ubsan = true cfi = true cfi_cross_dso = true debug = false @@ -70,6 +72,7 @@ if (is_ohos) { external_deps = [ "ability_runtime:abilitykit_native", + "ability_runtime:extensionkit_native", "ability_runtime:napi_base_context", "c_utils:utils", "common_event_service:cesfwk_innerkits", @@ -219,6 +222,8 @@ if (is_ohos) { "//plugins/libs/napi:napi_ios", ] + external_deps = [ "c_utils:utils" ] + subsystem_name = "distributeddatamgr" part_name = "relational_store" } diff --git a/relational_store/frameworks/js/napi/relationalstore/include/napi_async_call.h b/relational_store/frameworks/js/napi/relationalstore/include/napi_async_call.h index a3dd5d49..920be703 100644 --- a/relational_store/frameworks/js/napi/relationalstore/include/napi_async_call.h +++ b/relational_store/frameworks/js/napi/relationalstore/include/napi_async_call.h @@ -38,6 +38,7 @@ extern bool g_sync; #define ASYNC &g_async #define SYNC &g_sync +#define ASYNC_CALL(env, ctx) AsyncCall::Call(env, ctx, __FUNCTION__) class ContextBase { public: struct RecordData { @@ -66,6 +67,7 @@ public: void *boundObj = nullptr; std::shared_ptr error; std::shared_ptr executed_; + const char *fun = nullptr; napi_ref self_ = nullptr; napi_ref callback_ = nullptr; @@ -81,7 +83,7 @@ public: class AsyncCall final { public: - static napi_value Call(napi_env env, std::shared_ptr context); + static napi_value Call(napi_env env, std::shared_ptr context, const char *fun); private: enum { ARG_ERROR, ARG_DATA, ARG_BUTT }; diff --git a/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_js_utils.h b/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_js_utils.h index b879d331..ce6fc72a 100644 --- a/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_js_utils.h +++ b/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_js_utils.h @@ -36,12 +36,14 @@ using Error = RelationalStoreJsKit::Error; using SecurityLevel = NativeRdb::SecurityLevel; using RdbStoreConfig = NativeRdb::RdbStoreConfig; using BigInt = OHOS::NativeRdb::BigInteger; +using SqlExecInfo = DistributedRdb::SqlObserver::SqlExecutionInfo; struct RdbConfig { bool isEncrypt = false; bool isSearchable = false; bool isAutoClean = false; bool vector = false; bool allowRebuild = false; + bool isReadOnly = false; SecurityLevel securityLevel = SecurityLevel::LAST; std::string dataGroupId; std::string name; @@ -103,7 +105,8 @@ template<> int32_t Convert2Value(napi_env env, napi_value jsValue, BigInt &value); template<> std::string ToString(const PRIKey &key); - +template<> +napi_value Convert2JSValue(napi_env env, const SqlExecInfo &sqlExeInfo); bool IsNapiString(napi_env env, napi_value value); std::tuple> GetRealPath( diff --git a/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store.h b/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store.h index cb8020a7..dca21316 100644 --- a/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store.h +++ b/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store.h @@ -51,7 +51,6 @@ private: static napi_value Insert(napi_env env, napi_callback_info info); static napi_value BatchInsert(napi_env env, napi_callback_info info); static napi_value Query(napi_env env, napi_callback_info info); - static napi_value QuerySync(napi_env env, napi_callback_info info); static napi_value RemoteQuery(napi_env env, napi_callback_info info); static napi_value QuerySql(napi_env env, napi_callback_info info); static napi_value ExecuteSql(napi_env env, napi_callback_info info); @@ -95,7 +94,7 @@ private: static napi_value UnlockRow(napi_env env, napi_callback_info info); static napi_value QueryLockedRow(napi_env env, napi_callback_info info); - static constexpr int EVENT_HANDLE_NUM = 2; + static constexpr int EVENT_HANDLE_NUM = 3; static constexpr int WAIT_TIME_DEFAULT = 2; static constexpr int WAIT_TIME_LIMIT = 300; @@ -114,6 +113,7 @@ private: public: SyncObserver(napi_env env, napi_value callback, std::shared_ptr uvQueue); virtual ~SyncObserver(); + void Clear(); bool operator==(napi_value value); void ProgressNotification(const DistributedRdb::Details &details) override; @@ -123,8 +123,25 @@ private: std::shared_ptr queue_ = nullptr; }; + class NapiStatisticsObserver + : public DistributedRdb::SqlObserver, public std::enable_shared_from_this { + public: + NapiStatisticsObserver(napi_env env, napi_value callback, std::shared_ptr uvQueue); + virtual ~NapiStatisticsObserver(); + void Clear(); + bool operator==(napi_value value); + void OnStatistic(const SqlExecutionInfo &sqlExeInfo) override; + + private: + napi_env env_ = nullptr; + napi_ref callback_ = nullptr; + std::shared_ptr queue_ = nullptr; + }; + napi_value RegisterSyncCallback(napi_env env, size_t argc, napi_value *argv); napi_value UnregisterSyncCallback(napi_env env, size_t argc, napi_value *argv); + napi_value OnStatistics(napi_env env, size_t argc, napi_value *argv); + napi_value OffStatistics(napi_env env, size_t argc, napi_value *argv); using EventHandle = napi_value (RdbStoreProxy::*)(napi_env, size_t, napi_value *); struct HandleInfo { @@ -133,19 +150,23 @@ private: }; static constexpr HandleInfo onEventHandlers_[EVENT_HANDLE_NUM] = { { "dataChange", &RdbStoreProxy::OnRemote }, - { "autoSyncProgress", &RdbStoreProxy::RegisterSyncCallback } + { "autoSyncProgress", &RdbStoreProxy::RegisterSyncCallback }, + { "statistics", &RdbStoreProxy::OnStatistics } }; static constexpr HandleInfo offEventHandlers_[EVENT_HANDLE_NUM] = { { "dataChange", &RdbStoreProxy::OffRemote }, - { "autoSyncProgress", &RdbStoreProxy::UnregisterSyncCallback } + { "autoSyncProgress", &RdbStoreProxy::UnregisterSyncCallback }, + { "statistics", &RdbStoreProxy::OffStatistics } }; bool isSystemAppCalled_ = false; + int32_t dbType = NativeRdb::DB_SQLITE; std::shared_ptr queue_; std::list> observers_[DistributedRdb::SUBSCRIBE_MODE_MAX]; std::map>> localObservers_; std::map>> localSharedObservers_; std::list> syncObservers_; + std::list> statisticses_; }; } // namespace RelationalStoreJsKit } // namespace OHOS diff --git a/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store_observer.h b/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store_observer.h index 95208511..18a55690 100644 --- a/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store_observer.h +++ b/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store_observer.h @@ -17,10 +17,13 @@ #define NAPI_RDB_STORE_OBSERVER_H #include "rdb_types.h" -#include "napi_uv_queue.h" +#include "js_uv_queue.h" namespace OHOS::RelationalStoreJsKit { -class NapiRdbStoreObserver : public DistributedRdb::RdbStoreObserver, public NapiUvQueue { +using namespace OHOS::AppDataMgrJsKit; + +class NapiRdbStoreObserver : public DistributedRdb::RdbStoreObserver, + public std::enable_shared_from_this { public: using Origin = DistributedRdb::Origin; struct JSChangeInfo { @@ -31,7 +34,8 @@ public: std::vector updated; std::vector deleted; }; - explicit NapiRdbStoreObserver(napi_env env, napi_value callback, int32_t mode = DistributedRdb::REMOTE); + explicit NapiRdbStoreObserver(napi_value callback, std::shared_ptr uvQueue, + int32_t mode = DistributedRdb::REMOTE); virtual ~NapiRdbStoreObserver() noexcept; void OnChange(const std::vector& devices) override; @@ -40,8 +44,14 @@ public: void OnChange() override; + void Clear(); + + bool operator==(napi_value value); + private: int32_t mode_ = DistributedRdb::REMOTE; + std::shared_ptr uvQueue_; + napi_ref callback_; }; } // namespace OHOS::RelationalStoreJsKit #endif diff --git a/relational_store/frameworks/js/napi/relationalstore/mock/include/napi_rdb_store.h b/relational_store/frameworks/js/napi/relationalstore/mock/include/napi_rdb_store.h index 6c8d6ccc..fdb0f686 100644 --- a/relational_store/frameworks/js/napi/relationalstore/mock/include/napi_rdb_store.h +++ b/relational_store/frameworks/js/napi/relationalstore/mock/include/napi_rdb_store.h @@ -51,7 +51,6 @@ private: static napi_value BatchInsert(napi_env env, napi_callback_info info); static napi_value Query(napi_env env, napi_callback_info info); static napi_value QuerySql(napi_env env, napi_callback_info info); - static napi_value QuerySync(napi_env env, napi_callback_info info); static napi_value ExecuteSql(napi_env env, napi_callback_info info); static napi_value Execute(napi_env env, napi_callback_info info); static napi_value Backup(napi_env env, napi_callback_info info); @@ -64,7 +63,9 @@ private: static napi_value IsHoldingConnection(napi_env env, napi_callback_info info); static napi_value IsReadOnly(napi_env env, napi_callback_info info); static napi_value BeginTransaction(napi_env env, napi_callback_info info); + static napi_value BeginTrans(napi_env env, napi_callback_info info); static napi_value RollBack(napi_env env, napi_callback_info info); + static napi_value RollBackByTxId(napi_env env, napi_callback_info info); static napi_value Commit(napi_env env, napi_callback_info info); static napi_value QueryByStep(napi_env env, napi_callback_info info); static napi_value IsInTransaction(napi_env env, napi_callback_info info); 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 f3190f33..e98aed2b 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 @@ -32,6 +32,7 @@ public: ~ResultSetProxy(); ResultSetProxy(std::shared_ptr resultSet); ResultSetProxy &operator=(std::shared_ptr resultSet); + static void Init(napi_env env, napi_value exports); static napi_value NewInstance(napi_env env, std::shared_ptr resultSet); static napi_value GetConstructor(napi_env env); @@ -66,10 +67,12 @@ private: static napi_value GetBlob(napi_env env, napi_callback_info info); static napi_value GetAsset(napi_env env, napi_callback_info info); static napi_value GetAssets(napi_env env, napi_callback_info info); + static napi_value GetFloat32Array(napi_env env, napi_callback_info info); static napi_value GetString(napi_env env, napi_callback_info info); static napi_value GetDouble(napi_env env, napi_callback_info info); static napi_value IsColumnNull(napi_env env, napi_callback_info info); static napi_value GetRow(napi_env env, napi_callback_info info); + static napi_value GetValue(napi_env env, napi_callback_info info); static napi_value IsClosed(napi_env env, napi_callback_info info); static napi_value GetSharedBlockName(napi_env env, napi_callback_info info); diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_async_call.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_async_call.cpp index 71d496ed..06223b79 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_async_call.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_async_call.cpp @@ -116,12 +116,13 @@ void AsyncCall::SetBusinessError(napi_env env, std::shared_ptr error, nap } } -napi_value AsyncCall::Call(napi_env env, std::shared_ptr context) +napi_value AsyncCall::Call(napi_env env, std::shared_ptr context, const char *fun) { record_.total_.times_++; record_.total_.lastTime_ = std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch()).count(); context->executed_ = record_.executed_; + context->fun = (fun == nullptr || fun[0] == '\0') ? "RelationalStoreAsyncCall" : fun; return context->isAsync_ ? Async(env, context) : Sync(env, context); } @@ -137,7 +138,7 @@ napi_value AsyncCall::Async(napi_env env, std::shared_ptr context) } context->keep_ = context; napi_value resource = nullptr; - napi_create_string_utf8(env, "RelationalStoreAsyncCall", NAPI_AUTO_LENGTH, &resource); + napi_create_string_utf8(env, context->fun, NAPI_AUTO_LENGTH, &resource); // create async work, execute function is OnExecute, complete function is OnComplete napi_create_async_work(env, nullptr, resource, AsyncCall::OnExecute, AsyncCall::OnComplete, reinterpret_cast(context.get()), &context->work_); diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_const_properties.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_const_properties.cpp index 13aed47c..ced69f94 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_const_properties.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_const_properties.cpp @@ -193,6 +193,7 @@ static napi_value ExportRebuiltType(napi_env env) SET_NAPI_PROPERTY(rebuiltType, "NONE", int32_t(NativeRdb::RebuiltType::NONE)); SET_NAPI_PROPERTY(rebuiltType, "REBUILT", int32_t(NativeRdb::RebuiltType::REBUILT)); + SET_NAPI_PROPERTY(rebuiltType, "REPAIRED", int32_t(NativeRdb::RebuiltType::REPAIRED)); napi_object_freeze(env, rebuiltType); return rebuiltType; diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_error.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_error.cpp index fd1ed825..5b9f0e9d 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_error.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_error.cpp @@ -21,7 +21,8 @@ namespace OHOS { namespace RelationalStoreJsKit { using JsErrorCode = OHOS::RelationalStoreJsKit::JsErrorCode; static constexpr JsErrorCode JS_ERROR_CODE_MSGS[] = { - { NativeRdb::E_NOT_SUPPORTED, 801, "Capability not supported." }, + { E_NOT_STAGE_MODE, 14801001, "Only supported in stage mode." }, + { E_DATA_GROUP_ID_INVALID, 14801002, "The data group id is invalid." }, { NativeRdb::E_NOT_SELECT, 14800019, "The SQL must be a query statement." }, { NativeRdb::E_COLUMN_OUT_RANGE, 14800013, "Column out of bounds." }, { NativeRdb::E_INVALID_FILE_PATH, 14800010, "Invalid database path." }, @@ -49,8 +50,7 @@ static constexpr JsErrorCode JS_ERROR_CODE_MSGS[] = { { NativeRdb::E_SQLITE_MISMATCH, 14800033, "SQLite: Data type mismatch." }, { NativeRdb::E_SQLITE_MISUSE, 14800034, "SQLite: Library used incorrectly." }, { NativeRdb::E_CONFIG_INVALID_CHANGE, 14800017, "Config changed." }, - { E_NOT_STAGE_MODE, 14801001, "Only supported in stage mode." }, - { E_DATA_GROUP_ID_INVALID, 14801002, "The data group id is invalid." }, + { NativeRdb::E_NOT_SUPPORT, 801, "Capability not support." }, }; const std::optional GetJsErrorCode(int32_t errorCode) diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_js_utils.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_js_utils.cpp index 274a101c..44d4fd89 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_js_utils.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_js_utils.cpp @@ -23,6 +23,8 @@ #include "logger.h" #include "rdb_errno.h" #include "rdb_sql_utils.h" +#include "rdb_sql_statistic.h" +#include "rdb_types.h" #include "result_set.h" #define NAPI_CALL_RETURN_ERR(theCall, retVal) \ @@ -184,6 +186,21 @@ napi_value Convert2JSValue(napi_env env, const DistributedRdb::ProgressDetail &p return object; } +template<> +napi_value Convert2JSValue(napi_env env, const DistributedRdb::SqlObserver::SqlExecutionInfo &sqlExeInfo) +{ + napi_value object = nullptr; + NAPI_CALL_RETURN_ERR(napi_create_object(env, &object), object); + + std::vector sql(sqlExeInfo.sql_.begin(), sqlExeInfo.sql_.end()); + NAPI_CALL_RETURN_ERR(SetNamedProperty(env, object, "sql", sql), object); + NAPI_CALL_RETURN_ERR(SetNamedProperty(env, object, "totalTime", sqlExeInfo.totalTime_), object); + NAPI_CALL_RETURN_ERR(SetNamedProperty(env, object, "waitTime", sqlExeInfo.waitTime_), object); + NAPI_CALL_RETURN_ERR(SetNamedProperty(env, object, "prepareTime", sqlExeInfo.prepareTime_), object); + NAPI_CALL_RETURN_ERR(SetNamedProperty(env, object, "executeTime", sqlExeInfo.executeTime_), object); + return object; +} + template<> napi_value Convert2JSValue(napi_env env, const DistributedRdb::Details &details) { @@ -315,6 +332,9 @@ int32_t Convert2Value(napi_env env, napi_value jsValue, RdbConfig &rdbConfig) GetNamedProperty(env, jsValue, "allowRebuild", rdbConfig.allowRebuild, true); ASSERT(OK == status, "get allowRebuild failed.", napi_invalid_arg); + + GetNamedProperty(env, jsValue, "isReadOnly", rdbConfig.isReadOnly, true); + ASSERT(OK == status, "get isReadOnly failed.", napi_invalid_arg); return napi_ok; } @@ -416,12 +436,14 @@ RdbStoreConfig GetRdbStoreConfig(const RdbConfig &rdbConfig, const ContextParam rdbStoreConfig.SetEncryptStatus(rdbConfig.isEncrypt); rdbStoreConfig.SetSearchable(rdbConfig.isSearchable); rdbStoreConfig.SetIsVector(rdbConfig.vector); + rdbConfig.vector ? rdbStoreConfig.SetDBType(DB_VECTOR) : rdbStoreConfig.SetDBType(DB_SQLITE); rdbStoreConfig.SetAutoClean(rdbConfig.isAutoClean); rdbStoreConfig.SetSecurityLevel(rdbConfig.securityLevel); rdbStoreConfig.SetDataGroupId(rdbConfig.dataGroupId); rdbStoreConfig.SetName(rdbConfig.name); rdbStoreConfig.SetCustomDir(rdbConfig.customDir); rdbStoreConfig.SetAllowRebuild(rdbConfig.allowRebuild); + rdbStoreConfig.SetReadOnly(rdbConfig.isReadOnly); if (!param.bundleName.empty()) { rdbStoreConfig.SetBundleName(param.bundleName); 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 b2d800c1..607c510b 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 @@ -15,21 +15,22 @@ #define LOG_TAG "NapiRdbStore" #include "napi_rdb_store.h" +#include #include #include #include -#include #include "js_native_api_types.h" #include "js_utils.h" -#include "napi_rdb_js_utils.h" #include "logger.h" #include "napi_async_call.h" #include "napi_rdb_error.h" +#include "napi_rdb_js_utils.h" #include "napi_rdb_predicates.h" #include "napi_rdb_trace.h" #include "napi_result_set.h" #include "rdb_errno.h" +#include "rdb_sql_statistic.h" #include "securec.h" #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) @@ -204,6 +205,7 @@ Descriptor RdbStoreProxy::GetDescriptors() DECLARE_NAPI_FUNCTION("close", Close), DECLARE_NAPI_FUNCTION("attach", Attach), DECLARE_NAPI_FUNCTION("detach", Detach), +#if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) DECLARE_NAPI_FUNCTION("remoteQuery", RemoteQuery), DECLARE_NAPI_FUNCTION("setDistributedTables", SetDistributedTables), DECLARE_NAPI_FUNCTION("obtainDistributedTableName", ObtainDistributedTableName), @@ -218,6 +220,7 @@ Descriptor RdbStoreProxy::GetDescriptors() DECLARE_NAPI_FUNCTION("lockRow", LockRow), DECLARE_NAPI_FUNCTION("unlockRow", UnlockRow), DECLARE_NAPI_FUNCTION("queryLockedRow", QueryLockedRow), +#endif }; AddSyncFunctions(properties); return properties; @@ -230,9 +233,9 @@ void RdbStoreProxy::AddSyncFunctions(std::vector &prop properties.push_back(DECLARE_NAPI_FUNCTION_WITH_DATA("updateSync", Update, SYNC)); properties.push_back(DECLARE_NAPI_FUNCTION_WITH_DATA("insertSync", Insert, SYNC)); properties.push_back(DECLARE_NAPI_FUNCTION_WITH_DATA("batchInsertSync", BatchInsert, SYNC)); - properties.push_back(DECLARE_NAPI_FUNCTION_WITH_DATA("querySqlSync", QuerySync, SYNC)); + properties.push_back(DECLARE_NAPI_FUNCTION_WITH_DATA("querySqlSync", QueryByStep, SYNC)); properties.push_back(DECLARE_NAPI_FUNCTION_WITH_DATA("executeSync", Execute, SYNC)); - properties.push_back(DECLARE_NAPI_FUNCTION_WITH_DATA("querySync", QuerySync, SYNC)); + properties.push_back(DECLARE_NAPI_FUNCTION_WITH_DATA("querySync", QueryByStep, SYNC)); } void RdbStoreProxy::Init(napi_env env, napi_value exports) @@ -293,6 +296,7 @@ napi_value RdbStoreProxy::NewInstance(napi_env env, std::shared_ptrqueue_ = std::make_shared(env); + proxy->dbType = value->GetDbType(); proxy->SetInstance(std::move(value)); proxy->isSystemAppCalled_ = isSystemAppCalled; return instance; @@ -312,7 +316,8 @@ RdbStoreProxy *GetNativeInstance(napi_env env, napi_value self) int ParserThis(const napi_env &env, const napi_value &self, std::shared_ptr context) { RdbStoreProxy *obj = GetNativeInstance(env, self); - CHECK_RETURN_SET(obj && obj->GetInstance(), std::make_shared("RdbStore", "not nullptr.")); + CHECK_RETURN_SET(obj, std::make_shared("RdbStore", "not nullptr.")); + CHECK_RETURN_SET(obj->GetInstance(), std::make_shared(NativeRdb::E_ALREADY_CLOSED)); context->boundObj = obj; return OK; } @@ -617,7 +622,7 @@ napi_value RdbStoreProxy::Insert(napi_env env, napi_callback_info info) context->SetAction(env, info, input, exec, output); CHECK_RETURN_NULL(!(context->error) || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); + return ASYNC_CALL(env, context); } napi_value RdbStoreProxy::BatchInsert(napi_env env, napi_callback_info info) @@ -641,7 +646,7 @@ napi_value RdbStoreProxy::BatchInsert(napi_env env, napi_callback_info info) context->SetAction(env, info, input, exec, output); CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); + return ASYNC_CALL(env, context); } napi_value RdbStoreProxy::Delete(napi_env env, napi_callback_info info) @@ -670,7 +675,7 @@ napi_value RdbStoreProxy::Delete(napi_env env, napi_callback_info info) context->SetAction(env, info, input, exec, output); CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); + return ASYNC_CALL(env, context); } napi_value RdbStoreProxy::Update(napi_env env, napi_callback_info info) @@ -710,7 +715,7 @@ napi_value RdbStoreProxy::Update(napi_env env, napi_callback_info info) context->SetAction(env, info, input, exec, output); CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); + return ASYNC_CALL(env, context); } napi_value RdbStoreProxy::Query(napi_env env, napi_callback_info info) @@ -747,7 +752,7 @@ napi_value RdbStoreProxy::Query(napi_env env, napi_callback_info info) context->SetAction(env, info, input, exec, output); CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); + return ASYNC_CALL(env, context); } #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) @@ -780,7 +785,7 @@ napi_value RdbStoreProxy::RemoteQuery(napi_env env, napi_callback_info info) context->SetAction(env, info, input, exec, output); CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); + return ASYNC_CALL(env, context); } #endif @@ -799,6 +804,10 @@ napi_value RdbStoreProxy::QuerySql(napi_env env, napi_callback_info info) auto exec = [context]() -> int { RdbStoreProxy *obj = reinterpret_cast(context->boundObj); CHECK_RETURN_ERR(obj != nullptr && obj->GetInstance() != nullptr); + if (obj->dbType == DB_VECTOR) { + context->resultSet = obj->GetInstance()->QueryByStep(context->sql, context->bindArgs); + return (context->resultSet != nullptr) ? E_OK : E_ERROR; + } #if defined(WINDOWS_PLATFORM) || defined(MAC_PLATFORM) || defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM) context->resultSet = obj->GetInstance()->QueryByStep(context->sql, context->bindArgs); #else @@ -813,7 +822,7 @@ napi_value RdbStoreProxy::QuerySql(napi_env env, napi_callback_info info) context->SetAction(env, info, input, exec, output); CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); + return ASYNC_CALL(env, context); } napi_value RdbStoreProxy::ExecuteSql(napi_env env, napi_callback_info info) @@ -839,7 +848,7 @@ napi_value RdbStoreProxy::ExecuteSql(napi_env env, napi_callback_info info) context->SetAction(env, info, input, exec, output); CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); + return ASYNC_CALL(env, context); } napi_value RdbStoreProxy::Execute(napi_env env, napi_callback_info info) @@ -878,7 +887,7 @@ napi_value RdbStoreProxy::Execute(napi_env env, napi_callback_info info) context->SetAction(env, info, input, exec, output); CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); + return ASYNC_CALL(env, context); } napi_value RdbStoreProxy::Count(napi_env env, napi_callback_info info) @@ -902,7 +911,7 @@ napi_value RdbStoreProxy::Count(napi_env env, napi_callback_info info) context->SetAction(env, info, input, exec, output); CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); + return ASYNC_CALL(env, context); } napi_value RdbStoreProxy::Replace(napi_env env, napi_callback_info info) @@ -926,7 +935,7 @@ napi_value RdbStoreProxy::Replace(napi_env env, napi_callback_info info) context->SetAction(env, info, input, exec, output); CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); + return ASYNC_CALL(env, context); } napi_value RdbStoreProxy::Backup(napi_env env, napi_callback_info info) @@ -949,7 +958,7 @@ napi_value RdbStoreProxy::Backup(napi_env env, napi_callback_info info) context->SetAction(env, info, input, exec, output); CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); + return ASYNC_CALL(env, context); } struct AttachContext : public ContextBase { @@ -1011,7 +1020,7 @@ napi_value RdbStoreProxy::Attach(napi_env env, napi_callback_info info) context->SetAction(env, info, input, exec, output); CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); + return ASYNC_CALL(env, context); } napi_value RdbStoreProxy::Detach(napi_env env, napi_callback_info info) @@ -1051,7 +1060,7 @@ napi_value RdbStoreProxy::Detach(napi_env env, napi_callback_info info) context->SetAction(env, info, input, exec, output); CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); + return ASYNC_CALL(env, context); } napi_value RdbStoreProxy::IsReadOnly(napi_env env, napi_callback_info info) @@ -1095,8 +1104,9 @@ napi_value RdbStoreProxy::BeginTransaction(napi_env env, napi_callback_info info napi_value thisObj = nullptr; NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisObj, nullptr)); RdbStoreProxy *rdbStoreProxy = GetNativeInstance(env, thisObj); + RDB_NAPI_ASSERT(env, rdbStoreProxy != nullptr, std::make_shared("RdbStore", "valid")); RDB_NAPI_ASSERT( - env, rdbStoreProxy && rdbStoreProxy->GetInstance(), std::make_shared("RdbStore", "valid")); + env, rdbStoreProxy->GetInstance() != nullptr, std::make_shared(NativeRdb::E_ALREADY_CLOSED)); int errCode = rdbStoreProxy->GetInstance()->BeginTransaction(); RDB_NAPI_ASSERT(env, errCode == E_OK, std::make_shared(errCode)); LOG_DEBUG("RdbStoreProxy::BeginTransaction end, errCode is:%{public}d", errCode); @@ -1125,7 +1135,7 @@ napi_value RdbStoreProxy::BeginTrans(napi_env env, napi_callback_info info) context->SetAction(env, info, input, exec, output); CHECK_RETURN_NULL(!(context->error) || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); + return ASYNC_CALL(env, context); } napi_value RdbStoreProxy::RollBack(napi_env env, napi_callback_info info) @@ -1133,8 +1143,9 @@ napi_value RdbStoreProxy::RollBack(napi_env env, napi_callback_info info) napi_value thisObj = nullptr; NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisObj, nullptr)); RdbStoreProxy *rdbStoreProxy = GetNativeInstance(env, thisObj); + RDB_NAPI_ASSERT(env, rdbStoreProxy != nullptr, std::make_shared("RdbStore", "valid")); RDB_NAPI_ASSERT( - env, rdbStoreProxy && rdbStoreProxy->GetInstance(), std::make_shared("RdbStore", "valid")); + env, rdbStoreProxy->GetInstance() != nullptr, std::make_shared(NativeRdb::E_ALREADY_CLOSED)); int errCode = rdbStoreProxy->GetInstance()->RollBack(); NAPI_ASSERT(env, errCode == E_OK, "call RollBack failed"); LOG_DEBUG("RdbStoreProxy::RollBack end, errCode is:%{public}d", errCode); @@ -1164,7 +1175,7 @@ napi_value RdbStoreProxy::RollBackByTxId(napi_env env, napi_callback_info info) context->SetAction(env, info, input, exec, output); CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); + return ASYNC_CALL(env, context); } napi_value RdbStoreProxy::Commit(napi_env env, napi_callback_info info) @@ -1176,8 +1187,9 @@ napi_value RdbStoreProxy::Commit(napi_env env, napi_callback_info info) RDB_NAPI_ASSERT( env, status == napi_ok && (argc == 0 || argc == 1), std::make_shared("parameter", "1 to 2")); RdbStoreProxy *rdbStoreProxy = GetNativeInstance(env, thisObj); + RDB_NAPI_ASSERT(env, rdbStoreProxy != nullptr, std::make_shared("RdbStore", "valid")); RDB_NAPI_ASSERT( - env, rdbStoreProxy && rdbStoreProxy->GetInstance(), std::make_shared("RdbStore", "valid")); + env, rdbStoreProxy->GetInstance() != nullptr, std::make_shared(NativeRdb::E_ALREADY_CLOSED)); if (argc == 0) { int errCode = rdbStoreProxy->GetInstance()->Commit(); NAPI_ASSERT(env, errCode == E_OK, "call Commit failed"); @@ -1204,10 +1216,10 @@ napi_value RdbStoreProxy::Commit(napi_env env, napi_callback_info info) context->SetAction(env, info, input, exec, output); CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); + return ASYNC_CALL(env, context); } -napi_value RdbStoreProxy::QuerySync(napi_env env, napi_callback_info info) +napi_value RdbStoreProxy::QueryByStep(napi_env env, napi_callback_info info) { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); auto context = std::make_shared(); @@ -1240,37 +1252,8 @@ napi_value RdbStoreProxy::QuerySync(napi_env env, napi_callback_info info) CHECK_RETURN_SET_E(result != nullptr, std::make_shared(E_ERROR)); }; context->SetAction(env, info, input, exec, output); - CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); -} - -napi_value RdbStoreProxy::QueryByStep(napi_env env, napi_callback_info info) -{ - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); - auto context = std::make_shared(); - auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { - CHECK_RETURN_SET_E(argc == 1 || argc == 2, std::make_shared("2 or 3")); - CHECK_RETURN(OK == ParserThis(env, self, context)); - CHECK_RETURN(OK == ParseSql(env, argv[0], context)); - if (argc == 2) { - CHECK_RETURN(OK == ParseBindArgs(env, argv[1], context)); - } - }; - auto exec = [context]() -> int { - RdbStoreProxy *obj = reinterpret_cast(context->boundObj); - CHECK_RETURN_ERR(obj != nullptr && obj->GetInstance() != nullptr); - context->resultSet = obj->GetInstance()->QueryByStep(context->sql, context->bindArgs); - return (context->resultSet != nullptr) ? E_OK : E_ERROR; - }; - auto output = [context](napi_env env, napi_value &result) { - result = ResultSetProxy::NewInstance(env, context->resultSet); - CHECK_RETURN_SET_E(result != nullptr, std::make_shared(E_ERROR)); - }; - context->SetAction(env, info, input, exec, output); - - CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); + return ASYNC_CALL(env, context); } napi_value RdbStoreProxy::IsInTransaction(napi_env env, napi_callback_info info) @@ -1306,6 +1289,7 @@ napi_value RdbStoreProxy::GetVersion(napi_env env, napi_callback_info info) env, rdbStoreProxy && rdbStoreProxy->GetInstance(), std::make_shared("RdbStore", "valid")); int32_t version = 0; int out = rdbStoreProxy->GetInstance()->GetVersion(version); + RDB_NAPI_ASSERT(env, out == E_OK, std::make_shared(out)); LOG_DEBUG("RdbStoreProxy::GetVersion out is : %{public}d", out); return JSUtils::Convert2JSValue(env, version); } @@ -1335,6 +1319,7 @@ napi_value RdbStoreProxy::SetVersion(napi_env env, napi_callback_info info) napi_get_value_int32(env, args[0], &version); RDB_NAPI_ASSERT(env, version > 0, std::make_shared("version", "> 0")); int out = rdbStoreProxy->GetInstance()->SetVersion(version); + RDB_NAPI_ASSERT(env, out == E_OK, std::make_shared(out)); LOG_DEBUG("RdbStoreProxy::SetVersion out is : %{public}d", out); return nullptr; } @@ -1362,7 +1347,7 @@ napi_value RdbStoreProxy::Restore(napi_env env, napi_callback_info info) context->SetAction(env, info, input, exec, output); CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); + return ASYNC_CALL(env, context); } #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) @@ -1392,7 +1377,7 @@ napi_value RdbStoreProxy::SetDistributedTables(napi_env env, napi_callback_info context->SetAction(env, info, input, exec, output); CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); + return ASYNC_CALL(env, context); } napi_value RdbStoreProxy::ObtainDistributedTableName(napi_env env, napi_callback_info info) @@ -1423,7 +1408,7 @@ napi_value RdbStoreProxy::ObtainDistributedTableName(napi_env env, napi_callback context->SetAction(env, info, input, exec, output); CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); + return ASYNC_CALL(env, context); } napi_value RdbStoreProxy::Sync(napi_env env, napi_callback_info info) @@ -1455,7 +1440,7 @@ napi_value RdbStoreProxy::Sync(napi_env env, napi_callback_info info) context->SetAction(env, info, input, exec, output); CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); + return ASYNC_CALL(env, context); } InputAction GetCloudSyncInput(std::shared_ptr context) @@ -1527,7 +1512,7 @@ napi_value RdbStoreProxy::CloudSync(napi_env env, napi_callback_info info) }; context->SetAll(env, info, input, exec, output); CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); + return ASYNC_CALL(env, context); } napi_value RdbStoreProxy::GetModifyTime(napi_env env, napi_callback_info info) @@ -1556,7 +1541,7 @@ napi_value RdbStoreProxy::GetModifyTime(napi_env env, napi_callback_info info) context->SetAction(env, info, input, exec, output); CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); + return ASYNC_CALL(env, context); } napi_value RdbStoreProxy::CleanDirtyData(napi_env env, napi_callback_info info) @@ -1585,7 +1570,7 @@ napi_value RdbStoreProxy::CleanDirtyData(napi_env env, napi_callback_info info) context->SetAction(env, info, input, exec, output); CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); + return ASYNC_CALL(env, context); } napi_value RdbStoreProxy::OnRemote(napi_env env, size_t argc, napi_value *argv) @@ -1609,7 +1594,8 @@ napi_value RdbStoreProxy::OnRemote(napi_env env, size_t argc, napi_value *argv) SubscribeOption option; option.mode = static_cast(mode); option.event = "dataChange"; - auto observer = std::make_shared(env, argv[1], mode); + auto uvQueue = std::make_shared(env); + auto observer = std::make_shared(argv[1], uvQueue, mode); int errCode = E_OK; if (option.mode == SubscribeMode::LOCAL_DETAIL) { errCode = GetInstance()->SubscribeObserver(option, observer); @@ -1635,7 +1621,8 @@ napi_value RdbStoreProxy::RegisteredObserver(napi_env env, const DistributedRdb: return nullptr; } - auto localObserver = std::make_shared(env, callback); + auto uvQueue = std::make_shared(env); + auto localObserver = std::make_shared(callback, uvQueue); int errCode = GetInstance()->Subscribe(option, localObserver.get()); RDB_NAPI_ASSERT(env, errCode == E_OK, std::make_shared(errCode)); observers[option.event].push_back(localObserver); @@ -1687,6 +1674,7 @@ napi_value RdbStoreProxy::OffRemote(napi_env env, size_t argc, napi_value *argv) errCode = GetInstance()->UnSubscribe(option, it->get()); } RDB_NAPI_ASSERT(env, errCode == E_OK, std::make_shared(errCode)); + (*it)->Clear(); it = observers_[mode].erase(it); LOG_DEBUG("observer unsubscribe success"); } @@ -1743,6 +1731,7 @@ napi_value RdbStoreProxy::OnEvent(napi_env env, napi_callback_info info) auto proxy = GetNativeInstance(env, self); RDB_NAPI_ASSERT(env, proxy != nullptr, std::make_shared("RdbStore", "valid")); + RDB_NAPI_ASSERT(env, proxy->GetInstance() != nullptr, std::make_shared(NativeRdb::E_ALREADY_CLOSED)); std::string event; // 'argv[0]' represents a event @@ -1781,6 +1770,7 @@ napi_value RdbStoreProxy::OffEvent(napi_env env, napi_callback_info info) auto proxy = GetNativeInstance(env, self); RDB_NAPI_ASSERT(env, proxy != nullptr, std::make_shared("RdbStore", "valid")); + RDB_NAPI_ASSERT(env, proxy->GetInstance() != nullptr, std::make_shared(NativeRdb::E_ALREADY_CLOSED)); std::string event; status = JSUtils::Convert2Value(env, argv[0], event); @@ -1818,8 +1808,9 @@ napi_value RdbStoreProxy::Notify(napi_env env, napi_callback_info info) napi_status status = napi_get_cb_info(env, info, &argc, argv, &self, nullptr); RDB_NAPI_ASSERT(env, status == napi_ok && argc == 1, std::make_shared("1")); auto *proxy = GetNativeInstance(env, self); - RDB_NAPI_ASSERT(env, proxy != nullptr && proxy->GetInstance() != nullptr, - std::make_shared("RdbStore", "valid")); + RDB_NAPI_ASSERT(env, proxy != nullptr, std::make_shared("RdbStore", "valid")); + RDB_NAPI_ASSERT( + env, proxy->GetInstance() != nullptr, std::make_shared(NativeRdb::E_ALREADY_CLOSED)); int errCode = proxy->GetInstance()->Notify(JSUtils::Convert2String(env, argv[0])); RDB_NAPI_ASSERT(env, errCode == E_OK, std::make_shared(errCode)); return nullptr; @@ -1858,7 +1849,7 @@ napi_value RdbStoreProxy::QuerySharingResource(napi_env env, napi_callback_info context->SetAction(env, info, input, exec, output); CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); + return ASYNC_CALL(env, context); } napi_value RdbStoreProxy::RegisterSyncCallback(napi_env env, size_t argc, napi_value *argv) @@ -1867,7 +1858,7 @@ napi_value RdbStoreProxy::RegisterSyncCallback(napi_env env, size_t argc, napi_v napi_typeof(env, argv[0], &type); RDB_NAPI_ASSERT(env, type == napi_function, std::make_shared("progress", "function")); bool result = std::any_of(syncObservers_.begin(), syncObservers_.end(), [argv](const auto &observer) { - return *observer == argv[1]; + return *observer == argv[0]; }); if (result) { LOG_DEBUG("duplicate subscribe"); @@ -1895,19 +1886,110 @@ napi_value RdbStoreProxy::UnregisterSyncCallback(napi_env env, size_t argc, napi it = syncObservers_.erase(it); continue; } - if (isNotNull && !(**it == argv[1])) { + if (isNotNull && !(**it == argv[0])) { ++it; continue; } int errCode = GetInstance()->UnregisterAutoSyncCallback(*it); RDB_NAPI_ASSERT(env, errCode == E_OK, std::make_shared(errCode)); + (*it)->Clear(); it = syncObservers_.erase(it); LOG_DEBUG("observer unsubscribe success"); } return nullptr; } +napi_value RdbStoreProxy::OnStatistics(napi_env env, size_t argc, napi_value *argv) +{ + napi_valuetype type = napi_undefined; + napi_typeof(env, argv[0], &type); + RDB_NAPI_ASSERT(env, type == napi_function, std::make_shared("statistics", "function")); + bool result = std::any_of(statisticses_.begin(), statisticses_.end(), + [argv](std::shared_ptr obs) { return obs && *obs == argv[0]; }); + if (result) { + LOG_DEBUG("duplicate subscribe"); + return nullptr; + } + auto observer = std::make_shared(env, argv[0], queue_); + int errCode = DistributedRdb::SqlStatistic::Subscribe(observer); + RDB_NAPI_ASSERT(env, errCode == E_OK, std::make_shared(errCode)); + statisticses_.push_back(std::move(observer)); + LOG_DEBUG("statistics subscribe success"); + return nullptr; +} + +napi_value RdbStoreProxy::OffStatistics(napi_env env, size_t argc, napi_value *argv) +{ + napi_valuetype type; + napi_typeof(env, argv[0], &type); + RDB_NAPI_ASSERT(env, type == napi_function || type == napi_undefined || type == napi_null, + std::make_shared("statistics", "function")); + + auto it = statisticses_.begin(); + while (it != statisticses_.end()) { + if (*it == nullptr) { + it = statisticses_.erase(it); + LOG_WARN("statisticsObserver is nullptr."); + continue; + } + if (type == napi_function && !(**it == argv[0])) { + ++it; + continue; + } + int errCode = DistributedRdb::SqlStatistic::Unsubscribe(*it); + RDB_NAPI_ASSERT(env, errCode == E_OK, std::make_shared(errCode)); + (*it)->Clear(); + it = statisticses_.erase(it); + } + return nullptr; +} + +RdbStoreProxy::NapiStatisticsObserver::NapiStatisticsObserver( + napi_env env, napi_value callback, std::shared_ptr queue) + : env_(env), queue_(queue) +{ + napi_create_reference(env, callback, 1, &callback_); +} + +RdbStoreProxy::NapiStatisticsObserver::~NapiStatisticsObserver() +{ +} + +void RdbStoreProxy::NapiStatisticsObserver::Clear() +{ + if (callback_ == nullptr) { + return; + } + napi_delete_reference(env_, callback_); + callback_ = nullptr; +} + +bool RdbStoreProxy::NapiStatisticsObserver::operator==(napi_value value) +{ + return JSUtils::Equal(env_, callback_, value); +} + +void RdbStoreProxy::NapiStatisticsObserver::OnStatistic(const SqlExecutionInfo &sqlExeInfo) +{ + auto queue = queue_; + if (queue == nullptr) { + return; + } + queue->AsyncCall({ [observer = shared_from_this()](napi_env env) -> napi_value { + if (observer->callback_ == nullptr) { + return nullptr; + } + napi_value callback = nullptr; + napi_get_reference_value(env, observer->callback_, &callback); + return callback; + } }, + [infos = std::move(sqlExeInfo)](napi_env env, int &argc, napi_value *argv) { + argc = 1; + argv[0] = JSUtils::Convert2JSValue(env, infos); + }); +} + RdbStoreProxy::SyncObserver::SyncObserver( napi_env env, napi_value callback, std::shared_ptr queue) : env_(env), queue_(queue) @@ -1917,9 +1999,15 @@ RdbStoreProxy::SyncObserver::SyncObserver( RdbStoreProxy::SyncObserver::~SyncObserver() { - if (env_ != nullptr && callback_ != nullptr) { - napi_delete_reference(env_, callback_); +} + +void RdbStoreProxy::SyncObserver::Clear() +{ + if (callback_ == nullptr) { + return; } + napi_delete_reference(env_, callback_); + callback_ = nullptr; } bool RdbStoreProxy::SyncObserver::operator==(napi_value value) @@ -1962,7 +2050,7 @@ napi_value RdbStoreProxy::ModifyLockStatus(napi_env env, napi_callback_info info context->SetAction(env, info, input, exec, output); CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); + return ASYNC_CALL(env, context); } napi_value RdbStoreProxy::LockRow(napi_env env, napi_callback_info info) @@ -2003,25 +2091,22 @@ napi_value RdbStoreProxy::QueryLockedRow(napi_env env, napi_callback_info info) context->SetAction(env, info, input, exec, output); CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); + return ASYNC_CALL(env, context); } #endif + napi_value RdbStoreProxy::Close(napi_env env, napi_callback_info info) { auto context = std::make_shared(); auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { CHECK_RETURN(OK == ParserThis(env, self, context)); }; - ExecuteAction exec; - RdbStoreProxy *obj = reinterpret_cast(context->boundObj); - if (obj != nullptr) { - auto store = obj->GetInstance(); + auto exec = [context]() -> int { + RdbStoreProxy *obj = reinterpret_cast(context->boundObj); + CHECK_RETURN_ERR(obj != nullptr && obj->GetInstance() != nullptr); obj->SetInstance(nullptr); - exec = [context, store]() mutable -> int { - store = nullptr; - return OK; - }; - } + return OK; + }; auto output = [context](napi_env env, napi_value &result) { napi_status status = napi_get_undefined(env, &result); CHECK_RETURN_SET_E(status == napi_ok, std::make_shared(E_ERROR)); @@ -2029,7 +2114,7 @@ napi_value RdbStoreProxy::Close(napi_env env, napi_callback_info info) context->SetAction(env, info, input, exec, output); CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); + return ASYNC_CALL(env, context); } } // namespace RelationalStoreJsKit } // namespace OHOS diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store_helper.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store_helper.cpp index 19dcc451..a5f1f78b 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 @@ -84,7 +84,7 @@ napi_value GetRdbStore(napi_env env, napi_callback_info info) context->SetAction(env, info, input, exec, output); CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); + return ASYNC_CALL(env, context); } napi_value DeleteRdbStore(napi_env env, napi_callback_info info) @@ -120,7 +120,7 @@ napi_value DeleteRdbStore(napi_env env, napi_callback_info info) context->SetAction(env, info, input, exec, output); CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); - return AsyncCall::Call(env, context); + return ASYNC_CALL(env, context); } napi_value InitRdbHelper(napi_env env, napi_value exports) diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store_observer.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store_observer.cpp index 362e9b74..669ade03 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store_observer.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store_observer.cpp @@ -12,9 +12,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #define LOG_TAG "NapiRdbStoreObserver" + #include "napi_rdb_store_observer.h" +#include "js_native_api_types.h" #include "js_utils.h" #include "logger.h" @@ -22,9 +25,10 @@ using namespace OHOS::Rdb; using namespace OHOS::AppDataMgrJsKit; namespace OHOS::RelationalStoreJsKit { -NapiRdbStoreObserver::NapiRdbStoreObserver(napi_env env, napi_value callback, int32_t mode) - : NapiUvQueue(env, callback), mode_(mode) +NapiRdbStoreObserver::NapiRdbStoreObserver(napi_value callback, std::shared_ptr uvQueue, int32_t mode) + : mode_(mode), uvQueue_(uvQueue) { + napi_create_reference(uvQueue_->GetEnv(), callback, 1, &callback_); } NapiRdbStoreObserver::~NapiRdbStoreObserver() noexcept @@ -34,33 +38,72 @@ NapiRdbStoreObserver::~NapiRdbStoreObserver() noexcept void NapiRdbStoreObserver::OnChange(const std::vector &devices) { LOG_INFO("NapiRdbStoreObserver::OnChange begin"); - CallFunction([devices](napi_env env, int &argc, napi_value *argv) { - argc = 1; - argv[0] = JSUtils::Convert2JSValue(env, devices); - }); + auto uvQueue = uvQueue_; + if (uvQueue == nullptr) { + return; + } + uvQueue->AsyncCall({ [observer = shared_from_this()](napi_env env) -> napi_value { + if (observer->callback_ == nullptr) { + return nullptr; + } + napi_value callback = nullptr; + napi_get_reference_value(env, observer->callback_, &callback); + return callback; + } }, + [devices](napi_env env, int &argc, napi_value *argv) { + argc = 1; + argv[0] = JSUtils::Convert2JSValue(env, devices); + }); } void NapiRdbStoreObserver::OnChange(const Origin &origin, const PrimaryFields &fields, ChangeInfo &&changeInfo) { - if (mode_ == DistributedRdb::CLOUD_DETAIL || mode_ == DistributedRdb::LOCAL_DETAIL) { - std::vector infos; - for (auto it = changeInfo.begin(); it != changeInfo.end(); ++it) { - infos.push_back(JSChangeInfo(origin, it)); + if (mode_ != DistributedRdb::CLOUD_DETAIL && mode_ != DistributedRdb::LOCAL_DETAIL) { + RdbStoreObserver::OnChange(origin, fields, std::move(changeInfo)); + return; + } + std::vector infos; + for (auto it = changeInfo.begin(); it != changeInfo.end(); ++it) { + infos.push_back(JSChangeInfo(origin, it)); + } + + auto uvQueue = uvQueue_; + if (uvQueue == nullptr) { + return; + } + + uvQueue->AsyncCall({ [observer = shared_from_this()](napi_env env) -> napi_value { + if (observer->callback_ == nullptr) { + return nullptr; } - CallFunction([infos = std::move(infos)](napi_env env, int &argc, napi_value *argv) { + napi_value callback = nullptr; + napi_get_reference_value(env, observer->callback_, &callback); + return callback; + } }, + [infos = std::move(infos)](napi_env env, int &argc, napi_value *argv) { argc = 1; argv[0] = JSUtils::Convert2JSValue(env, infos); }); - return; - } - RdbStoreObserver::OnChange(origin, fields, std::move(changeInfo)); } void NapiRdbStoreObserver::OnChange() { - CallFunction([](napi_env env, int &argc, napi_value *argv) {}); + auto uvQueue = uvQueue_; + if (uvQueue == nullptr) { + return; + } + uvQueue->AsyncCall({ [observer = shared_from_this()](napi_env env) -> napi_value { + if (observer->callback_ == nullptr) { + return nullptr; + } + napi_value callback = nullptr; + napi_get_reference_value(env, observer->callback_, &callback); + return callback; + } }, + [](napi_env env, int &argc, napi_value *argv) {}); } + NapiRdbStoreObserver::JSChangeInfo::JSChangeInfo(const Origin &origin, ChangeInfo::iterator info) { table = info->first; @@ -69,4 +112,29 @@ NapiRdbStoreObserver::JSChangeInfo::JSChangeInfo(const Origin &origin, ChangeInf updated = std::move(info->second[CHG_TYPE_UPDATE]); deleted = std::move(info->second[CHG_TYPE_DELETE]); } + +bool NapiRdbStoreObserver::operator==(napi_value value) +{ + napi_value callback = nullptr; + napi_status status = napi_get_reference_value(uvQueue_->GetEnv(), callback_, &callback); + if (status != napi_ok) { + LOG_ERROR("call napi_get_reference_value failed status[%{public}d].", status); + } + + bool isEquals = false; + status = napi_strict_equals(uvQueue_->GetEnv(), value, callback, &isEquals); + if (status != napi_ok) { + LOG_ERROR("call napi_strict_equals failed status[%{public}d].", status); + } + return isEquals; +} + +void NapiRdbStoreObserver::Clear() +{ + if (callback_ == nullptr) { + return; + } + napi_delete_reference(uvQueue_->GetEnv(), callback_); + callback_ = nullptr; +} } // namespace OHOS::RelationalStoreJsKit \ No newline at end of file diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_result_set.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_result_set.cpp index f0d028aa..ef692ce4 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_result_set.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_result_set.cpp @@ -65,13 +65,16 @@ napi_value ResultSetProxy::NewInstance(napi_env env, std::shared_ptr ResultSetProxy::Create() { - if (GetInstance() == nullptr) { + auto instance = GetInstance(); + if (instance == nullptr) { LOG_ERROR("resultSet is null"); return nullptr; } - return std::make_shared(GetInstance()); + SetInstance(nullptr); + return std::make_shared(instance); } #endif + napi_value ResultSetProxy::Initialize(napi_env env, napi_callback_info info) { napi_value self = nullptr; @@ -171,6 +174,7 @@ ResultSetProxy *ResultSetProxy::ParseFieldByName( napi_value ResultSetProxy::GetAllColumnNames(napi_env env, napi_callback_info info) { + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); ResultSetProxy *resultSetProxy = GetInnerResultSet(env, info); CHECK_RETURN_NULL(resultSetProxy && resultSetProxy->GetInstance()); @@ -185,6 +189,7 @@ napi_value ResultSetProxy::GetAllColumnNames(napi_env env, napi_callback_info in napi_value ResultSetProxy::GetColumnCount(napi_env env, napi_callback_info info) { + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); ResultSetProxy *resultSetProxy = GetInnerResultSet(env, info); CHECK_RETURN_NULL(resultSetProxy && resultSetProxy->GetInstance()); @@ -199,6 +204,7 @@ napi_value ResultSetProxy::GetColumnCount(napi_env env, napi_callback_info info) napi_value ResultSetProxy::GetColumnType(napi_env env, napi_callback_info info) { + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); int32_t columnIndex; auto resultSetProxy = ParseInt32FieldByName(env, info, columnIndex, "columnIndex"); CHECK_RETURN_NULL(resultSetProxy && resultSetProxy->GetInstance()); @@ -214,6 +220,7 @@ napi_value ResultSetProxy::GetColumnType(napi_env env, napi_callback_info info) napi_value ResultSetProxy::GetRowCount(napi_env env, napi_callback_info info) { + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); ResultSetProxy *resultSetProxy = GetInnerResultSet(env, info); CHECK_RETURN_NULL(resultSetProxy && resultSetProxy->GetInstance()); @@ -228,6 +235,7 @@ napi_value ResultSetProxy::GetRowCount(napi_env env, napi_callback_info info) napi_value ResultSetProxy::GetRowIndex(napi_env env, napi_callback_info info) { + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); ResultSetProxy *resultSetProxy = GetInnerResultSet(env, info); CHECK_RETURN_NULL(resultSetProxy && resultSetProxy->GetInstance()); @@ -242,21 +250,18 @@ napi_value ResultSetProxy::GetRowIndex(napi_env env, napi_callback_info info) napi_value ResultSetProxy::IsEnded(napi_env env, napi_callback_info info) { + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); ResultSetProxy *resultSetProxy = GetInnerResultSet(env, info); CHECK_RETURN_NULL(resultSetProxy && resultSetProxy->GetInstance()); - bool result = false; - int errCode = resultSetProxy->GetInstance()->IsEnded(result); - if (errCode != E_OK) { - LOG_ERROR("IsEnded failed code:%{public}d", errCode); - result = true; - } + resultSetProxy->GetInstance()->IsEnded(result); return JSUtils::Convert2JSValue(env, result); } napi_value ResultSetProxy::IsBegin(napi_env env, napi_callback_info info) { + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); ResultSetProxy *resultSetProxy = GetInnerResultSet(env, info); CHECK_RETURN_NULL(resultSetProxy && resultSetProxy->GetInstance()); @@ -271,6 +276,7 @@ napi_value ResultSetProxy::IsBegin(napi_env env, napi_callback_info info) napi_value ResultSetProxy::IsAtFirstRow(napi_env env, napi_callback_info info) { + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); ResultSetProxy *resultSetProxy = GetInnerResultSet(env, info); CHECK_RETURN_NULL(resultSetProxy && resultSetProxy->GetInstance()); @@ -285,6 +291,7 @@ napi_value ResultSetProxy::IsAtFirstRow(napi_env env, napi_callback_info info) napi_value ResultSetProxy::IsAtLastRow(napi_env env, napi_callback_info info) { + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); ResultSetProxy *resultSetProxy = GetInnerResultSet(env, info); CHECK_RETURN_NULL(resultSetProxy && resultSetProxy->GetInstance()); @@ -299,6 +306,7 @@ napi_value ResultSetProxy::IsAtLastRow(napi_env env, napi_callback_info info) napi_value ResultSetProxy::Close(napi_env env, napi_callback_info info) { + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); ResultSetProxy *resultSetProxy = GetInnerResultSet(env, info); CHECK_RETURN_NULL(resultSetProxy && resultSetProxy->GetInstance()); @@ -311,6 +319,7 @@ napi_value ResultSetProxy::Close(napi_env env, napi_callback_info info) napi_value ResultSetProxy::GoToRow(napi_env env, napi_callback_info info) { + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); int32_t position; auto resultSetProxy = ParseInt32FieldByName(env, info, position, "position"); CHECK_RETURN_NULL(resultSetProxy && resultSetProxy->GetInstance()); @@ -321,6 +330,7 @@ napi_value ResultSetProxy::GoToRow(napi_env env, napi_callback_info info) napi_value ResultSetProxy::GoTo(napi_env env, napi_callback_info info) { + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); int32_t offset; auto resultSetProxy = ParseInt32FieldByName(env, info, offset, "offset"); CHECK_RETURN_NULL(resultSetProxy && resultSetProxy->GetInstance()); @@ -331,6 +341,7 @@ napi_value ResultSetProxy::GoTo(napi_env env, napi_callback_info info) napi_value ResultSetProxy::GoToFirstRow(napi_env env, napi_callback_info info) { + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); ResultSetProxy *resultSetProxy = GetInnerResultSet(env, info); CHECK_RETURN_NULL(resultSetProxy && resultSetProxy->GetInstance()); @@ -340,6 +351,7 @@ napi_value ResultSetProxy::GoToFirstRow(napi_env env, napi_callback_info info) napi_value ResultSetProxy::GoToLastRow(napi_env env, napi_callback_info info) { + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); ResultSetProxy *resultSetProxy = GetInnerResultSet(env, info); CHECK_RETURN_NULL(resultSetProxy && resultSetProxy->GetInstance()); @@ -349,6 +361,7 @@ napi_value ResultSetProxy::GoToLastRow(napi_env env, napi_callback_info info) napi_value ResultSetProxy::GoToNextRow(napi_env env, napi_callback_info info) { + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); ResultSetProxy *resultSetProxy = GetInnerResultSet(env, info); CHECK_RETURN_NULL(resultSetProxy && resultSetProxy->GetInstance()); @@ -358,6 +371,7 @@ napi_value ResultSetProxy::GoToNextRow(napi_env env, napi_callback_info info) napi_value ResultSetProxy::GoToPreviousRow(napi_env env, napi_callback_info info) { + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); ResultSetProxy *resultSetProxy = GetInnerResultSet(env, info); CHECK_RETURN_NULL(resultSetProxy && resultSetProxy->GetInstance()); @@ -367,6 +381,7 @@ napi_value ResultSetProxy::GoToPreviousRow(napi_env env, napi_callback_info info napi_value ResultSetProxy::GetInt(napi_env env, napi_callback_info info) { + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); int32_t columnIndex; auto resultSetProxy = ParseInt32FieldByName(env, info, columnIndex, "columnIndex"); CHECK_RETURN_NULL(resultSetProxy && resultSetProxy->GetInstance()); @@ -380,6 +395,7 @@ napi_value ResultSetProxy::GetInt(napi_env env, napi_callback_info info) napi_value ResultSetProxy::GetLong(napi_env env, napi_callback_info info) { + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); int32_t columnIndex; auto resultSetProxy = ParseInt32FieldByName(env, info, columnIndex, "columnIndex"); CHECK_RETURN_NULL(resultSetProxy && resultSetProxy->GetInstance()); @@ -474,6 +490,7 @@ napi_value ResultSetProxy::GetString(napi_env env, napi_callback_info info) napi_value ResultSetProxy::GetDouble(napi_env env, napi_callback_info info) { + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); int32_t columnIndex; auto resultSetProxy = ParseInt32FieldByName(env, info, columnIndex, "columnIndex"); CHECK_RETURN_NULL(resultSetProxy && resultSetProxy->GetInstance()); @@ -487,6 +504,7 @@ napi_value ResultSetProxy::GetDouble(napi_env env, napi_callback_info info) napi_value ResultSetProxy::GetColumnIndex(napi_env env, napi_callback_info info) { + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); std::string input; auto resultSetProxy = ParseFieldByName(env, info, input, "columnName"); CHECK_RETURN_NULL(resultSetProxy && resultSetProxy->GetInstance()); @@ -498,6 +516,7 @@ napi_value ResultSetProxy::GetColumnIndex(napi_env env, napi_callback_info info) napi_value ResultSetProxy::GetColumnName(napi_env env, napi_callback_info info) { + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); int32_t columnIndex; auto resultSetProxy = ParseInt32FieldByName(env, info, columnIndex, "columnIndex"); CHECK_RETURN_NULL(resultSetProxy && resultSetProxy->GetInstance()); @@ -513,6 +532,7 @@ napi_value ResultSetProxy::GetColumnName(napi_env env, napi_callback_info info) napi_value ResultSetProxy::IsColumnNull(napi_env env, napi_callback_info info) { + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); int32_t columnIndex; auto resultSetProxy = ParseInt32FieldByName(env, info, columnIndex, "columnIndex"); CHECK_RETURN_NULL(resultSetProxy && resultSetProxy->GetInstance()); @@ -526,6 +546,7 @@ napi_value ResultSetProxy::IsColumnNull(napi_env env, napi_callback_info info) napi_value ResultSetProxy::GetRow(napi_env env, napi_callback_info info) { + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); ResultSetProxy *resultSetProxy = GetInnerResultSet(env, info); CHECK_RETURN_NULL(resultSetProxy && resultSetProxy->GetInstance()); @@ -537,6 +558,7 @@ napi_value ResultSetProxy::GetRow(napi_env env, napi_callback_info info) napi_value ResultSetProxy::GetValue(napi_env env, napi_callback_info info) { + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); int32_t columnIndex; auto resultSetProxy = ParseInt32FieldByName(env, info, columnIndex, "columnIndex"); CHECK_RETURN_NULL(resultSetProxy && resultSetProxy->GetInstance()); @@ -549,6 +571,7 @@ napi_value ResultSetProxy::GetValue(napi_env env, napi_callback_info info) napi_value ResultSetProxy::IsClosed(napi_env env, napi_callback_info info) { + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); ResultSetProxy *resultSetProxy = GetInnerResultSet(env, info); CHECK_RETURN_NULL(resultSetProxy && resultSetProxy->GetInstance()); bool result = resultSetProxy->GetInstance()->IsClosed(); diff --git a/relational_store/frameworks/native/appdatafwk/src/shared_block.cpp b/relational_store/frameworks/native/appdatafwk/src/shared_block.cpp index afece3fb..5dc020cd 100644 --- a/relational_store/frameworks/native/appdatafwk/src/shared_block.cpp +++ b/relational_store/frameworks/native/appdatafwk/src/shared_block.cpp @@ -54,6 +54,7 @@ bool SharedBlock::Init() if (mHeader == nullptr) { return false; } + Clear(); return true; } diff --git a/relational_store/frameworks/native/dfx/include/rdb_radar_reporter.h b/relational_store/frameworks/native/dfx/include/rdb_radar_reporter.h new file mode 100644 index 00000000..03e75351 --- /dev/null +++ b/relational_store/frameworks/native/dfx/include/rdb_radar_reporter.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DISTRIBUTEDDATAMGR_RDB_RADAR_REPORTER_H +#define DISTRIBUTEDDATAMGR_RDB_RADAR_REPORTER_H + +#include +namespace OHOS::NativeRdb { + +enum Scene : int { + SCENE_SYNC = 1, +}; + +enum State : int { + STATE_START = 1, + STATE_FINISH = 2, +}; + +enum SyncStage : int { + SYNC_STAGE_RUN = 1, +}; + +enum StageRes : int { + RES_IDLE = 0, + RES_SUCCESS = 1, + RES_FAILED = 2, + RES_CANCELLED = 3, + RES_UNKNOW = 4, +}; + +class RdbRadar { +public: + static constexpr char ORG_PKG_LABEL[] = "ORG_PKG"; + static constexpr char ORG_PKG_VALUE[] = "distributeddata"; + static constexpr char FUNC_LABEL[] = "FUNC"; + static constexpr char BIZ_SCENE_LABEL[] = "BIZ_SCENE"; + static constexpr char BIZ_STATE_LABEL[] = "BIZ_STATE"; + static constexpr char BIZ_STAGE_LABEL[] = "BIZ_STAGE"; + static constexpr char STAGE_RES_LABEL[] = "STAGE_RES"; + static constexpr char ERROR_CODE_LABEL[] = "ERROR_CODE"; + static constexpr char TO_CALL_PKG_LABEL[] = "TO_CALL_PKG"; + static constexpr char HOST_PKG_LABEL[] = "HOST_PKG"; + static constexpr char LOCAL_UUID_LABEL[] = "HOST_PKG"; + static constexpr char PEER_UUID_LABEL[] = "HOST_PKG"; + static constexpr char EVENT_NAME[] = "DISTRIBUTED_RDB_BEHAVIOR"; + static constexpr char HOST_PKG[] = "HOST_PKG"; + static constexpr char UNKNOW[] = "unknow"; + +public: + RdbRadar(Scene scene, const char *funcName, std::string bundleName); + ~RdbRadar(); + + RdbRadar &operator=(int x); + operator int() const; + +private: + int errCode_{ 0 }; + Scene scene_; + const char* funcName_; + + static bool hasHostPkg_; + static std::string hostPkg_; + + void LocalReport(int bizSence, const char *funcName, int state, int errCode = 0); + void GetHostPkgInfo(std::string bundleName); +}; +} // namespace OHOS::NativeRdb +#endif //DISTRIBUTEDDATAMGR_RDB_RADAR_REPORTER_H diff --git a/relational_store/frameworks/native/dfx/src/rdb_radar_reporter.cpp b/relational_store/frameworks/native/dfx/src/rdb_radar_reporter.cpp new file mode 100644 index 00000000..283c5ac8 --- /dev/null +++ b/relational_store/frameworks/native/dfx/src/rdb_radar_reporter.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "rdb_radar_reporter.h" +#include "rdb_errno.h" +#include "hisysevent.h" +#include "ipc_skeleton.h" +#include "accesstoken_kit.h" + +namespace OHOS::NativeRdb { + +using namespace Security::AccessToken; + +bool RdbRadar::hasHostPkg_ = false; +std::string RdbRadar::hostPkg_{ "" }; + +RdbRadar::RdbRadar(Scene scene, const char* funcName, std::string bundleName) : scene_(scene), funcName_(funcName) +{ + if (funcName_ == nullptr) { + funcName_ = UNKNOW; + } + GetHostPkgInfo(bundleName); + LocalReport(scene_, funcName_, STATE_START); +} + +RdbRadar::~RdbRadar() +{ + LocalReport(scene_, funcName_, STATE_FINISH, errCode_); +} + +RdbRadar& RdbRadar::operator=(int errCode) +{ + errCode_ = errCode; + return *this; +} + +RdbRadar::operator int() const +{ + return errCode_; +} + +void RdbRadar::LocalReport(int bizSence, const char* funcName, int state, int errCode) +{ + int stageRes = static_cast(StageRes::RES_SUCCESS); + if (errCode != E_OK) { + stageRes = static_cast(StageRes::RES_FAILED); + } + + HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::DISTRIBUTED_DATAMGR, + RdbRadar::EVENT_NAME, + OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR, + RdbRadar::ORG_PKG_LABEL, RdbRadar::ORG_PKG_VALUE, + RdbRadar::FUNC_LABEL, funcName, + RdbRadar::BIZ_SCENE_LABEL, bizSence, + RdbRadar::BIZ_STAGE_LABEL, SYNC_STAGE_RUN, + RdbRadar::STAGE_RES_LABEL, stageRes, + RdbRadar::ERROR_CODE_LABEL, errCode, + RdbRadar::BIZ_STATE_LABEL, state, + RdbRadar::HOST_PKG, hostPkg_.c_str()); + return; +} + +void RdbRadar::GetHostPkgInfo(std::string bundleName) +{ + if (hasHostPkg_) { + return; + } + auto tokenId = IPCSkeleton::GetCallingTokenID(); + auto tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId); + if ((tokenType == TOKEN_NATIVE) || (tokenType == TOKEN_SHELL)) { + NativeTokenInfo tokenInfo; + if (AccessTokenKit::GetNativeTokenInfo(tokenId, tokenInfo) == 0) { + hostPkg_ = tokenInfo.processName; + hasHostPkg_ = true; + } + } else { + hostPkg_ = bundleName; + hasHostPkg_ = true; + } +} +} \ No newline at end of file diff --git a/relational_store/frameworks/native/rdb/include/connection.h b/relational_store/frameworks/native/rdb/include/connection.h index 6c784870..e0839abe 100644 --- a/relational_store/frameworks/native/rdb/include/connection.h +++ b/relational_store/frameworks/native/rdb/include/connection.h @@ -33,8 +33,14 @@ public: using Stmt = std::shared_ptr; using Notifier = std::function &tables)>; using Creator = std::pair (*)(const RdbStoreConfig &config, bool isWriter); + using Repairer = int32_t (*)(const RdbStoreConfig &config); + using Deleter = void (*)(const RdbStoreConfig &config); static std::pair Create(const RdbStoreConfig &config, bool isWriter); + static int32_t Repair(const RdbStoreConfig &config); + static void DeleteDbFile(const RdbStoreConfig &config); static int32_t RegisterCreator(int32_t dbType, Creator creator); + static int32_t RegisterRepairer(int32_t dbType, Repairer repairer); + static int32_t RegisterFileDeleter(int32_t dbType, Deleter deleter); int32_t SetId(int32_t id); int32_t GetId() const; @@ -51,10 +57,13 @@ public: virtual int32_t SubscribeTableChanges(const Notifier ¬ifier) = 0; virtual int32_t GetMaxVariable() const = 0; virtual int32_t GetJournalMode() = 0; + virtual int32_t ClearCache() = 0; virtual int32_t Subscribe(const std::string &event, const std::shared_ptr &observer) = 0; virtual int32_t Unsubscribe(const std::string &event, const std::shared_ptr &observer) = 0; + virtual int32_t Backup(const std::string &databasePath, const std::vector &destEncryptKey) = 0; + virtual int32_t Restore(const std::string &databasePath, const std::vector &destEncryptKey) = 0; private: int32_t id_ = 0; diff --git a/relational_store/frameworks/native/rdb/include/grd_api_manager.h b/relational_store/frameworks/native/rdb/include/grd_api_manager.h index a9941b52..e0944ee9 100644 --- a/relational_store/frameworks/native/rdb/include/grd_api_manager.h +++ b/relational_store/frameworks/native/rdb/include/grd_api_manager.h @@ -23,6 +23,7 @@ namespace NativeRdb { typedef int32_t (*DBOpen)(const char *dbPath, const char *configStr, uint32_t flags, GRD_DB **db); typedef int32_t (*DBClose)(GRD_DB *db, uint32_t flags); +typedef int32_t (*DBRepair)(const char *dbPath, const char *configStr); typedef int (*DBSqlPrepare)(GRD_DB *db, const char *str, uint32_t strLen, GRD_SqlStmt **stmt, const char **unusedStr); typedef int (*DBSqlReset)(GRD_SqlStmt *stmt); @@ -48,10 +49,15 @@ typedef int (*DBSqlColInt)(GRD_SqlStmt *stmt, uint32_t idx); typedef uint64_t (*DBSqlColInt64)(GRD_SqlStmt *stmt, uint32_t idx); typedef double (*DBSqlColDouble)(GRD_SqlStmt *stmt, uint32_t idx); typedef const float *(*DBSqlColumnFloatVector)(GRD_SqlStmt *stmt, uint32_t idx, uint32_t *dim); +typedef int (*DBBackup) (GRD_DB *db, const char *backupDbFile, uint8_t *encryptedKey, uint32_t encryptedKeyLen); +typedef int (*DBRestore) (GRD_DB *db, const char *backupDbFile, uint8_t *encryptedKey, uint32_t encryptedKeyLen); +typedef GRD_DbValueT (*DBGetConfig) (GRD_DB *db, GRD_ConfigTypeE type); +typedef int (*DBSetConfig) (GRD_DB *db, GRD_ConfigTypeE type, GRD_DbValueT value); struct GRD_APIInfo { DBOpen DBOpenApi = nullptr; DBClose DBCloseApi = nullptr; + DBRepair DBRepairApi = nullptr; DBSqlPrepare DBSqlPrepare = nullptr; DBSqlReset DBSqlReset = nullptr; DBSqlFinalize DBSqlFinalize = nullptr; @@ -74,6 +80,10 @@ struct GRD_APIInfo { DBSqlColInt64 DBSqlColInt64 = nullptr; DBSqlColDouble DBSqlColDouble = nullptr; DBSqlColumnFloatVector DBSqlColumnFloatVector = nullptr; + DBBackup DBBackupApi = nullptr; + DBRestore DBRestoreApi = nullptr; + DBGetConfig DBGetConfigApi = nullptr; + DBSetConfig DBSetConfigApi = nullptr; }; GRD_APIInfo GetApiInfoInstance(); diff --git a/relational_store/frameworks/native/rdb/include/grd_error.h b/relational_store/frameworks/native/rdb/include/grd_error.h index 1bc67128..9505e5a5 100644 --- a/relational_store/frameworks/native/rdb/include/grd_error.h +++ b/relational_store/frameworks/native/rdb/include/grd_error.h @@ -48,6 +48,7 @@ extern "C" { #define GRD_DISK_SPACE_FULL (-41000) #define GRD_CRC_CHECK_DISABLED (-42000) #define GRD_PERMISSION_DENIED (-43000) +#define GRD_DATA_CORRUPTED (-45000) // not support #define GRD_JSON_OPERATION_NOT_SUPPORT (-5001001) diff --git a/relational_store/frameworks/native/rdb/include/grd_type_export.h b/relational_store/frameworks/native/rdb/include/grd_type_export.h index e41e09b4..6d4ba9b8 100644 --- a/relational_store/frameworks/native/rdb/include/grd_type_export.h +++ b/relational_store/frameworks/native/rdb/include/grd_type_export.h @@ -56,6 +56,11 @@ typedef enum { GRD_SQL_DATATYPE_NULL, } GRD_DbDataTypeE; +typedef enum { + GRD_CONFIG_USER_VERSION, + GRD_CONFIG_BOTTOM, +} GRD_ConfigTypeE; + typedef struct GRD_DbValueT { GRD_DbDataTypeE type; union { diff --git a/relational_store/frameworks/native/rdb/include/rd_connection.h b/relational_store/frameworks/native/rdb/include/rd_connection.h index eb7968fe..e3037fdf 100644 --- a/relational_store/frameworks/native/rdb/include/rd_connection.h +++ b/relational_store/frameworks/native/rdb/include/rd_connection.h @@ -21,44 +21,57 @@ #include #include "rd_utils.h" -#include "rdb_connection.h" -#include "rdb_statement.h" +#include "connection.h" #include "rdb_store_config.h" -#include "sqlite_statement.h" #include "value_object.h" -#include "shared_block.h" typedef struct ClientChangedData ClientChangedData; namespace OHOS { namespace NativeRdb { -class RdConnection : public RdbConnection { +class RdConnection : public Connection { public: - static std::shared_ptr Open(const RdbStoreConfig &config, bool isWriteConnection, int &errCode); + static std::pair> Create(const RdbStoreConfig& config, bool isWrite); + static int32_t Repair(const RdbStoreConfig& config); + static void DeleteDbFile(const RdbStoreConfig& config); explicit RdConnection(bool isWriteConnection); ~RdConnection(); - int Prepare(const std::string &sql, bool &outIsReadOnly) override; - int ExecuteSql( - const std::string &sql, const std::vector &bindArgs) override; - - std::shared_ptr BeginStepQuery(int &errCode, const std::string &sql, - const std::vector &args) const override; - int DesFinalize() override; - int EndStepQuery() override; - - void SetInTransaction(bool transaction) override; - bool IsInTransaction() override; - GRD_DB *GetDbHandle() - { - return dbHandle_; - } + int32_t OnInitialize() override; + std::pair CreateStatement(const std::string& sql, SConn conn) override; + int32_t GetDBType() const override; + bool IsWriter() const override; + int32_t ReSetKey(const RdbStoreConfig& config) override; + int32_t TryCheckPoint() override; + int32_t LimitWalSize() override; + int32_t ConfigLocale(const std::string& localeStr) override; + int32_t CleanDirtyData(const std::string& table, uint64_t cursor) override; + int32_t SubscribeTableChanges(const Notifier& notifier) override; + int32_t GetMaxVariable() const override; + int32_t GetJournalMode() override; + int32_t ClearCache() override; + int32_t Subscribe(const std::string& event, + const std::shared_ptr& observer) override; + int32_t Unsubscribe(const std::string& event, + const std::shared_ptr& observer) override; + int32_t Backup(const std::string &databasePath, const std::vector &destEncryptKey) override; + int32_t Restore(const std::string &databasePath, const std::vector &destEncryptKey) override; + private: - static constexpr const char *GRD_OPEN_CONFIG_STR = "{\"pageSize\":16, \"redoFlushByTrx\":1}"; + static constexpr int MAX_VARIABLE_NUM = 500; + static constexpr const char *GRD_OPEN_CONFIG_STR = + "{\"pageSize\":8, \"crcCheckEnable\":0, \"redoFlushByTrx\":1, \"bufferPoolSize\":10240," + "\"sharedModeEnable\":1, \"metaInfoBak\":1, \"maxConnNum\":500 }"; + static constexpr uint32_t NO_ITER = 0; + static constexpr uint32_t ITER_V1 = 5000; + static constexpr uint32_t ITERS[] = {NO_ITER, ITER_V1}; + static constexpr uint32_t ITERS_COUNT = sizeof(ITERS) / sizeof(ITERS[0]); + static const int32_t regCreator_; + static const int32_t regRepairer_; + static const int32_t regFileDeleter_; - int PrepareAndBind(const std::string &sql, const std::vector &bindArgs); int InnerOpen(const RdbStoreConfig &config); + bool isWriter_ = false; GRD_DB *dbHandle_ = nullptr; - bool inTransaction_; std::string configStr_ = GRD_OPEN_CONFIG_STR; }; diff --git a/relational_store/frameworks/native/rdb/include/rd_result_set.h b/relational_store/frameworks/native/rdb/include/rd_result_set.h deleted file mode 100644 index 7d49591c..00000000 --- a/relational_store/frameworks/native/rdb/include/rd_result_set.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#ifndef NATIVE_RDB_RD_RESULT_SET_H -#define NATIVE_RDB_RD_RESULT_SET_H - -#include -#include -#include -#include -#include - -#include "abs_shared_result_set.h" -#include "rd_statement.h" -#include "rdb_connection_pool.h" -#include "value_object.h" - -namespace OHOS { -namespace NativeRdb { -class RdSharedResultSet : public AbsSharedResultSet { -public: - RdSharedResultSet(std::shared_ptr connectionPool, const std::string& sql, - const std::vector& selectionArgs); - RdSharedResultSet(std::shared_ptr connectionPool, const std::string& sql, - const std::vector& selectionArgs, int rowCount); - ~RdSharedResultSet() override; - - int GetColumnType(int columnIndex, ColumnType &columnType) override; - int GetRowCount(int &count) override; - int GoToRow(int position) override; - int GoToNextRow() override; - int IsStarted(bool &result) const override; - int IsAtFirstRow(bool &result) const override; - int IsEnded(bool &result) override; - int GetSize(int columnIndex, size_t &size) override; - int Get(int32_t col, ValueObject &value) override; - int Close() override; - -protected: - std::pair> GetColumnNames() override; - virtual int PrepareStep(); - - template - int GetValue(int32_t col, T &value); - std::pair GetValueObject(int32_t col, size_t index); - std::pair, std::shared_ptr> GetStatement(); - void Reset(); - int FinishStep(); - - static const int INIT_POS = -1; - // Max times of retrying step query - static const int STEP_QUERY_RETRY_MAX_TIMES = 50; - // Interval of retrying step query in millisecond - static const int STEP_QUERY_RETRY_INTERVAL = 1000; - - std::shared_ptr statement_ = nullptr; - std::shared_ptr conn_ = nullptr; - std::vector args_ = {}; - std::string sql_ = ""; - std::shared_ptr rdConnectionPool_ = nullptr; - // The value indicates the row count of the result set - int rowCount_; - // Whether reach the end of this result set or not - bool isAfterLast_; -}; - - -} // namespace NativeRdb -} // namespace OHOS - -#endif // NATIVE_RDB_RD_RESULT_SET_H diff --git a/relational_store/frameworks/native/rdb/include/rd_statement.h b/relational_store/frameworks/native/rdb/include/rd_statement.h index 5b5250c1..b59ca34d 100644 --- a/relational_store/frameworks/native/rdb/include/rd_statement.h +++ b/relational_store/frameworks/native/rdb/include/rd_statement.h @@ -19,49 +19,52 @@ #include #include -#include "rd_connection.h" +#include "connection.h" #include "rd_utils.h" -#include "rdb_statement.h" +#include "statement.h" #include "value_object.h" - +#include "rd_connection.h" namespace OHOS { namespace NativeRdb { - -class RdStatement : public RdbStatement { +class RdStatement final : public Statement { public: RdStatement(); ~RdStatement(); - static std::shared_ptr CreateStatement( - std::shared_ptr connection, const std::string &sql); - int Prepare(GRD_DB *db, const std::string &sql); int Finalize() override; - int BindArguments(const std::vector &bindArgs) const override; - int ResetStatementAndClearBindings() const override; - int Step() const override; - - int GetColumnCount(int &count) const override; - int GetColumnName(int index, std::string &columnName) const override; - int GetColumnType(int index, int &columnType) const override; - int GetColumnBlob(int index, std::vector &value) const override; - int GetColumnString(int index, std::string &value) const override; - int GetColumnInt(int index, int &value); - int GetColumnLong(int index, int64_t &value) const override; - int GetColumnDouble(int index, double &value) const override; - int GetFloat32Array(int32_t index, std::vector &vecs) const override; - int GetSize(int index, size_t &size) const override; - int GetColumn(int index, ValueObject &value) const override; - bool IsReadOnly() const override; + int32_t Prepare(const std::string& sql) override; + int32_t Bind(const std::vector& args) override; + int32_t Step() override; + int32_t Reset() override; + int32_t Execute(const std::vector& args) override; + std::pair ExecuteForValue(const std::vector& args) override; + int32_t Changes() const override; + int64_t LastInsertRowId() const override; + int32_t GetColumnCount() const override; + std::pair GetColumnName(int32_t index) const override; + std::pair GetColumnType(int32_t index) const override; + std::pair GetSize(int32_t index) const override; + std::pair GetColumn(int32_t index) const override; + bool ReadOnly() const override; + bool SupportBlockInfo() const override; + int32_t FillBlockInfo(SharedBlockInfo* info) const override; + void GetProperties(); private: - int InnerBindArguments(const std::vector &bindArgs) const; + friend class RdConnection; + int Prepare(GRD_DB *db, const std::string &sql); int InnerBindBlobTypeArgs(const ValueObject &bindArg, uint32_t index) const; - int IsValid(int index) const; + + bool readOnly_ = false; std::string sql_ = ""; GRD_SqlStmt *stmtHandle_ = nullptr; + GRD_DB *dbHandle_ = nullptr; + std::shared_ptr conn_; int columnCount_ = 0; -}; + std::map> setPragmas_; + std::map> getPragmas_; +}; } // namespace NativeRdb } // namespace OHOS #endif // NATIVE_RDB_RD_STATEMENT_H \ No newline at end of file diff --git a/relational_store/frameworks/native/rdb/include/rd_utils.h b/relational_store/frameworks/native/rdb/include/rd_utils.h index 94db0f6e..39cb6d14 100644 --- a/relational_store/frameworks/native/rdb/include/rd_utils.h +++ b/relational_store/frameworks/native/rdb/include/rd_utils.h @@ -31,6 +31,7 @@ public: static int TransferGrdErrno(int err); static ColumnType TransferGrdTypeToColType(int grdColType); static int RdDbOpen(const char *dbPath, const char *configStr, uint32_t flags, GRD_DB **db); + static int RdDbRepair(const char *dbPath, const char *configStr); static int RdDbClose(GRD_DB *db, uint32_t flags); static int RdSqlPrepare(GRD_DB *db, const char *str, uint32_t strLen, GRD_SqlStmt **stmt, const char **unusedStr); static int RdSqlReset(GRD_SqlStmt *stmt); @@ -59,9 +60,11 @@ public: static double RdSqlColDouble(GRD_SqlStmt *stmt, uint32_t idx); static const float *RdSqlColumnFloatVector(GRD_SqlStmt *stmt, uint32_t idx, uint32_t *dim); - static const std::string BEGIN_TRANSACTION_SQL; - static const std::string COMMIT_TRANSACTION_SQL; - static const std::string ROLLBACK_TRANSACTION_SQL; + static int RdDbBackup(GRD_DB *db, const char *backupDbFile, uint8_t *encryptedKey, uint32_t encryptedKeyLen); + static int RdDbRestore(GRD_DB *db, const char *backupDbFile, uint8_t *encryptedKey, uint32_t encryptedKeyLen); + + static int RdDbGetVersion(GRD_DB *db, GRD_ConfigTypeE type, int &version); + static int RdDbSetVersion(GRD_DB *db, GRD_ConfigTypeE type, int version); }; } // namespace NativeRdb diff --git a/relational_store/frameworks/native/rdb/include/rdb_connection.h b/relational_store/frameworks/native/rdb/include/rdb_connection.h deleted file mode 100644 index 41d437b2..00000000 --- a/relational_store/frameworks/native/rdb/include/rdb_connection.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NATIVE_RDB_CONNECTION_H -#define NATIVE_RDB_CONNECTION_H - -#include -#include -#include - -#include "rdb_statement.h" -#include "rdb_store_config.h" -#include "value_object.h" -#include "shared_block.h" - -typedef struct ClientChangedData ClientChangedData; -namespace OHOS { -namespace NativeRdb { - -/** - * @brief Use DataChangeCallback replace std::function. - */ -using DataChangeCallback = std::function; - -class RdbConnection { -public: - static std::shared_ptr Open(const RdbStoreConfig &config, bool isWriteConnection, int &errCode); - virtual ~RdbConnection() = default; - virtual bool IsWriteConnection() const; - virtual int Prepare(const std::string &sql, bool &outIsReadOnly); - virtual int ExecuteSql( - const std::string &sql, const std::vector &bindArgs = std::vector()); - virtual std::shared_ptr BeginStepQuery(int &errCode, const std::string &sql, - const std::vector &args) const; - virtual int DesFinalize(); - virtual int EndStepQuery(); - virtual int ExecuteForChangedRowCount( - int &changedRows, const std::string &sql, const std::vector &bindArgs); - virtual int ExecuteForLastInsertedRowId(int64_t &outRowId, const std::string &sql, - const std::vector &bindArgs); - virtual int ExecuteGetLong(int64_t &outValue, const std::string &sql, - const std::vector &bindArgs = std::vector()); - virtual int ExecuteGetString(std::string &outValue, const std::string &sql, - const std::vector &bindArgs = std::vector()); - virtual int ExecuteEncryptSql(const RdbStoreConfig &config, uint32_t iter); - virtual int ReSetKey(const RdbStoreConfig &config); - virtual void SetInTransaction(bool transaction); - virtual bool IsInTransaction(); - virtual int TryCheckPoint(); - virtual int LimitWalSize(); - virtual int ConfigLocale(const std::string &localeStr); - virtual int ExecuteForSharedBlock(int &rowNum, std::string sql, const std::vector &bindArgs, - AppDataFwk::SharedBlock *sharedBlock, int startPos, int requiredPos, bool isCountAllRows); - virtual int CleanDirtyData(const std::string &table, uint64_t cursor); - virtual int RegisterCallBackObserver(const DataChangeCallback &clientChangedData); - virtual int GetMaxVariableNumber(); - virtual uint32_t GetId() const; - virtual int32_t SetId(uint32_t id); - virtual JournalMode GetJournalMode(); -protected: - explicit RdbConnection(bool isWriteConnection); - int GetDbPath(const RdbStoreConfig &config, std::string &dbPath); - bool isWriteConnection_; - bool isReadOnly_; - bool isConfigured_ = false; - std::shared_ptr statement_ = nullptr; - std::shared_ptr stepStatement_ = nullptr; - std::string filePath_; - int openFlags; - - static constexpr int DEFAULT_BUSY_TIMEOUT_MS = 2000; - static constexpr uint32_t NO_ITER = 0; - static constexpr uint32_t ITER_V1 = 5000; - static constexpr uint32_t ITERS[] = {NO_ITER, ITER_V1}; - static constexpr uint32_t ITERS_COUNT = sizeof(ITERS) / sizeof(ITERS[0]); -}; - -} // namespace NativeRdb -} // namespace OHOS -#endif // NATIVE_RDB_CONNECTION_H \ No newline at end of file diff --git a/relational_store/frameworks/native/rdb/include/rdb_connection_pool.h b/relational_store/frameworks/native/rdb/include/rdb_connection_pool.h deleted file mode 100644 index 778da127..00000000 --- a/relational_store/frameworks/native/rdb/include/rdb_connection_pool.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NATIVE_RDB_CONNECTION_POOL_H -#define NATIVE_RDB_CONNECTION_POOL_H - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rdb_store_config.h" -#include "rdb_connection.h" -#include "sqlite_connection.h" -#include "base_transaction.h" -namespace OHOS { -namespace NativeRdb { -class RdbConnectionPool { -public: - static std::shared_ptr Create(const RdbStoreConfig &storeConfig, int &errCode); - explicit RdbConnectionPool(const RdbStoreConfig &storeConfig); - virtual ~RdbConnectionPool(); - virtual std::shared_ptr AcquireNewConnection(bool isReadOnly, int64_t &trxId); - virtual void ReleaseConnection(std::shared_ptr rdbConnection, int64_t trxId = 0); - virtual std::shared_ptr AcquireConnection(bool isReadOnly, int64_t trxId = 0); - virtual int RestartReaders(); - virtual std::pair, std::vector>> - AcquireAll(int32_t time); - virtual int ConfigLocale(const std::string &localeStr); - virtual int ChangeDbFileForRestore(const std::string &newPath, const std::string &backupPath, - const std::vector &newKey); - virtual std::stack &GetTransactionStack(); - virtual std::mutex &GetTransactionStackMutex(); - virtual std::pair> DisableWalMode(); - virtual int AcquireTransaction(); - virtual void ReleaseTransaction(); - virtual int EnableWalMode(); - virtual void CloseAllConnections(); -protected: - std::mutex transactionStackMutex_; - std::stack transactionStack_; - RdbStoreConfig config_; -private: - static constexpr uint32_t MAX_WRITE_CONN_NUM = 16; - static constexpr uint32_t MAX_READ_CONN_NUM = 64; - static constexpr uint32_t DEFAULT_WRITE_CONN_NUM = 2; - static constexpr uint32_t DEFAULT_READ_CONN_NUM = 8; - - virtual int Init(); - std::shared_ptr AcquireConnectionByTrxId(bool isReadOnly, int64_t trxId = 0); - std::shared_ptr AcquireReadConnByTrxId(int64_t trxId); - std::shared_ptr AcquireWriteConnByTrxId(int64_t trxId); - void CloseAllConns(); - - std::mutex idleConnsMutex_; - std::vector> idleReadConns_; - std::vector> idleWriteConns_; - std::map> trxConnMap_ = {}; - - std::atomic newtrxId_ = 1; - std::atomic writeConnNum_ = 0; - std::atomic readConnNum_ = 0; -}; - -} // namespace NativeRdb -} // namespace OHOS -#endif // NATIVE_RDB_CONNECTION_POOL_H diff --git a/relational_store/frameworks/native/rdb/include/rdb_platform.h b/relational_store/frameworks/native/rdb/include/rdb_platform.h index 2279b795..5bb5d036 100644 --- a/relational_store/frameworks/native/rdb/include/rdb_platform.h +++ b/relational_store/frameworks/native/rdb/include/rdb_platform.h @@ -36,12 +36,21 @@ static UNUSED_FUNCTION uint32_t GetUid() #endif } -static UNUSED_FUNCTION int MkDir(const std::string &filePath) +static UNUSED_FUNCTION int MkDir(const std::string &filePath, mode_t dirRight = DIR_RIGHT) { #ifdef WINDOWS_PLATFORM return mkdir(filePath.c_str()); #else - return mkdir(filePath.c_str(), DIR_RIGHT); + return mkdir(filePath.c_str(), dirRight); +#endif +} + +static UNUSED_FUNCTION uint64_t GetThreadId() +{ +#ifdef WINDOWS_PLATFORM + return 0; +#else + return (uint64_t)pthread_self(); #endif } diff --git a/relational_store/frameworks/native/rdb/include/rdb_security_manager.h b/relational_store/frameworks/native/rdb/include/rdb_security_manager.h index b319b122..e0d93bea 100644 --- a/relational_store/frameworks/native/rdb/include/rdb_security_manager.h +++ b/relational_store/frameworks/native/rdb/include/rdb_security_manager.h @@ -30,7 +30,7 @@ #include #include -#include "hks_api.h" +#include "hks_type.h" #include "rdb_errno.h" namespace OHOS::NativeRdb { diff --git a/relational_store/frameworks/native/rdb/include/rdb_sql_statistic.h b/relational_store/frameworks/native/rdb/include/rdb_sql_statistic.h new file mode 100644 index 00000000..2427cff7 --- /dev/null +++ b/relational_store/frameworks/native/rdb/include/rdb_sql_statistic.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_DATA_RELATIONAL_STORE_FRAMEWORKS_NATIVE_RDB_SQL_STATISTIC_H +#define OHOS_DISTRIBUTED_DATA_RELATIONAL_STORE_FRAMEWORKS_NATIVE_RDB_SQL_STATISTIC_H +#include +#include +#include + +#include "concurrent_map.h" +#include "rdb_types.h" +#include "rdb_visibility.h" + +namespace OHOS::DistributedRdb { +class SqlStatistic { +public: + enum Step : int32_t { + STEP_TOTAL, + STEP_TOTAL_REF, + STEP_TOTAL_RES, + STEP_WAIT, + STEP_PREPARE, + STEP_EXECUTE, + STEP_BUTT, + }; + API_EXPORT static int Subscribe(std::shared_ptr observer); + API_EXPORT static int Unsubscribe(std::shared_ptr observer); + static uint32_t GenerateId(); + SqlStatistic(const std::string &sql, int32_t step, uint32_t seqId = 0); + ~SqlStatistic(); + +private: + using SqlExecInfo = SqlObserver::SqlExecutionInfo; + static void Release(SqlExecInfo *execInfo); + static ConcurrentMap> observers_; + static ConcurrentMap> execInfos_; + static bool enabled_; + static std::atomic_uint32_t seqId_; + int32_t step_ = 0; + uint64_t key_ = 0; + std::chrono::steady_clock::time_point time_; + std::shared_ptr execInfo_; +}; +} +#endif // OHOS_DISTRIBUTED_DATA_RELATIONAL_STORE_FRAMEWORKS_NATIVE_RDB_SQL_STATISTIC_H diff --git a/relational_store/frameworks/native/rdb/include/rdb_store_impl.h b/relational_store/frameworks/native/rdb/include/rdb_store_impl.h index 12604464..68a2d7ee 100644 --- a/relational_store/frameworks/native/rdb/include/rdb_store_impl.h +++ b/relational_store/frameworks/native/rdb/include/rdb_store_impl.h @@ -35,6 +35,7 @@ #include "sqlite_connection_pool.h" #include "sqlite_statement.h" #include "value_object.h" +#include "rd_statement.h" namespace OHOS { class ExecutorPool; @@ -186,6 +187,7 @@ public: std::pair Detach(const std::string &attachName, int32_t waitTime = 2) override; int ModifyLockStatus(const AbsRdbPredicates &predicates, bool isLock) override; void AfterOpen(const RdbStoreConfig &config); + int32_t GetDbType() const override; protected: int InnerOpen(); @@ -201,12 +203,18 @@ protected: std::string fileType_; private: + std::map> trxConnMap_ = {}; + std::atomic newTrxId_ = 1; + int ExecuteByTrxId(const std::string &sql, int64_t trxId, bool closeConnAfterExecute = false, + const std::vector &bindArgs = {}); + std::pair HandleDifferentSqlTypes(std::shared_ptr statement, + const std::string &sql, const ValueObject &object, int sqlType); + using ExecuteSqls = std::vector>>>; using Stmt = std::shared_ptr; int CheckAttach(const std::string &sql); std::pair BeginExecuteSql(const std::string &sql); ExecuteSqls GenerateSql(const std::string& table, const std::vector& buckets, int limit); - ExecuteSqls MakeExecuteSqls(const std::string& sql, std::vector&& args, int fieldSize, int limit); int GetDataBasePath(const std::string &databasePath, std::string &backupFilePath); int ExecuteSqlInner(const std::string &sql, const std::vector &bindArgs); void SetAssetStatus(const ValueObject &val, int32_t status); @@ -216,7 +224,6 @@ private: int InnerBackup(const std::string& databasePath, const std::vector& destEncryptKey = std::vector()); ModifyTime GetModifyTimeByRowId(const std::string& logTable, std::vector& keys); - inline std::string GetSqlArgs(size_t size); Uri GetUri(const std::string &event); int SubscribeLocal(const SubscribeOption& option, RdbStoreObserver *observer); int SubscribeLocalShared(const SubscribeOption& option, RdbStoreObserver *observer); @@ -239,10 +246,22 @@ private: std::string GetSecManagerName(const RdbStoreConfig &config); void RemoveDbFiles(std::string &path); int GetHashKeyForLockRow(const AbsRdbPredicates &predicates, std::vector> &hashKeys); + int InsertWithConflictResolutionEntry(int64_t &outRowId, const std::string &table, const ValuesBucket &values, + ConflictResolution conflictResolution); + int UpdateWithConflictResolutionEntry(int &changedRows, const std::string &table, const ValuesBucket &values, + const std::string &whereClause, const std::vector &bindArgs, + ConflictResolution conflictResolution); + int BatchInsertEntry(int64_t& outInsertNum, const std::string& table, const std::vector& values); + int ExecuteSqlEntry(const std::string& sql, const std::vector& bindArgs); + std::pair ExecuteEntry(const std::string& sql, const std::vector& bindArgs, + int64_t trxId); + static void UploadSchema(const DistributedRdb::RdbSyncerParam ¶m, uint32_t retry); static constexpr char SCHEME_RDB[] = "rdb://"; static constexpr uint32_t EXPANSION = 2; static inline constexpr uint32_t INTERVAL = 10; + static inline constexpr uint32_t RETRY_INTERVAL = 5; // s + static inline constexpr uint32_t MAX_RETRY_TIMES = 5; static constexpr const char *ROW_ID = "ROWID"; std::shared_ptr connectionPool_ = nullptr; diff --git a/relational_store/frameworks/native/rdb/include/rdb_trace.h b/relational_store/frameworks/native/rdb/include/rdb_trace.h index 660ad1da..2f3acc79 100644 --- a/relational_store/frameworks/native/rdb/include/rdb_trace.h +++ b/relational_store/frameworks/native/rdb/include/rdb_trace.h @@ -19,7 +19,11 @@ #ifdef RDB_TRACE_ON #include "hitrace.h" + +#ifndef DISTRIBUTED_DATA_HITRACE #define DISTRIBUTED_DATA_HITRACE(trace) HiTrace hitrace(trace) +#endif + #else #define DISTRIBUTED_DATA_HITRACE(trace) DO_NOTHING #endif diff --git a/relational_store/frameworks/native/rdb/include/sqlite_connection.h b/relational_store/frameworks/native/rdb/include/sqlite_connection.h index 92760b70..03775c75 100644 --- a/relational_store/frameworks/native/rdb/include/sqlite_connection.h +++ b/relational_store/frameworks/native/rdb/include/sqlite_connection.h @@ -40,6 +40,7 @@ using DataChangeCallback = std::function> Create(const RdbStoreConfig &config, bool isWrite); + static void DeleteDbFile(const RdbStoreConfig &config); ~SqliteConnection(); int32_t OnInitialize() override; int TryCheckPoint() override; @@ -53,17 +54,18 @@ public: int SubscribeTableChanges(const Notifier ¬ifier) override; int GetMaxVariable() const override; int32_t GetDBType() const override; + int32_t ClearCache() override; int32_t Subscribe(const std::string &event, const std::shared_ptr &observer) override; int32_t Unsubscribe(const std::string &event, const std::shared_ptr &observer) override; + int32_t Backup(const std::string &databasePath, const std::vector &destEncryptKey) override; + int32_t Restore(const std::string &databasePath, const std::vector &destEncryptKey) override; protected: - int ExecuteSql(const std::string &sql, const std::vector &bindArgs = std::vector()); - int ExecuteGetLong(int64_t &outValue, const std::string &sql, - const std::vector &bindArgs = std::vector()); - int ExecuteGetString(std::string &outValue, const std::string &sql, + std::pair ExecuteForValue(const std::string &sql, const std::vector &bindArgs = std::vector()); + int ExecuteSql(const std::string &sql, const std::vector &bindArgs = std::vector()); int ExecuteEncryptSql(const RdbStoreConfig &config, uint32_t iter); void SetInTransaction(bool transaction); @@ -95,13 +97,17 @@ private: int32_t UnsubscribeLocalDetail(const std::string &event, const std::shared_ptr &observer); int32_t UnsubscribeLocalDetailAll(const std::string &event); + int32_t OpenDatabase(const std::string &dbPath, int openFileFlags); + void ReadFile2Buffer(const char* fileName); + static constexpr uint32_t BUFFER_LEN = 16; static constexpr int DEFAULT_BUSY_TIMEOUT_MS = 2000; static constexpr uint32_t NO_ITER = 0; static constexpr uint32_t ITER_V1 = 5000; static constexpr uint32_t ITERS[] = { NO_ITER, ITER_V1 }; static constexpr uint32_t ITERS_COUNT = sizeof(ITERS) / sizeof(ITERS[0]); - static const int32_t g_reg; + static const int32_t regCreater_; + static const int32_t regFileDeleter_; sqlite3 *dbHandle; bool isWriter_; diff --git a/relational_store/frameworks/native/rdb/include/sqlite_connection_pool.h b/relational_store/frameworks/native/rdb/include/sqlite_connection_pool.h index 4db159ba..7d28876d 100644 --- a/relational_store/frameworks/native/rdb/include/sqlite_connection_pool.h +++ b/relational_store/frameworks/native/rdb/include/sqlite_connection_pool.h @@ -31,6 +31,7 @@ #include "connection.h" #include "rdb_common.h" #include "rdb_store_config.h" +#include "rd_statement.h" namespace OHOS { namespace NativeRdb { class SqliteConnectionPool : public std::enable_shared_from_this { @@ -40,6 +41,9 @@ public: static constexpr std::chrono::milliseconds INVALID_TIME = std::chrono::milliseconds(0); static std::shared_ptr Create(const RdbStoreConfig &storeConfig, int &errCode); ~SqliteConnectionPool(); + static std::pair> HandleDataCorruption + (const RdbStoreConfig &storeConfig, int &errCode); + std::pair> CreateConnection(bool isReadOnly); SharedConn AcquireConnection(bool isReadOnly); SharedConn Acquire(bool isReadOnly, std::chrono::milliseconds ms = INVALID_TIME); // this interface is only provided for resultSet @@ -112,11 +116,12 @@ private: int32_t GetMaxReaders(const RdbStoreConfig &config); std::shared_ptr Convert2AutoConn(std::shared_ptr node); void ReleaseNode(std::shared_ptr node); + void RemoveDBFile(); void RemoveDBFile(const std::string &path); static constexpr int LIMITATION = 1024; - RdbStoreConfig config_; + const RdbStoreConfig &config_; Container writers_; Container readers_; int32_t maxReader_ = 0; diff --git a/relational_store/frameworks/native/rdb/include/sqlite_errno.h b/relational_store/frameworks/native/rdb/include/sqlite_errno.h index aa10d0da..90625e73 100644 --- a/relational_store/frameworks/native/rdb/include/sqlite_errno.h +++ b/relational_store/frameworks/native/rdb/include/sqlite_errno.h @@ -41,6 +41,8 @@ const static std::map ERROR_CODE_MAPPINT_TABLE = { { SQLITE_MISMATCH, E_SQLITE_MISMATCH }, { SQLITE_MISUSE, E_SQLITE_MISUSE }, { SQLITE_NOTADB, E_SQLITE_CORRUPT }, + { SQLITE_DONE, E_NO_MORE_ROWS }, + { SQLITE_ROW, E_OK }, }; class SQLiteError { public: diff --git a/relational_store/frameworks/native/rdb/include/sqlite_global_config.h b/relational_store/frameworks/native/rdb/include/sqlite_global_config.h index 0a17dac3..00399d47 100644 --- a/relational_store/frameworks/native/rdb/include/sqlite_global_config.h +++ b/relational_store/frameworks/native/rdb/include/sqlite_global_config.h @@ -60,7 +60,7 @@ public: SqliteGlobalConfig(); ~SqliteGlobalConfig(); static void InitSqliteGlobalConfig(); - static void SqliteLogCallback(const void *data, int err, const char *msg); + static void Log(const void *data, int err, const char *msg); static int GetReadConnectionCount(); static std::string GetMemoryDbPath(); static int GetPageSize(); diff --git a/relational_store/frameworks/native/rdb/include/sqlite_shared_result_set.h b/relational_store/frameworks/native/rdb/include/sqlite_shared_result_set.h index c1c62e85..2faf9e0d 100644 --- a/relational_store/frameworks/native/rdb/include/sqlite_shared_result_set.h +++ b/relational_store/frameworks/native/rdb/include/sqlite_shared_result_set.h @@ -38,7 +38,6 @@ public: std::string sql, const std::vector &bindArgs); ~SqliteSharedResultSet() override; int Close() override; - int GetRowCount(int &count) override; int32_t OnGo(int oldPosition, int newPosition) override; void SetBlock(AppDataFwk::SharedBlock *block) override; int PickFillBlockStartPosition(int resultSetPosition, int blockCapacity) const; @@ -49,16 +48,20 @@ protected: std::pair> GetColumnNames() override; private: + int InitRowCount(); std::pair, int> PrepareStep(); int32_t FillBlock(int requiredPos); - std::pair ExecuteForSharedBlock(AppDataFwk::SharedBlock* block, int start, int required, - bool needCount); + int32_t ExecuteForSharedBlock(AppDataFwk::SharedBlock* block, int start, int required); private: // The specified value is -1 when there is no data static constexpr int NO_COUNT = -1; // The pick position of the shared block for search static constexpr int PICK_POS = 3; + // Max times of retrying query + static const int MAX_RETRY_TIMES = 50; + // Interval of retrying query in millisecond + static const int RETRY_INTERVAL = 1000; // Controls fetching of rows relative to requested position bool isOnlyFillBlock_ = false; uint32_t blockCapacity_ = 0; @@ -66,6 +69,7 @@ private: int rowNum_ = NO_COUNT; std::shared_ptr conn_; + std::shared_ptr statement_; std::string qrySql_; std::vector bindArgs_; std::vector columnNames_; diff --git a/relational_store/frameworks/native/rdb/include/sqlite_sql_builder.h b/relational_store/frameworks/native/rdb/include/sqlite_sql_builder.h index 28e8144f..16ad934d 100644 --- a/relational_store/frameworks/native/rdb/include/sqlite_sql_builder.h +++ b/relational_store/frameworks/native/rdb/include/sqlite_sql_builder.h @@ -26,6 +26,7 @@ namespace OHOS { namespace NativeRdb { class SqliteSqlBuilder { public: + using ExecuteSqls = std::vector>>>; SqliteSqlBuilder(); ~SqliteSqlBuilder(); static std::string BuildDeleteString(const std::string &tableName, const std::string &index, @@ -51,7 +52,10 @@ public: const std::vector &columns, const std::string &logTable, const std::pair &queryStatus); static std::string BuildLockRowQueryString( const AbsRdbPredicates &predicates, const std::vector &columns, const std::string &logTable); + static std::string GetSqlArgs(size_t size); + static ExecuteSqls MakeExecuteSqls( + const std::string &sql, std::vector &&args, int fieldSize, int limit); private: static void AppendClause(std::string &builder, const std::string &name, const std::string &clause, const std::string &table = ""); diff --git a/relational_store/frameworks/native/rdb/include/sqlite_statement.h b/relational_store/frameworks/native/rdb/include/sqlite_statement.h index f917c01b..127a5baa 100644 --- a/relational_store/frameworks/native/rdb/include/sqlite_statement.h +++ b/relational_store/frameworks/native/rdb/include/sqlite_statement.h @@ -87,6 +87,7 @@ private: bool bound_ = false; int columnCount_ = -1; int numParameters_; + uint32_t seqId_ = 0; sqlite3_stmt *stmt_; std::shared_ptr conn_; std::string sql_; diff --git a/relational_store/frameworks/native/rdb/include/statement.h b/relational_store/frameworks/native/rdb/include/statement.h index 134ac434..78c0a6cd 100644 --- a/relational_store/frameworks/native/rdb/include/statement.h +++ b/relational_store/frameworks/native/rdb/include/statement.h @@ -25,6 +25,7 @@ namespace OHOS::NativeRdb { struct SharedBlockInfo; class Statement { public: + static constexpr int32_t COLUMN_TYPE_INVALID = 0; static constexpr int32_t COLUMN_TYPE_ASSET = 1000; static constexpr int32_t COLUMN_TYPE_ASSETS = 1001; static constexpr int32_t COLUMN_TYPE_FLOATS = 1002; @@ -36,8 +37,8 @@ public: virtual int32_t Step() = 0; virtual int32_t Reset() = 0; virtual int32_t Finalize() = 0; - virtual int32_t Execute(const std::vector &args = {}) = 0; + virtual std::pair ExecuteForValue(const std::vector &args = {}) = 0; virtual int32_t Changes() const = 0; virtual int64_t LastInsertRowId() const = 0; diff --git a/relational_store/frameworks/native/rdb/include/step_result_set.h b/relational_store/frameworks/native/rdb/include/step_result_set.h index a1abf360..7c11cfc6 100644 --- a/relational_store/frameworks/native/rdb/include/step_result_set.h +++ b/relational_store/frameworks/native/rdb/include/step_result_set.h @@ -34,12 +34,8 @@ public: const std::vector &selectionArgs); ~StepResultSet() override; int GetColumnType(int columnIndex, ColumnType &columnType) override; - int GetRowCount(int &count) override; int GoToRow(int position) override; int GoToNextRow() override; - int IsStarted(bool &result) const override; - int IsAtFirstRow(bool &result) const override; - int IsEnded(bool &result) override; int GetSize(int columnIndex, size_t &size) override; int Get(int32_t col, ValueObject &value) override; int Close() override; @@ -52,11 +48,10 @@ private: int GetValue(int32_t col, T &value); std::pair GetValueObject(int32_t col, size_t index); std::shared_ptr GetStatement(); - void Reset(); - int FinishStep(); + int Reset(); + int InitRowCount(); int PrepareStep(); - static const int INIT_POS = -1; // Max times of retrying step query static const int STEP_QUERY_RETRY_MAX_TIMES = 50; // Interval of retrying step query in millisecond @@ -68,11 +63,6 @@ private: std::string sql_; std::vector args_; - // The value indicates the row count of the result set - int rowCount_; - // Whether reach the end of this result set or not - bool isAfterLast_; - bool isStarted_; mutable std::shared_mutex mutex_; }; } // namespace NativeRdb diff --git a/relational_store/frameworks/native/rdb/include/string_utils.h b/relational_store/frameworks/native/rdb/include/string_utils.h index ebd93b33..d0747912 100644 --- a/relational_store/frameworks/native/rdb/include/string_utils.h +++ b/relational_store/frameworks/native/rdb/include/string_utils.h @@ -28,6 +28,8 @@ public: const std::string &function, const std::string &separator, const std::vector &array); static std::vector Split(const std::string &str, const std::string &delim); + static std::string ExtractFilePath(const std::string& fileFullName); + static std::string ExtractFileName(const std::string& fileFullName); static bool IsEmpty(std::string source) { return (source.empty()); diff --git a/relational_store/frameworks/native/rdb/include/vdb_store_impl.h b/relational_store/frameworks/native/rdb/include/vdb_store_impl.h deleted file mode 100644 index 348c0eba..00000000 --- a/relational_store/frameworks/native/rdb/include/vdb_store_impl.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NATIVE_RDB_VDB_STORE_IMPL_H -#define NATIVE_RDB_VDB_STORE_IMPL_H - -#include -#include -#include -#include -#include -#include - -#include "concurrent_map.h" -#include "data_ability_observer_stub.h" -#include "dataobs_mgr_client.h" -#include "rdb_connection_pool.h" -#include "rdb_errno.h" -#include "rdb_service.h" -#include "rdb_store.h" -#include "rdb_store_config.h" -#include "rdb_store_impl.h" -#include "refbase.h" - -namespace OHOS::NativeRdb { - -class VdbStoreImpl : public RdbStoreImpl { -public: - VdbStoreImpl(const RdbStoreConfig &config, int &errCode); - ~VdbStoreImpl() override; - // Interface to support in VDB - std::pair BeginTrans() override; - int Commit(int64_t trxId) override; - int RollBack(int64_t trxId) override; - std::pair Execute(const std::string &sql, - const std::vector &bindArgs, int64_t trxId) override; - std::shared_ptr QuerySql(const std::string &sql, - const std::vector &bindArgs) override; - int ExecuteSqlByTrxId( - const std::string &sql, const std::vector &bindArgs = {}, int64_t trxId = 0); - // Interface not to support in VDB - int Insert(int64_t &outRowId, const std::string &table, const ValuesBucket &values) override; - int BatchInsert(int64_t& outInsertNum, const std::string& table, const std::vector& values) override; - int Replace(int64_t &outRowId, const std::string &table, const ValuesBucket &initialValues) override; - int InsertWithConflictResolution(int64_t &outRowId, const std::string &table, const ValuesBucket &values, - ConflictResolution conflictResolution) override; - int Update(int &changedRows, const std::string &table, const ValuesBucket &values, const std::string &whereClause, - const std::vector &whereArgs) override; - int Update(int &changedRows, const std::string &table, const ValuesBucket &values, const std::string &whereClause, - const std::vector &bindArgs) override; - int UpdateWithConflictResolution(int &changedRows, const std::string &table, const ValuesBucket &values, - const std::string &whereClause, const std::vector &whereArgs, - ConflictResolution conflictResolution) override; - int UpdateWithConflictResolution(int &changedRows, const std::string &table, const ValuesBucket &values, - const std::string &whereClause, const std::vector &bindArgs, - ConflictResolution conflictResolution) override; - int Delete(int &deletedRows, const std::string &table, const std::string &whereClause, - const std::vector &whereArgs) override; - int Delete(int &deletedRows, const std::string &table, const std::string &whereClause, - const std::vector &bindArgs) override; - std::shared_ptr Query(int &errCode, bool distinct, - const std::string &table, const std::vector &columns, - const std::string &whereClause, const std::vector &bindArgs, const std::string &groupBy, - const std::string &indexName, const std::string &orderBy, const int &limit, const int &offset) override; - std::shared_ptr QuerySql(const std::string &sql, - const std::vector &sqlArgs) override; - int ExecuteSql(const std::string& sql, const std::vector& bindArgs) override; - int ExecuteAndGetLong(int64_t &outValue, const std::string &sql, const std::vector &bindArgs) override; - int ExecuteAndGetString(std::string &outValue, const std::string &sql, - const std::vector &bindArgs) override; - int ExecuteForLastInsertedRowId(int64_t &outValue, const std::string &sql, - const std::vector &bindArgs) override; - int ExecuteForChangedRowCount(int64_t &outValue, const std::string &sql, - const std::vector &bindArgs) override; - int Backup(const std::string &databasePath, const std::vector &destEncryptKey) override; - int GetVersion(int &version) override; - int SetVersion(int version) override; - int BeginTransaction() override; - int RollBack() override; - int Commit() override; - bool IsInTransaction() override; - int Restore(const std::string &backupPath, const std::vector &newKey) override; - std::shared_ptr QueryByStep(const std::string &sql, - const std::vector &sqlArgs) override; - std::shared_ptr QueryByStep(const std::string &sql, const std::vector &args) override; - std::shared_ptr QueryByStep( - const AbsRdbPredicates &predicates, const std::vector &columns) override; - std::shared_ptr Query( - const AbsRdbPredicates &predicates, const std::vector &columns) override; - std::pair> QuerySharingResource( - const AbsRdbPredicates &predicates, const std::vector &columns) override; - int Count(int64_t &outValue, const AbsRdbPredicates &predicates) override; - int Update(int &changedRows, const ValuesBucket &values, const AbsRdbPredicates &predicates) override; - int Delete(int &deletedRows, const AbsRdbPredicates &predicates) override; - std::shared_ptr RemoteQuery(const std::string &device, const AbsRdbPredicates &predicates, - const std::vector &columns, int &errCode) override; - int SetDistributedTables(const std::vector &tables, int32_t type, - const DistributedRdb::DistributedConfig &distributedConfig) override; - std::string ObtainDistributedTableName(const std::string& device, const std::string& table, int &errCode) override; - int Sync(const SyncOption &option, const AbsRdbPredicates &predicate, const AsyncBrief &async) override; - int Sync(const SyncOption &option, const std::vector &tables, const AsyncDetail &async) override; - int Sync(const SyncOption &option, const AbsRdbPredicates &predicate, const AsyncDetail &async) override; - int Subscribe(const SubscribeOption& option, RdbStoreObserver *observer) override; - int UnSubscribe(const SubscribeOption& option, RdbStoreObserver *observer) override; - int RegisterAutoSyncCallback(std::shared_ptr observer) override; - int UnregisterAutoSyncCallback(std::shared_ptr observer) override; - int Notify(const std::string &event) override; - ModifyTime GetModifyTime(const std::string& table, const std::string& columnName, - std::vector& keys) override; - int CleanDirtyData(const std::string &table, uint64_t cursor) override; - std::pair Attach( - const RdbStoreConfig &config, const std::string &attachName, int32_t waitTime = 2) override; - std::pair Detach(const std::string &attachName, int32_t waitTime = 2) override; -private: - std::shared_ptr rdConnectionPool_ = nullptr; -}; -} // namespace OHOS::NativeRdb -#endif diff --git a/relational_store/frameworks/native/rdb/mock/include/connection.h b/relational_store/frameworks/native/rdb/mock/include/connection.h index 6c784870..be4d4c82 100644 --- a/relational_store/frameworks/native/rdb/mock/include/connection.h +++ b/relational_store/frameworks/native/rdb/mock/include/connection.h @@ -33,8 +33,14 @@ public: using Stmt = std::shared_ptr; using Notifier = std::function &tables)>; using Creator = std::pair (*)(const RdbStoreConfig &config, bool isWriter); + using Repairer = int32_t (*)(const RdbStoreConfig &config); + using Deleter = void (*)(const RdbStoreConfig &config); static std::pair Create(const RdbStoreConfig &config, bool isWriter); + static int32_t Repair(const RdbStoreConfig &config); + static void DeleteDbFile(const RdbStoreConfig &config); static int32_t RegisterCreator(int32_t dbType, Creator creator); + static int32_t RegisterRepairer(int32_t dbType, Repairer repairer); + static int32_t RegisterFileDeleter(int32_t dbType, Deleter deleter); int32_t SetId(int32_t id); int32_t GetId() const; @@ -51,10 +57,14 @@ public: virtual int32_t SubscribeTableChanges(const Notifier ¬ifier) = 0; virtual int32_t GetMaxVariable() const = 0; virtual int32_t GetJournalMode() = 0; + virtual int32_t ClearCache() = 0; + virtual int32_t Subscribe(const std::string &event, const std::shared_ptr &observer) = 0; virtual int32_t Unsubscribe(const std::string &event, const std::shared_ptr &observer) = 0; + virtual int32_t Backup(const std::string &databasePath, const std::vector &destEncryptKey) = 0; + virtual int32_t Restore(const std::string &databasePath, const std::vector &destEncryptKey) = 0; private: int32_t id_ = 0; diff --git a/relational_store/frameworks/native/rdb/mock/include/hisysevent.h b/relational_store/frameworks/native/rdb/mock/include/hisysevent.h new file mode 100644 index 00000000..ee7e982e --- /dev/null +++ b/relational_store/frameworks/native/rdb/mock/include/hisysevent.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef HI_SYS_EVENT_H +#define HI_SYS_EVENT_H + +namespace OHOS::HiviewDFX { + +inline void HiSysEventWrite(...) +{ +} + +class HiSysEvent { +public: + class Domain { + public: + static constexpr char DISTRIBUTED_DATAMGR[] = "DISTDATAMGR"; + }; + + enum EventType { + FAULT = 1, // system fault event + STATISTIC = 2, // system statistic event + SECURITY = 3, // system security event + BEHAVIOR = 4 // system behavior event + }; +}; +} // namespace OHOS::HiviewDFX + +#endif // HI_SYS_EVENT_H diff --git a/relational_store/frameworks/native/rdb/mock/include/rdb_store_impl.h b/relational_store/frameworks/native/rdb/mock/include/rdb_store_impl.h index 70c78576..c6b26504 100644 --- a/relational_store/frameworks/native/rdb/mock/include/rdb_store_impl.h +++ b/relational_store/frameworks/native/rdb/mock/include/rdb_store_impl.h @@ -16,6 +16,7 @@ #ifndef NATIVE_RDB_RDB_STORE_IMPL_H #define NATIVE_RDB_RDB_STORE_IMPL_H +#include #include #include #include @@ -28,6 +29,7 @@ #include "rdb_store_config.h" #include "sqlite_connection_pool.h" #include "sqlite_statement.h" +#include "rd_statement.h" namespace OHOS::NativeRdb { class RdbStoreImpl : public RdbStore { @@ -89,6 +91,8 @@ public: const std::vector &sqlArgs) override; std::shared_ptr QueryByStep( const std::string &sql, const std::vector &args) override; + std::shared_ptr QueryByStep( + const AbsRdbPredicates &predicates, const std::vector &columns) override; std::shared_ptr Query( const AbsRdbPredicates &predicates, const std::vector &columns) override; int Count(int64_t &outValue, const AbsRdbPredicates &predicates) override; @@ -113,12 +117,18 @@ protected: std::string fileType_; private: + std::map> trxConnMap_ = {}; + std::atomic newTrxId_ = 1; + int ExecuteByTrxId(const std::string &sql, int64_t trxId, bool closeConnAfterExecute = false, + const std::vector &bindArgs = {}); + std::pair HandleDifferentSqlTypes(std::shared_ptr statement, + const std::string &sql, const ValueObject &object, int sqlType); + using ExecuteSqls = std::vector>>>; using Stmt = std::shared_ptr; int CheckAttach(const std::string &sql); std::pair BeginExecuteSql(const std::string &sql); ExecuteSqls GenerateSql(const std::string& table, const std::vector& buckets, int limit); - ExecuteSqls MakeExecuteSqls(const std::string& sql, std::vector&& args, int fieldSize, int limit); int GetDataBasePath(const std::string &databasePath, std::string &backupFilePath); int ExecuteSqlInner(const std::string &sql, const std::vector &bindArgs = std::vector()); int ExecuteGetLongInner(const std::string &sql, const std::vector &bindArgs); @@ -126,14 +136,21 @@ private: void DoCloudSync(const std::string &table); int InnerBackup(const std::string &databasePath, const std::vector &destEncryptKey = std::vector()); - inline std::string GetSqlArgs(size_t size); int RegisterDataChangeCallback(); std::pair GetStatement(const std::string& sql, std::shared_ptr conn) const; std::pair GetStatement(const std::string& sql, bool read = false) const; int AttachInner(const std::string &attachName, const std::string &dbPath, const std::vector &key, int32_t waitTime); void RemoveDbFiles(std::string &path); - + int InsertWithConflictResolutionEntry(int64_t &outRowId, const std::string &table, const ValuesBucket &values, + ConflictResolution conflictResolution); + int UpdateWithConflictResolutionEntry(int &changedRows, const std::string &table, const ValuesBucket &values, + const std::string &whereClause, const std::vector &bindArgs, + ConflictResolution conflictResolution); + int BatchInsertEntry(int64_t& outInsertNum, const std::string& table, const std::vector& values); + int ExecuteSqlEntry(const std::string& sql, const std::vector& bindArgs); + std::pair ExecuteEntry(const std::string& sql, const std::vector& bindArgs, + int64_t trxId); static constexpr char SCHEME_RDB[] = "rdb://"; static constexpr uint32_t EXPANSION = 2; static constexpr uint32_t AUTO_SYNC_MAX_INTERVAL = 20000; diff --git a/relational_store/frameworks/native/rdb/mock/include/sqlite_connection.h b/relational_store/frameworks/native/rdb/mock/include/sqlite_connection.h index 3de7ca1d..d1afa01a 100644 --- a/relational_store/frameworks/native/rdb/mock/include/sqlite_connection.h +++ b/relational_store/frameworks/native/rdb/mock/include/sqlite_connection.h @@ -40,6 +40,7 @@ using DataChangeCallback = std::function> Create(const RdbStoreConfig &config, bool isWrite); + static void DeleteDbFile(const RdbStoreConfig &config); ~SqliteConnection(); int32_t OnInitialize() override; int TryCheckPoint() override; @@ -53,17 +54,16 @@ public: int SubscribeTableChanges(const Notifier ¬ifier) override; int GetMaxVariable() const override; int32_t GetDBType() const override; + int ClearCache() override; int32_t Subscribe(const std::string &event, const std::shared_ptr &observer) override; int32_t Unsubscribe(const std::string &event, const std::shared_ptr &observer) override; protected: - int ExecuteSql(const std::string &sql, const std::vector &bindArgs = std::vector()); - int ExecuteGetLong(int64_t &outValue, const std::string &sql, - const std::vector &bindArgs = std::vector()); - int ExecuteGetString(std::string &outValue, const std::string &sql, + std::pair ExecuteForValue(const std::string &sql, const std::vector &bindArgs = std::vector()); + int ExecuteSql(const std::string &sql, const std::vector &bindArgs = std::vector()); int ExecuteEncryptSql(const RdbStoreConfig &config, uint32_t iter); void SetInTransaction(bool transaction); @@ -95,13 +95,19 @@ private: int32_t UnsubscribeLocalDetail(const std::string &event, const std::shared_ptr &observer); int32_t UnsubscribeLocalDetailAll(const std::string &event); + int32_t Backup(const std::string &databasePath, const std::vector &destEncryptKey) override; + int32_t Restore(const std::string &databasePath, const std::vector &destEncryptKey) override; + int32_t OpenDatabase(const std::string &dbPath, int openFileFlags); + void ReadFile2Buffer(const char* fileName); + static constexpr uint32_t BUFFER_LEN = 16; static constexpr int DEFAULT_BUSY_TIMEOUT_MS = 2000; static constexpr uint32_t NO_ITER = 0; static constexpr uint32_t ITER_V1 = 5000; static constexpr uint32_t ITERS[] = { NO_ITER, ITER_V1 }; static constexpr uint32_t ITERS_COUNT = sizeof(ITERS) / sizeof(ITERS[0]); - static const int32_t g_reg; + static const int32_t regCreater_; + static const int32_t regFileDeleter_; sqlite3 *dbHandle; bool isWriter_; diff --git a/relational_store/frameworks/native/rdb/mock/include/sqlite_connection_pool.h b/relational_store/frameworks/native/rdb/mock/include/sqlite_connection_pool.h index 4db159ba..214d0900 100644 --- a/relational_store/frameworks/native/rdb/mock/include/sqlite_connection_pool.h +++ b/relational_store/frameworks/native/rdb/mock/include/sqlite_connection_pool.h @@ -31,6 +31,7 @@ #include "connection.h" #include "rdb_common.h" #include "rdb_store_config.h" +#include "rd_statement.h" namespace OHOS { namespace NativeRdb { class SqliteConnectionPool : public std::enable_shared_from_this { @@ -39,7 +40,10 @@ public: using SharedConns = std::vector; static constexpr std::chrono::milliseconds INVALID_TIME = std::chrono::milliseconds(0); static std::shared_ptr Create(const RdbStoreConfig &storeConfig, int &errCode); + static std::pair> HandleDataCorruption + (const RdbStoreConfig &storeConfig, int &errCode); ~SqliteConnectionPool(); + std::pair> CreateConnection(bool isReadOnly); SharedConn AcquireConnection(bool isReadOnly); SharedConn Acquire(bool isReadOnly, std::chrono::milliseconds ms = INVALID_TIME); // this interface is only provided for resultSet @@ -116,7 +120,7 @@ private: void RemoveDBFile(const std::string &path); static constexpr int LIMITATION = 1024; - RdbStoreConfig config_; + const RdbStoreConfig &config_; Container writers_; Container readers_; int32_t maxReader_ = 0; diff --git a/relational_store/frameworks/native/rdb/mock/include/step_result_set.h b/relational_store/frameworks/native/rdb/mock/include/step_result_set.h index 97cde0f3..2a30908f 100644 --- a/relational_store/frameworks/native/rdb/mock/include/step_result_set.h +++ b/relational_store/frameworks/native/rdb/mock/include/step_result_set.h @@ -34,12 +34,8 @@ public: const std::vector& selectionArgs); ~StepResultSet() override; int GetColumnType(int columnIndex, ColumnType &columnType) override; - int GetRowCount(int &count) override; int GoToRow(int position) override; int GoToNextRow() override; - int IsStarted(bool &result) const override; - int IsAtFirstRow(bool &result) const override; - int IsEnded(bool &result) override; int GetSize(int columnIndex, size_t &size) override; int Get(int32_t col, ValueObject &value) override; int Close() override; @@ -52,11 +48,10 @@ private: int GetValue(int32_t col, T &value); std::pair GetValueObject(int32_t col, size_t index); std::shared_ptr GetStatement(); - void Reset(); - int FinishStep(); + int Reset(); + int InitRowCount(); int PrepareStep(); - static const int INIT_POS = -1; // Max times of retrying step query static const int STEP_QUERY_RETRY_MAX_TIMES = 50; // Interval of retrying step query in millisecond @@ -68,11 +63,6 @@ private: std::string sql_; std::vector args_; - // The value indicates the row count of the result set - int rowCount_; - // Whether reach the end of this result set or not - bool isAfterLast_; - bool isStarted_; mutable std::shared_mutex mutex_; }; } // namespace NativeRdb diff --git a/relational_store/frameworks/native/rdb/mock/include/vdb_store_impl.h b/relational_store/frameworks/native/rdb/mock/include/vdb_store_impl.h deleted file mode 100644 index 97ddca10..00000000 --- a/relational_store/frameworks/native/rdb/mock/include/vdb_store_impl.h +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NATIVE_RDB_VDB_STORE_IMPL_H -#define NATIVE_RDB_VDB_STORE_IMPL_H - -#include -#include -#include -#include -#include - -#include "concurrent_map.h" -#include "rdb_store.h" -#include "rdb_store_config.h" -#include "rdb_store_impl.h" -#include "sqlite_connection_pool.h" -#include "sqlite_statement.h" - -namespace OHOS::NativeRdb { - -class RdbConnectionPool { -public: - explicit RdbConnectionPool(const RdbStoreConfig &storeConfig); - virtual ~RdbConnectionPool(); -}; - -class VdbStoreImpl : public RdbStoreImpl, public std::enable_shared_from_this { -public: - VdbStoreImpl(const RdbStoreConfig &config, int &errCode) : RdbStoreImpl(config, errCode) - { - } - - ~VdbStoreImpl() override - { - } - - // Interface to support in VDB - std::pair BeginTrans() override - { - return {}; - } - - int Commit(int64_t trxId) override - { - return 0; - } - - int RollBack(int64_t trxId) override - { - return 0; - } - - std::pair Execute(const std::string &sql, - const std::vector &bindArgs, int64_t trxId) override - { - return {}; - } - - int ExecuteSqlByTrxId( - const std::string &sql, const std::vector &bindArgs = {}, int64_t trxId = 0) - { - return 0; - } - - // Interface not to support in VDB - int Insert(int64_t &outRowId, const std::string &table, const ValuesBucket &values) override - { - return 0; - } - - int BatchInsert(int64_t& outInsertNum, const std::string& table, const std::vector& values) override - { - return 0; - } - - int Replace(int64_t &outRowId, const std::string &table, const ValuesBucket &initialValues) override - { - return 0; - } - - int InsertWithConflictResolution(int64_t &outRowId, const std::string &table, const ValuesBucket &values, - ConflictResolution conflictResolution) override - { - return 0; - } - - int Update(int &changedRows, const std::string &table, const ValuesBucket &values, const std::string &whereClause, - const std::vector &whereArgs) override - { - return 0; - } - - int Update(int &changedRows, const std::string &table, const ValuesBucket &values, const std::string &whereClause, - const std::vector &bindArgs) override - { - return 0; - } - - int UpdateWithConflictResolution(int &changedRows, const std::string &table, const ValuesBucket &values, - const std::string &whereClause, const std::vector &whereArgs, - ConflictResolution conflictResolution) override - { - return 0; - } - - int UpdateWithConflictResolution(int &changedRows, const std::string &table, const ValuesBucket &values, - const std::string &whereClause, const std::vector &bindArgs, - ConflictResolution conflictResolution) override - { - return 0; - } - - int Delete(int &deletedRows, const std::string &table, const std::string &whereClause, - const std::vector &whereArgs) override - { - return 0; - } - - int Delete(int &deletedRows, const std::string &table, const std::string &whereClause, - const std::vector &bindArgs) override - { - return 0; - } - - int ExecuteSql(const std::string& sql, const std::vector& bindArgs) override - { - return 0; - } - - int ExecuteAndGetLong(int64_t &outValue, const std::string &sql, const std::vector &bindArgs) override - { - return 0; - } - - int ExecuteAndGetString(std::string &outValue, const std::string &sql, - const std::vector &bindArgs) override - { - return 0; - } - - int ExecuteForLastInsertedRowId(int64_t &outValue, const std::string &sql, - const std::vector &bindArgs) override - { - return 0; - } - - int ExecuteForChangedRowCount(int64_t &outValue, const std::string &sql, - const std::vector &bindArgs) override - { - return 0; - } - - int Backup(const std::string &databasePath, const std::vector &destEncryptKey) override - { - return 0; - } - - int GetVersion(int &version) override - { - return 0; - } - - int SetVersion(int version) override - { - return 0; - } - - int BeginTransaction() override - { - return 0; - } - - int RollBack() override - { - return 0; - } - - int Commit() override - { - return 0; - } - - bool IsInTransaction() override - { - return 0; - } - - int Restore(const std::string &backupPath, const std::vector &newKey) override - { - return 0; - } - - std::shared_ptr QueryByStep(const std::string &sql, - const std::vector &sqlArgs) override - { - return nullptr; - } - - std::shared_ptr QueryByStep(const std::string &sql, const std::vector &args) override - { - return nullptr; - } - - std::shared_ptr Query( - const AbsRdbPredicates &predicates, const std::vector &columns) override - { - return nullptr; - } - - int Count(int64_t &outValue, const AbsRdbPredicates &predicates) override - { - return 0; - } - - int Update(int &changedRows, const ValuesBucket &values, const AbsRdbPredicates &predicates) override - { - return 0; - } - - int Delete(int &deletedRows, const AbsRdbPredicates &predicates) override - { - return 0; - } - - std::pair Attach( - const RdbStoreConfig &config, const std::string &attachName, int32_t waitTime = 2) override - { - return {}; - } - - std::pair Detach(const std::string &attachName, int32_t waitTime = 2) override - { - return {}; - } - -private: - std::shared_ptr rdConnectionPool_ = nullptr; -}; -} // namespace OHOS::NativeRdb -#endif diff --git a/relational_store/frameworks/native/rdb/mock/src/rdb_radar_reporter.cpp b/relational_store/frameworks/native/rdb/mock/src/rdb_radar_reporter.cpp new file mode 100644 index 00000000..192ee48b --- /dev/null +++ b/relational_store/frameworks/native/rdb/mock/src/rdb_radar_reporter.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "rdb_radar_reporter.h" +#include "rdb_errno.h" + +namespace OHOS::NativeRdb { + + +bool RdbRadar::hasHostPkg_ = false; +std::string RdbRadar::hostPkg_{ "" }; + +RdbRadar::RdbRadar(Scene scene, const char* funcName, std::string bundleName) : scene_(scene), funcName_(funcName) +{ +} + +RdbRadar::~RdbRadar() +{ +} + +RdbRadar& RdbRadar::operator=(int errCode) +{ + errCode_ = errCode; + return *this; +} + +RdbRadar::operator int() const +{ + return errCode_; +} + +void RdbRadar::LocalReport(int bizSence, const char* funcName, int state, int errCode) +{ + (void)scene_; + (void)funcName_; +} + +void RdbRadar::GetHostPkgInfo(std::string bundleName) +{ +} +} \ No newline at end of file diff --git a/relational_store/frameworks/native/rdb/src/abs_rdb_predicates.cpp b/relational_store/frameworks/native/rdb/src/abs_rdb_predicates.cpp index 8cc42bab..04fc3c62 100644 --- a/relational_store/frameworks/native/rdb/src/abs_rdb_predicates.cpp +++ b/relational_store/frameworks/native/rdb/src/abs_rdb_predicates.cpp @@ -174,7 +174,6 @@ const DistributedRdb::PredicatesMemo& AbsRdbPredicates::GetDistributedPredicates AbsRdbPredicates* AbsRdbPredicates::EqualTo(const std::string &field, const ValueObject &value) { - DISTRIBUTED_DATA_HITRACE("AbsRdbPredicates::EqualTo"); if (auto pval = std::get_if(&value.value)) { predicates_.AddOperation(DistributedRdb::EQUAL_TO, field, *pval); } diff --git a/relational_store/frameworks/native/rdb/src/abs_result_set.cpp b/relational_store/frameworks/native/rdb/src/abs_result_set.cpp index 85792844..9bca24ce 100644 --- a/relational_store/frameworks/native/rdb/src/abs_result_set.cpp +++ b/relational_store/frameworks/native/rdb/src/abs_result_set.cpp @@ -12,16 +12,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #define LOG_TAG "AbsResultSet" #include "abs_result_set.h" #include +#include +#include + #include "logger.h" #include "rdb_errno.h" #include "rdb_trace.h" #include "result_set.h" #include "sqlite_utils.h" + namespace OHOS { namespace NativeRdb { using namespace OHOS::Rdb; @@ -81,6 +86,16 @@ AbsResultSet::~AbsResultSet() int AbsResultSet::GetRowCount(int &count) { + count = rowCount_; + if (rowCount_ != NO_COUNT) { + return E_OK; + } + + if (isClosed_) { + LOG_ERROR("fail, result set E_ALREADY_CLOSED"); + return E_ALREADY_CLOSED; + } + return E_OK; } @@ -130,7 +145,6 @@ int AbsResultSet::InitColumnNames() int AbsResultSet::GetBlob(int columnIndex, std::vector& blob) { - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); ValueObject object; int errorCode = Get(columnIndex, object); if (errorCode != E_OK) { @@ -149,7 +163,6 @@ int AbsResultSet::GetBlob(int columnIndex, std::vector& blob) int AbsResultSet::GetString(int columnIndex, std::string &value) { - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); ValueObject object; int errorCode = Get(columnIndex, object); if (errorCode != E_OK) { @@ -167,7 +180,6 @@ int AbsResultSet::GetString(int columnIndex, std::string &value) int AbsResultSet::GetInt(int columnIndex, int &value) { - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); int64_t temp = 0; int errCode = GetLong(columnIndex, temp); if (errCode != E_OK) { @@ -179,7 +191,6 @@ int AbsResultSet::GetInt(int columnIndex, int &value) int AbsResultSet::GetLong(int columnIndex, int64_t& value) { - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); ValueObject object; int errorCode = Get(columnIndex, object); if (errorCode != E_OK) { @@ -197,7 +208,6 @@ int AbsResultSet::GetLong(int columnIndex, int64_t& value) int AbsResultSet::GetDouble(int columnIndex, double& value) { - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); ValueObject object; int errorCode = Get(columnIndex, object); if (errorCode != E_OK) { @@ -215,7 +225,7 @@ int AbsResultSet::GetDouble(int columnIndex, double& value) int AbsResultSet::IsColumnNull(int columnIndex, bool &isNull) { - ColumnType columnType; + ColumnType columnType = ColumnType::TYPE_NULL; int errCode = GetColumnType(columnIndex, columnType); if (errCode != E_OK) { LOG_ERROR("ret is %{public}d", errCode); @@ -266,19 +276,16 @@ int AbsResultSet::GetRowIndex(int &position) const int AbsResultSet::GoTo(int offset) { - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); return GoToRow(rowPos_ + offset); } int AbsResultSet::GoToFirstRow() { - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); return GoToRow(0); } int AbsResultSet::GoToLastRow() { - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); int rowCnt = 0; int ret = GetRowCount(rowCnt); if (ret != E_OK) { @@ -294,13 +301,11 @@ int AbsResultSet::GoToLastRow() int AbsResultSet::GoToNextRow() { - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); return GoToRow(rowPos_ + 1); } int AbsResultSet::GoToPreviousRow() { - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); return GoToRow(rowPos_ - 1); } @@ -328,16 +333,22 @@ int AbsResultSet::IsStarted(bool &result) const return E_OK; } -int AbsResultSet::IsEnded(bool &result) +std::pair AbsResultSet::IsEnded() { int rowCnt = 0; int ret = GetRowCount(rowCnt); if (ret != E_OK) { LOG_ERROR("Failed to GetRowCount, ret is %{public}d", ret); - return ret; + return { ret, true }; } - result = (rowCnt == 0) || (rowPos_ == rowCnt); - return E_OK; + return { E_OK, (rowCnt == 0) || (rowPos_ == rowCnt) }; +} + +int AbsResultSet::IsEnded(bool &result) +{ + int res = E_OK; + std::tie(res, result) = IsEnded(); + return res; } int AbsResultSet::GetColumnCount(int &count) @@ -423,12 +434,14 @@ int AbsResultSet::Close() // clear columnMap_ auto map = std::move(columnMap_); isClosed_ = true; + rowPos_ = INIT_POS; + rowCount_ = NO_COUNT; + columnCount_ = -1; return E_OK; } int AbsResultSet::GetAsset(int32_t col, ValueObject::Asset &value) { - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); ValueObject valueObject; int errorCode = Get(col, valueObject); if (errorCode != E_OK) { @@ -449,7 +462,6 @@ int AbsResultSet::GetAsset(int32_t col, ValueObject::Asset &value) int AbsResultSet::GetAssets(int32_t col, ValueObject::Assets &value) { - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); ValueObject valueObject; int errorCode = Get(col, valueObject); if (errorCode != E_OK) { @@ -470,7 +482,6 @@ int AbsResultSet::GetAssets(int32_t col, ValueObject::Assets &value) int AbsResultSet::GetFloat32Array(int32_t col, ValueObject::FloatVector &value) { - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); ValueObject valueObject; int errorCode = Get(col, valueObject); if (errorCode != E_OK) { diff --git a/relational_store/frameworks/native/rdb/src/abs_shared_result_set.cpp b/relational_store/frameworks/native/rdb/src/abs_shared_result_set.cpp index 4dc5dda5..125ad922 100644 --- a/relational_store/frameworks/native/rdb/src/abs_shared_result_set.cpp +++ b/relational_store/frameworks/native/rdb/src/abs_shared_result_set.cpp @@ -49,7 +49,7 @@ AbsSharedResultSet::~AbsSharedResultSet() int AbsSharedResultSet::GetRowCount(int &count) { - return E_OK; + return AbsResultSet::GetRowCount(count); } int32_t AbsSharedResultSet::OnGo(int oldRowIndex, int newRowIndex) @@ -88,57 +88,44 @@ int AbsSharedResultSet::GetColumnType(int columnIndex, ColumnType &columnType) return E_OK; } +int AbsSharedResultSet::UpdateBlockPos(int position, int rowCnt) +{ + auto block = GetBlock(); + auto ret = OnGo(rowPos_, position); + if (ret == E_OK) { + uint32_t startPos = block->GetStartPos(); + uint32_t blockPos = block->GetBlockPos(); + if (static_cast(position) != startPos + blockPos) { + block->SetBlockPos(position - startPos); + } + } + return ret; +} + int AbsSharedResultSet::GoToRow(int position) { - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); if (isClosed_) { return E_ALREADY_CLOSED; } - if (position == rowPos_) { - return E_OK; - } - - if (position < 0) { - LOG_ERROR("Invalid position %{public}d!", position); - return E_ERROR; - } int rowCnt = 0; auto ret = GetRowCount(rowCnt); - if (ret != E_OK || rowCnt == 0) { + if (ret != E_OK) { LOG_ERROR("GetRowCount ret is %{public}d, rowCount is %{public}d", ret, rowCnt); - return ret == E_OK ? E_ERROR : ret; + return ret; } - if (position >= rowCnt) { - rowPos_ = rowCnt; + if (position >= rowCnt || position < 0) { + rowPos_ = (position >= rowCnt && rowCnt != 0) ? rowCnt : rowPos_; + LOG_ERROR("position[%{public}d] rowCnt[%{public}d] rowPos[%{public}d]!", position, rowCnt, rowPos_); return E_ROW_OUT_RANGE; } - if (rowPos_ <= INIT_POS) { - rowPos_ = 0; - } - - auto block = GetBlock(); - if (block == nullptr || (uint32_t)position < block->GetStartPos() || - (uint32_t)position >= block->GetLastPos() || rowPos_ == rowCnt) { - ret = OnGo(rowPos_, position); - } else { - uint32_t blockPos = block->GetBlockPos(); - if (position > rowPos_) { - blockPos += (uint32_t)(position - rowPos_); - } else { - uint32_t offset = (uint32_t)(rowPos_ - position); - if (blockPos >= offset) { - blockPos -= offset; - } else { - LOG_ERROR("GoToRow failed of position= %{public}d, rowPos= %{public}d", position, rowPos_); - return E_ERROR; - } - } - block->SetBlockPos(blockPos); + if (position == rowPos_) { + return E_OK; } + ret = UpdateBlockPos(position, rowCnt); if (ret == E_OK) { rowPos_ = position; } @@ -152,7 +139,6 @@ int AbsSharedResultSet::GetString(int columnIndex, std::string &value) int AbsSharedResultSet::Get(int32_t col, ValueObject& value) { - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); auto block = GetBlock(); int errorCode = CheckState(col); if (errorCode != E_OK || block == nullptr) { 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 628e2d2e..176898ba 100644 --- a/relational_store/frameworks/native/rdb/src/cache_result_set.cpp +++ b/relational_store/frameworks/native/rdb/src/cache_result_set.cpp @@ -309,7 +309,7 @@ int CacheResultSet::GetAssets(int32_t col, ValueObject::Assets &value) int CacheResultSet::GetFloat32Array(int32_t index, ValueObject::FloatVector &vecs) { - return E_NOT_SUPPORTED; + return E_NOT_SUPPORT; } int CacheResultSet::Get(int32_t col, ValueObject &value) diff --git a/relational_store/frameworks/native/rdb/src/connection.cpp b/relational_store/frameworks/native/rdb/src/connection.cpp index 437512a0..48d5c374 100644 --- a/relational_store/frameworks/native/rdb/src/connection.cpp +++ b/relational_store/frameworks/native/rdb/src/connection.cpp @@ -14,10 +14,13 @@ */ #include "connection.h" +#include "rdb_common.h" #include "rdb_errno.h" #include "rdb_store_config.h" namespace OHOS::NativeRdb { static Connection::Creator g_creators[DB_BUTT] = { nullptr, nullptr }; +static Connection::Repairer g_repairers[DB_BUTT] = { nullptr, nullptr }; +static Connection::Deleter g_fileDeleter[DB_BUTT] = { nullptr, nullptr }; std::pair> Connection::Create(const RdbStoreConfig &config, bool isWriter) { auto dbType = config.GetDBType(); @@ -32,6 +35,34 @@ std::pair> Connection::Create(const RdbStoreCon return creator(config, isWriter); } +int32_t Connection::Repair(const RdbStoreConfig &config) +{ + auto dbType = config.GetDBType(); + if (dbType < static_cast(DB_SQLITE) || dbType >= static_cast(DB_BUTT)) { + return E_INVALID_ARGS; + } + auto repairer = g_repairers[dbType]; + if (repairer == nullptr) { + return E_ERROR; + } + + return repairer(config); +} + +void Connection::DeleteDbFile(const RdbStoreConfig &config) +{ + auto dbType = config.GetDBType(); + if (dbType < static_cast(DB_SQLITE) || dbType >= static_cast(DB_BUTT)) { + return; + } + auto deleter = g_fileDeleter[dbType]; + if (deleter == nullptr) { + return; + } + + deleter(config); +} + int32_t Connection::RegisterCreator(int32_t dbType, Creator creator) { if (dbType < static_cast(DB_SQLITE) || dbType >= static_cast(DB_BUTT)) { @@ -40,10 +71,37 @@ int32_t Connection::RegisterCreator(int32_t dbType, Creator creator) if (g_creators[dbType] != nullptr) { return E_OK; } + g_creators[dbType] = creator; return E_OK; } +int32_t Connection::RegisterRepairer(int32_t dbType, Repairer repairer) +{ + if (dbType < static_cast(DB_SQLITE) || dbType >= static_cast(DB_BUTT)) { + return E_INVALID_ARGS; + } + if (g_repairers[dbType] != nullptr) { + return E_OK; + } + + g_repairers[dbType] = repairer; + return E_OK; +} + +int32_t Connection::RegisterFileDeleter(int32_t dbType, Deleter deleter) +{ + if (dbType < static_cast(DB_SQLITE) || dbType >= static_cast(DB_BUTT)) { + return E_INVALID_ARGS; + } + if (g_fileDeleter[dbType] != nullptr) { + return E_OK; + } + + g_fileDeleter[dbType] = deleter; + return E_OK; +} + int Connection::SetId(int id) { id_ = id; diff --git a/relational_store/frameworks/native/rdb/src/grd_api_manager.cpp b/relational_store/frameworks/native/rdb/src/grd_api_manager.cpp index cfd11f6a..e952ffe2 100644 --- a/relational_store/frameworks/native/rdb/src/grd_api_manager.cpp +++ b/relational_store/frameworks/native/rdb/src/grd_api_manager.cpp @@ -33,6 +33,7 @@ void GRD_DBApiInitEnhance(GRD_APIInfo &GRD_DBApiInfo) #ifndef _WIN32 GRD_DBApiInfo.DBOpenApi = (DBOpen)dlsym(g_library, "GRD_DBOpen"); GRD_DBApiInfo.DBCloseApi = (DBClose)dlsym(g_library, "GRD_DBClose"); + GRD_DBApiInfo.DBRepairApi = (DBRepair)dlsym(g_library, "GRD_DBRepair"); GRD_DBApiInfo.DBSqlPrepare = (DBSqlPrepare)dlsym(g_library, "GRD_SqlPrepare"); GRD_DBApiInfo.DBSqlReset = (DBSqlReset)dlsym(g_library, "GRD_SqlReset"); GRD_DBApiInfo.DBSqlFinalize = (DBSqlFinalize)dlsym(g_library, "GRD_SqlFinalize"); @@ -55,6 +56,10 @@ void GRD_DBApiInitEnhance(GRD_APIInfo &GRD_DBApiInfo) GRD_DBApiInfo.DBSqlColInt64 = (DBSqlColInt64)dlsym(g_library, "GRD_SqlColumnInt64"); GRD_DBApiInfo.DBSqlColDouble = (DBSqlColDouble)dlsym(g_library, "GRD_SqlColumnDouble"); GRD_DBApiInfo.DBSqlColumnFloatVector = (DBSqlColumnFloatVector)dlsym(g_library, "GRD_SqlColumnFloatVector"); + GRD_DBApiInfo.DBBackupApi = (DBBackup)dlsym(g_library, "GRD_DBBackup"); + GRD_DBApiInfo.DBRestoreApi = (DBRestore)dlsym(g_library, "GRD_DBRestore"); + GRD_DBApiInfo.DBGetConfigApi = (DBGetConfig)dlsym(g_library, "GRD_GetConfig"); + GRD_DBApiInfo.DBSetConfigApi = (DBSetConfig)dlsym(g_library, "GRD_SetConfig"); #endif } diff --git a/relational_store/frameworks/native/rdb/src/rd_connection.cpp b/relational_store/frameworks/native/rdb/src/rd_connection.cpp index bcb3b777..0b6fdb25 100644 --- a/relational_store/frameworks/native/rdb/src/rd_connection.cpp +++ b/relational_store/frameworks/native/rdb/src/rd_connection.cpp @@ -16,40 +16,78 @@ #include "rd_connection.h" #include "logger.h" -#include "rdb_errno.h" #include "rd_statement.h" - +#include "rdb_errno.h" +#include "sqlite_global_config.h" namespace OHOS { namespace NativeRdb { using namespace OHOS::Rdb; +__attribute__((used)) +const int32_t RdConnection::regCreator_ = Connection::RegisterCreator(DB_VECTOR, RdConnection::Create); +const int32_t RdConnection::regRepairer_ = Connection::RegisterRepairer(DB_VECTOR, RdConnection::Repair); +const int32_t RdConnection::regFileDeleter_ = + Connection::RegisterFileDeleter(DB_VECTOR, RdConnection::DeleteDbFile); -std::shared_ptr RdConnection::Open(const RdbStoreConfig &config, bool isWriteConnection, int &errCode) +std::pair> RdConnection::Create(const RdbStoreConfig& config, bool isWrite) { + std::pair> result; + auto& [errCode, conn] = result; for (size_t i = 0; i < ITERS_COUNT; i++) { - std::shared_ptr connection = std::make_shared(isWriteConnection); + std::shared_ptr connection = std::make_shared(isWrite); if (connection == nullptr) { LOG_ERROR("SqliteConnection::Open new failed, connection is nullptr"); - return nullptr; + return result; } errCode = connection->InnerOpen(config); if (errCode == E_OK) { - return connection; + conn = connection; + break; } } - return nullptr; + return result; +} + +int32_t RdConnection::Repair(const RdbStoreConfig& config) +{ + std::string dbPath = ""; + auto errCode = SqliteGlobalConfig::GetDbPath(config, dbPath); + if (errCode != E_OK) { + LOG_ERROR("Can not get db path"); + return errCode; + } + errCode = RdUtils::RdDbRepair(dbPath.c_str(), GRD_OPEN_CONFIG_STR); + if (errCode != E_OK) { + LOG_ERROR("Fail to repair db"); + } + return errCode; } -RdConnection::RdConnection(bool isWriteConnection) - : RdbConnection(isWriteConnection), inTransaction_(false) +static std::vector rdPostFixes = { + "", + ".redo", + ".undo", + ".ctrl", + ".ctrl.dwr", + ".safe", + ".map", +}; + +void RdConnection::DeleteDbFile(const RdbStoreConfig& config) { + auto path = config.GetPath(); + for (std::string &postFix : rdPostFixes) { + std::string shmFilePath = path + postFix; + if (access(shmFilePath.c_str(), F_OK) == 0) { + remove(shmFilePath.c_str()); + } + } } +RdConnection::RdConnection(bool isWriter) : isWriter_(isWriter) {} + RdConnection::~RdConnection() { if (dbHandle_ != nullptr) { - if (statement_ != nullptr) { - statement_ = nullptr; - } int errCode = RdUtils::RdDbClose(dbHandle_, 0); if (errCode != E_OK) { LOG_ERROR("~RdConnection ~RdConnection: could not close database err = %{public}d", errCode); @@ -61,7 +99,7 @@ RdConnection::~RdConnection() int RdConnection::InnerOpen(const RdbStoreConfig &config) { std::string dbPath = ""; - int errCode = GetDbPath(config, dbPath); + auto errCode = SqliteGlobalConfig::GetDbPath(config, dbPath); if (errCode != E_OK) { LOG_ERROR("Can not get db path"); return errCode; @@ -71,119 +109,114 @@ int RdConnection::InnerOpen(const RdbStoreConfig &config) LOG_ERROR("Can not open rd db"); return errCode; } - statement_ = std::make_shared(); return errCode; } -int RdConnection::Prepare(const std::string &sql, bool &outIsReadOnly) +int32_t RdConnection::OnInitialize() { - if (statement_ == nullptr) { - LOG_ERROR("RdConnection Prepare meets empty statement"); - return E_ERROR; - } - int ret = std::static_pointer_cast(statement_)->Prepare(dbHandle_, sql); + return E_NOT_SUPPORT; +} + +std::pair RdConnection::CreateStatement(const std::string& sql, Connection::SConn conn) +{ + auto stmt = std::make_shared(); + stmt->conn_ = conn; + stmt->setPragmas_["user_version"] = ([this](const int &value) -> int32_t { + return RdUtils::RdDbSetVersion(dbHandle_, GRD_CONFIG_USER_VERSION, value); + }); + stmt->getPragmas_["user_version"] = ([this](int &version) -> int32_t { + return RdUtils::RdDbGetVersion(dbHandle_, GRD_CONFIG_USER_VERSION, version); + }); + int32_t ret = stmt->Prepare(dbHandle_, sql); if (ret != E_OK) { - LOG_ERROR("RdConnection Unable to prepare statement"); - return ret; + return { ret, nullptr }; } - outIsReadOnly = IsWriteConnection(); - return E_OK; + return { ret, stmt }; } -int RdConnection::PrepareAndBind(const std::string &sql, const std::vector &bindArgs) +int32_t RdConnection::GetDBType() const { - if (statement_ == nullptr) { - LOG_ERROR("RdConnection PrepareAndBind meets empty statement"); - return E_ERROR; - } - int errCode = std::static_pointer_cast(statement_)->Prepare(dbHandle_, sql); - if (errCode != E_OK) { - LOG_ERROR("PrepareAndBind unable to prepare stmt : err %{public}d", errCode); - return errCode; - } - return statement_->BindArguments(bindArgs); + return DB_VECTOR; } -int RdConnection::ExecuteSql(const std::string &sql, const std::vector &bindArgs) +bool RdConnection::IsWriter() const { - int ret = PrepareAndBind(sql, bindArgs); - if (ret != E_OK) { - LOG_ERROR("RdConnection unable to prepare and bind stmt : err %{public}d", ret); - return ret; - } - ret = statement_->Step(); - if (ret != E_OK && ret != E_NO_MORE_ROWS) { - LOG_ERROR("RdConnection Execute : err %{public}d", ret); - statement_->ResetStatementAndClearBindings(); - return ret; - } - return statement_->ResetStatementAndClearBindings(); + return isWriter_; } -std::shared_ptr RdConnection::BeginStepQuery(int &errCode, const std::string &sql, - const std::vector &args) const +int32_t RdConnection::ReSetKey(const RdbStoreConfig& config) { - if (stepStatement_ == nullptr) { - LOG_ERROR("RdConnection meets unexpected null"); - errCode = E_ROW_OUT_RANGE; - } - errCode = std::static_pointer_cast(stepStatement_)->Prepare(dbHandle_, sql); - if (errCode != E_OK) { - return nullptr; - } - errCode = stepStatement_->BindArguments(args); - if (errCode != E_OK) { - return nullptr; - } - return stepStatement_; + return E_NOT_SUPPORT; } -int RdConnection::DesFinalize() +int32_t RdConnection::TryCheckPoint() { - if (statement_ == nullptr) { - LOG_ERROR("RdConnection DesFinalize meets empty statement"); - return E_ERROR; - } - int ret = 0; - ret = statement_->Finalize(); - if (ret != E_OK) { - LOG_ERROR("RdConnection meets unexpected null"); - return ret; - } - if (stepStatement_ == nullptr) { - return E_OK; - } - ret = stepStatement_->Finalize(); - if (ret != E_OK) { - LOG_ERROR("RdConnection unable to finalize statement"); - return ret; - } - if (dbHandle_ != nullptr) { - ret = RdUtils::RdDbClose(dbHandle_, 0); - } - if (ret != E_OK) { - LOG_ERROR("RdConnection unable to close db handle"); - } - return ret; + return E_NOT_SUPPORT; } -int RdConnection::EndStepQuery() +int32_t RdConnection::LimitWalSize() { - if (stepStatement_ == nullptr) { - LOG_ERROR("RdConnection meets unexpected null"); - return E_ALREADY_CLOSED; - } - return stepStatement_->ResetStatementAndClearBindings(); + return E_NOT_SUPPORT; +} + +int32_t RdConnection::ConfigLocale(const std::string& localeStr) +{ + return E_NOT_SUPPORT; +} + +int32_t RdConnection::CleanDirtyData(const std::string& table, uint64_t cursor) +{ + return E_NOT_SUPPORT; +} + +int32_t RdConnection::SubscribeTableChanges(const Connection::Notifier& notifier) +{ + return E_NOT_SUPPORT; +} + +int32_t RdConnection::GetMaxVariable() const +{ + return MAX_VARIABLE_NUM; +} + +int32_t RdConnection::GetJournalMode() +{ + return E_NOT_SUPPORT; +} + +int32_t RdConnection::ClearCache() +{ + return E_NOT_SUPPORT; } -void RdConnection::SetInTransaction(bool transaction) +int32_t RdConnection::Subscribe(const std::string& event, + const std::shared_ptr& observer) { - inTransaction_ = transaction; + return E_NOT_SUPPORT; } -bool RdConnection::IsInTransaction() +int32_t RdConnection::Unsubscribe(const std::string& event, + const std::shared_ptr& observer) { - return inTransaction_; + return E_NOT_SUPPORT; +} + +int32_t RdConnection::Backup(const std::string &databasePath, const std::vector &destEncryptKey) +{ + uint32_t size = destEncryptKey.size(); + if (size != 0) { + return RdUtils::RdDbBackup(dbHandle_, databasePath.c_str(), const_cast(&destEncryptKey[0]), size); + } + return RdUtils::RdDbBackup(dbHandle_, databasePath.c_str(), nullptr, 0); +} + +int32_t RdConnection::Restore(const std::string &databasePath, const std::vector &destEncryptKey) +{ + uint32_t size = destEncryptKey.size(); + if (size != 0) { + return RdUtils::RdDbRestore(dbHandle_, databasePath.c_str(), const_cast(&destEncryptKey[0]), size); + } + return RdUtils::RdDbRestore(dbHandle_, databasePath.c_str(), nullptr, 0); } } // namespace NativeRdb diff --git a/relational_store/frameworks/native/rdb/src/rd_result_set.cpp b/relational_store/frameworks/native/rdb/src/rd_result_set.cpp deleted file mode 100644 index 597f6f45..00000000 --- a/relational_store/frameworks/native/rdb/src/rd_result_set.cpp +++ /dev/null @@ -1,377 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#define LOG_TAG "RdSharedResultSet" -#include "rd_result_set.h" -#include "step_result_set.h" -#include -#include "logger.h" -#include "rdb_errno.h" -#include "rdb_sql_utils.h" -#include "rdb_trace.h" -#include "sqlite_utils.h" - -namespace OHOS { -namespace NativeRdb { -using namespace OHOS::Rdb; - -RdSharedResultSet::RdSharedResultSet(std::shared_ptr connectionPool, const std::string &sql, - const std::vector& selectionArgs) - : statement_(nullptr), args_(std::move(selectionArgs)), sql_(sql), - rdConnectionPool_(std::move(connectionPool)), rowCount_(INIT_POS), isAfterLast_(false) -{ - int errCode = PrepareStep(); - if (errCode) { - LOG_ERROR("step resultset ret %{public}d", errCode); - } -} - -RdSharedResultSet::RdSharedResultSet(std::shared_ptr connectionPool, const std::string &sql_, - const std::vector& selectionArgs, int rowCount) - : statement_(nullptr), args_(std::move(selectionArgs)), sql_(sql_), - rdConnectionPool_(std::move(connectionPool)), rowCount_(rowCount), isAfterLast_(false) -{ -} - -RdSharedResultSet::~RdSharedResultSet() -{ - Close(); -} - -std::pair> RdSharedResultSet::GetColumnNames() -{ - if (isClosed_) { - return { E_ALREADY_CLOSED, {} }; - } - std::vector columnNames; - int errCode = PrepareStep(); - if (errCode != E_OK) { - LOG_ERROR("get all column names Step ret %{public}d", errCode); - return { errCode, {} }; - } - auto [statement, connection] = GetStatement(); - if (statement == nullptr) { - return { E_ALREADY_CLOSED, {} }; - } - bool needReset = false; - if (rowPos_ == INIT_POS) { - errCode = statement->Step(); - if (errCode != E_OK && errCode != E_NO_MORE_ROWS) { - return { errCode, {} }; - } - needReset = true; - } - int columnCount = 0; - errCode = statement->GetColumnCount(columnCount); - if (errCode != E_OK) { - LOG_ERROR("GetColumnCount errCode is %{public}d", errCode); - return { errCode, {} }; - } - columnNames.clear(); - for (int i = 0; i < columnCount; i++) { - std::string columnName; - errCode = statement->GetColumnName(i, columnName); - if (errCode != E_OK) { - columnNames.clear(); - LOG_ERROR("GetColumnName errCode is %{public}d", errCode); - return { errCode, {} }; - } - columnNames.push_back(columnName); - } - if (needReset) { - rowPos_ = INIT_POS; - errCode = statement->ResetStatementAndClearBindings(); - } - - return { errCode, std::move(columnNames) }; -} - -int RdSharedResultSet::GetColumnType(int columnIndex, ColumnType &columnType) -{ - auto [statement, connection] = GetStatement(); - if (statement == nullptr) { - LOG_ERROR("the resultSet is closed"); - return E_ALREADY_CLOSED; - } - if (rowPos_ == INIT_POS) { - LOG_ERROR("query not executed."); - return E_ROW_OUT_RANGE; - } - int outputType; - int errCode = statement->GetColumnType(columnIndex, outputType); - if (errCode != E_OK) { - LOG_ERROR("GetColumnType errCode is %{public}d", errCode); - return errCode; - } - columnType = static_cast(outputType); - return E_OK; -} - -int RdSharedResultSet::GetRowCount(int &count) -{ - if (rowCount_ != INIT_POS) { - count = rowCount_; - return E_OK; - } - int oldPosition = 0; - // Get the start position of the query result - GetRowIndex(oldPosition); - int ret = E_OK; - while (ret == E_OK) { - ret = GoToNextRow(); - if (ret != E_OK) { - break; - } - } - count = rowCount_; - // Reset the start position of the query result - GoToRow(oldPosition); - return E_OK; -} - -int RdSharedResultSet::GoToRow(int position) -{ - // If the moved position is less than zero, reset the result and return an error - if (position < 0) { - LOG_DEBUG("position is %{public}d", position); - Reset(); - return E_ERROR; - } - if (position == rowPos_) { - return E_OK; - } - if (position < rowPos_) { - Reset(); - return GoToRow(position); - } - while (position != rowPos_) { - int errCode = GoToNextRow(); - if (errCode != E_OK) { - LOG_ERROR("GoToNextRow errCode is %{public}d", errCode); - return errCode; - } - } - return E_OK; -} - -int RdSharedResultSet::GoToNextRow() -{ - if (isClosed_) { - LOG_ERROR("the resultSet is closed"); - return E_ALREADY_CLOSED; - } - int errCode = PrepareStep(); - if (errCode != E_OK) { - LOG_ERROR("go to next row step errCode is %{public}d", errCode); - return errCode; - } - auto [statement, conn] = GetStatement(); - if (statement == nullptr) { - LOG_ERROR("the resultSet is closed"); - return E_ALREADY_CLOSED; - } - errCode = statement->Step(); - if (errCode == E_OK) { - rowPos_++; - return E_OK; - } else if (errCode == E_NO_MORE_ROWS) { - isAfterLast_ = true; - RdSharedResultSet::rowCount_ = rowPos_ + 1; - RdSharedResultSet::FinishStep(); - rowPos_ = RdSharedResultSet::rowCount_; - return E_NO_MORE_ROWS; - } else { - LOG_ERROR("step errCode is %{public}d", errCode); - RdSharedResultSet::FinishStep(); - rowPos_ = RdSharedResultSet::rowCount_; - return errCode; - } -} - -int RdSharedResultSet::PrepareStep() -{ - if (statement_ != nullptr) { - LOG_INFO("statement_ is not nullptr"); - return E_OK; - } - if (SqliteUtils::GetSqlStatementType(sql_) != SqliteUtils::STATEMENT_SELECT) { - LOG_ERROR("not a select sql_!"); - return E_NOT_SELECT; - } - - auto pool = rdConnectionPool_; - if (pool == nullptr) { - return E_ALREADY_CLOSED; - } - - auto connection = pool->AcquireConnection(true, 0); - if (connection == nullptr) { - LOG_ERROR("rdConnectionPool_ AcquireConnection failed!"); - return E_DATABASE_BUSY; - } - auto statement = RdStatement::CreateStatement(std::static_pointer_cast(connection), sql_); - if (statement == nullptr) { - return E_STATEMENT_NOT_PREPARED; - } - int errCode = statement->Prepare(std::static_pointer_cast(connection)->GetDbHandle(), sql_); - if (errCode != E_OK) { - LOG_ERROR("Prepare arg faild! Ret is %{public}d", errCode); - statement = nullptr; - return errCode; - } - errCode = statement->BindArguments(args_); - if (errCode != E_OK) { - LOG_ERROR("Bind arg faild! Ret is %{public}d", errCode); - statement->ResetStatementAndClearBindings(); - statement = nullptr; - return errCode; - } - statement_ = std::move(statement); - conn_ = connection; - return E_OK; -} - -int RdSharedResultSet::Close() -{ - if (isClosed_) { - return E_OK; - } - auto args = std::move(args_); - statement_ = nullptr; - isClosed_ = true; - return FinishStep(); -} - -/** - * Release resource of step result set, this method can be called more than once - */ -int RdSharedResultSet::FinishStep() -{ - auto [statement, connection] = GetStatement(); - if (statement != nullptr) { - statement->ResetStatementAndClearBindings(); - statement_ = nullptr; - if (statement_ != nullptr) { - statement_ = nullptr; - } - if (conn_ != nullptr) { - rdConnectionPool_->ReleaseConnection(conn_); - conn_ = nullptr; - } - if (connection != nullptr) { - connection = nullptr; - } - } - rowPos_ = INIT_POS; - return E_OK; -} - -/** - * Reset the statement - */ -void RdSharedResultSet::Reset() -{ - FinishStep(); - isAfterLast_ = false; -} - - -/** - * Checks whether the result set is positioned after the last row - */ -int RdSharedResultSet::IsEnded(bool &result) -{ - result = isAfterLast_; - return E_OK; -} - -/** - * Checks whether the result set is moved - */ -int RdSharedResultSet::IsStarted(bool &result) const -{ - result = (rowPos_ != INIT_POS); - return E_OK; -} - -/** - * Check whether the result set is in the first row - */ -int RdSharedResultSet::IsAtFirstRow(bool &result) const -{ - result = (rowPos_ == 0); - return E_OK; -} - -int RdSharedResultSet::Get(int32_t col, ValueObject &value) -{ - return GetValue(col, value); -} - -int RdSharedResultSet::GetSize(int columnIndex, size_t &size) -{ - auto [statement, conn] = GetStatement(); - if (statement == nullptr) { - LOG_ERROR("resultSet closed"); - return E_ALREADY_CLOSED; - } - - if (rowPos_ == INIT_POS) { - size = 0; - return E_ROW_OUT_RANGE; - } - - return statement->GetSize(columnIndex, size); -} - -template -int RdSharedResultSet::GetValue(int32_t col, T &value) -{ - auto [errCode, object] = GetValueObject(col, ValueObject::TYPE_INDEX); - if (errCode != E_OK) { - LOG_ERROR("ret is %{public}d", errCode); - return errCode; - } - value = object; - return E_OK; -} - -std::pair RdSharedResultSet::GetValueObject(int32_t col, size_t index) -{ - auto [statement, conn] = GetStatement(); - if (statement == nullptr) { - return { E_ALREADY_CLOSED, ValueObject() }; - } - - if (rowPos_ == INIT_POS) { - return { E_ROW_OUT_RANGE, ValueObject() }; - } - - ValueObject value; - auto ret = statement->GetColumn(col, value); - if (index < ValueObject::TYPE_MAX && value.value.index() != index) { - return { E_INVALID_COLUMN_TYPE, ValueObject() }; - } - return { ret, std::move(value) }; -} - -std::pair, std::shared_ptr> RdSharedResultSet::GetStatement() -{ - if (isClosed_) { - return { nullptr, nullptr }; - } - return {statement_, conn_}; -} -} // namespace NativeRdb -} // namespace OHOS diff --git a/relational_store/frameworks/native/rdb/src/rd_statement.cpp b/relational_store/frameworks/native/rdb/src/rd_statement.cpp index 5ca7e03f..1895e71c 100644 --- a/relational_store/frameworks/native/rdb/src/rd_statement.cpp +++ b/relational_store/frameworks/native/rdb/src/rd_statement.cpp @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#define LOG_TAG "RdSharedResultSet" +#define LOG_TAG "RdStatement" #include "rd_statement.h" #include @@ -23,31 +23,102 @@ #include "raw_data_parser.h" #include "rdb_errno.h" #include "rd_utils.h" -#include "rdb_connection.h" +#include "rd_connection.h" +#include "sqlite_global_config.h" +#include "sqlite_utils.h" namespace OHOS { namespace NativeRdb { using namespace OHOS::Rdb; +RdStatement::RdStatement() +{ +} -std::shared_ptr RdStatement::CreateStatement( - std::shared_ptr connection, const std::string &sql) +RdStatement::~RdStatement() { - (void)connection; - (void)sql; - return std::make_shared(); + Finalize(); } -RdStatement::RdStatement() +constexpr size_t PRAGMA_VERSION_SQL_LEN = __builtin_strlen(GlobalExpr::PRAGMA_VERSION); + +static bool TryEatSymbol(const std::string &str, char symbol, size_t &curIdx) { + size_t idx = curIdx; + while (idx < str.length()) { + if (str[idx] == ' ') { + idx++; + continue; + } + if (str[idx] == symbol) { + curIdx = idx + 1; + return true; + } + break; + } + return false; } -RdStatement::~RdStatement() +static int TryEatNumber(const std::string &str, int &outNumber, size_t &curIdx) { - Finalize(); + size_t idx = curIdx; + uint32_t numSpace = 0; + bool hasMeetDigit = false; + while (idx < str.length()) { + if (str[idx] == ' ' && !hasMeetDigit) { + idx++; + numSpace++; + continue; + } + if (isdigit(str[idx]) != 0) { + idx++; + hasMeetDigit = true; + continue; + } + // Indicates that meet first not-digit-char + break; + } + if (!hasMeetDigit) { + return false; + } + outNumber = atoi(str.substr(curIdx).c_str()); + curIdx = idx; + return true; +} + +static int EndWithNull(const std::string &str, size_t curIdx) +{ + size_t idx = curIdx; + while (idx < str.length()) { + if (str[idx] == ' ') { + idx++; + continue; + } + return false; + } + return true; } int RdStatement::Prepare(GRD_DB *db, const std::string &newSql) { + if (newSql.find(GlobalExpr::PRAGMA_VERSION) == 0) { + // Indicates that sql is start with pragma version + if (newSql.length() == PRAGMA_VERSION_SQL_LEN) { + // Indicates that sql is to get version + sql_ = newSql; + readOnly_ = true; + return E_OK; + } + size_t curIdx = PRAGMA_VERSION_SQL_LEN; + int version = 0; + if ((!TryEatSymbol(newSql, '=', curIdx)) || (!TryEatNumber(newSql, version, curIdx)) || + (!EndWithNull(newSql, curIdx) && !TryEatSymbol(newSql, ';', curIdx))) { + return E_INCORRECT_SQL; + } + + readOnly_ = false; + sql_ = newSql; + return setPragmas_["user_version"](version); + } if (sql_.compare(newSql) == 0) { return E_OK; } @@ -63,6 +134,18 @@ int RdStatement::Prepare(GRD_DB *db, const std::string &newSql) Finalize(); // Finalize original stmt sql_ = newSql; stmtHandle_ = tmpStmt; + readOnly_ = SqliteUtils::GetSqlStatementType(newSql) == SqliteUtils::STATEMENT_SELECT; + if (readOnly_) { + ret = Step(); + if (ret != E_OK && ret != E_NO_MORE_ROWS) { + return ret; + } + GetProperties(); + ret = Reset(); + if (ret != E_OK) { + return ret; + } + } return E_OK; } @@ -79,17 +162,10 @@ int RdStatement::Finalize() stmtHandle_ = nullptr; sql_ = ""; columnCount_ = 0; + readOnly_ = false; return E_OK; } -int RdStatement::BindArguments(const std::vector &bindArgs) const -{ - if (bindArgs.empty()) { - return E_OK; - } - return InnerBindArguments(bindArgs); -} - int RdStatement::InnerBindBlobTypeArgs(const ValueObject &arg, uint32_t index) const { int ret = E_OK; @@ -108,7 +184,7 @@ int RdStatement::InnerBindBlobTypeArgs(const ValueObject &arg, uint32_t index) c break; } case ValueObjectType::TYPE_ASSET: { - Asset asset; + ValueObject::Asset asset; arg.GetAsset(asset); auto rawData = RawDataParser::PackageRawData(asset); ret = RdUtils::RdSqlBindBlob(stmtHandle_, index, static_cast(rawData.data()), @@ -116,7 +192,7 @@ int RdStatement::InnerBindBlobTypeArgs(const ValueObject &arg, uint32_t index) c break; } case ValueObjectType::TYPE_ASSETS: { - Assets assets; + ValueObject::Assets assets; arg.GetAssets(assets); auto rawData = RawDataParser::PackageRawData(assets); ret = RdUtils::RdSqlBindBlob(stmtHandle_, index, static_cast(rawData.data()), @@ -124,7 +200,7 @@ int RdStatement::InnerBindBlobTypeArgs(const ValueObject &arg, uint32_t index) c break; } case ValueObjectType::TYPE_VECS: { - FloatVector vectors; + ValueObject::FloatVector vectors; arg.GetVecs(vectors); ret = RdUtils::RdSqlBindFloatVector(stmtHandle_, index, static_cast(vectors.data()), vectors.size(), nullptr); @@ -140,11 +216,36 @@ int RdStatement::InnerBindBlobTypeArgs(const ValueObject &arg, uint32_t index) c return ret; } -int RdStatement::InnerBindArguments(const std::vector &bindArgs) const +int RdStatement::IsValid(int index) const +{ + if (stmtHandle_ == nullptr) { + LOG_ERROR("statement already close."); + return E_ALREADY_CLOSED; + } + if (index < 0) { + LOG_ERROR("invalid index %{public}d", index); + return E_INVALID_ARGS; + } + if (index >= columnCount_) { + LOG_ERROR("index (%{public}d) >= columnCount (%{public}d)", index, columnCount_); + return E_COLUMN_OUT_RANGE; + } + return E_OK; +} + +int32_t RdStatement::Prepare(const std::string& sql) +{ + if (dbHandle_ == nullptr) { + return E_ERROR; + } + return Prepare(dbHandle_, sql); +} + +int32_t RdStatement::Bind(const std::vector& args) { uint32_t index = 1; int ret = E_OK; - for (auto arg : bindArgs) { + for (auto &arg : args) { switch (arg.GetType()) { case ValueObjectType::TYPE_NULL: { ret = RdUtils::RdSqlBindNull(stmtHandle_, index); @@ -176,264 +277,153 @@ int RdStatement::InnerBindArguments(const std::vector &bindArgs) co return E_OK; } -int RdStatement::ResetStatementAndClearBindings() const +int32_t RdStatement::Step() { if (stmtHandle_ == nullptr) { return E_OK; } - int ret = RdUtils::RdSqlReset(stmtHandle_); - if (ret != E_OK) { - LOG_ERROR("reset ret is %{public}d", ret); - } - return ret; -} - -int RdStatement::Step() const -{ return RdUtils::RdSqlStep(stmtHandle_); } -int RdStatement::GetColumnCount(int &count) const +int32_t RdStatement::Reset() { if (stmtHandle_ == nullptr) { - LOG_ERROR("statement already close."); - return E_ALREADY_CLOSED; + return E_OK; } - count = RdUtils::RdSqlColCnt(stmtHandle_); - return E_OK; + return RdUtils::RdSqlReset(stmtHandle_); } -int RdStatement::GetColumnName(int index, std::string &columnName) const +int32_t RdStatement::Execute(const std::vector& args) { - int ret = IsValid(index); + if (!readOnly_ && strcmp(sql_.c_str(), GlobalExpr::PRAGMA_VERSION) == 0) { + // It has already set version in prepare procedure + // Current modification is only temporary for unification between rd and sqlite, + // rd kernal will support pragma in later version + return E_OK; + } + int ret = Bind(args); if (ret != E_OK) { + LOG_ERROR("RdConnection unable to prepare and bind stmt : err %{public}d", ret); return ret; } - const char *name = RdUtils::RdSqlColName(stmtHandle_, index); - if (name == nullptr) { - LOG_ERROR("column_name is null."); - return E_ERROR; + ret = Step(); + if (ret != E_OK && ret != E_NO_MORE_ROWS) { + LOG_ERROR("RdConnection Execute : err %{public}d", ret); } - columnName = std::string(name); - return E_OK; + return ret; } -int RdStatement::GetColumnType(int index, int &columnType) const +std::pair RdStatement::ExecuteForValue(const std::vector& args) { - int ret = IsValid(index); - if (ret != E_OK) { - return ret; - } - ColumnType type = RdUtils::RdSqlColType(stmtHandle_, index); - switch (type) { - case ColumnType::TYPE_INTEGER: - case ColumnType::TYPE_FLOAT: - case ColumnType::TYPE_NULL: - case ColumnType::TYPE_STRING: - columnType = static_cast(type); - return E_OK; - case ColumnType::TYPE_BLOB: { - // Attention! Grd can not distinguish assets type and blob type - columnType = static_cast(type); - return E_OK; - } - case ColumnType::TYPE_FLOAT32_ARRAY: { - columnType = static_cast(type); - return E_OK; + int ret = E_OK; + if (readOnly_ && strcmp(sql_.c_str(), GlobalExpr::PRAGMA_VERSION) == 0) { + int version = 0; + ret = getPragmas_["user_version"](version); + if (ret != E_OK) { + LOG_ERROR("RdConnection unable to GetVersion : err %{public}d", ret); + return { ret, ValueObject() }; } - default: - LOG_ERROR("invalid type %{public}d.", type); - return E_ERROR; + return { ret, ValueObject(version) }; } -} - -int RdStatement::GetFloat32Array(int index, std::vector &vecs) const -{ - int ret = IsValid(index); + ret = Bind(args); if (ret != E_OK) { - // It has already logged inside - return ret; + LOG_ERROR("RdConnection unable to prepare and bind stmt : err %{public}d", ret); + return { ret, ValueObject() }; } - ColumnType type = RdUtils::RdSqlColType(stmtHandle_, index); - if (type != ColumnType::TYPE_FLOAT32_ARRAY) { - LOG_ERROR("invalid type %{public}d.", static_cast(type)); - return E_INVALID_COLUMN_TYPE; - } - uint32_t dim = 0; - const float *vec = RdUtils::RdSqlColumnFloatVector(stmtHandle_, index, &dim); - if (dim == 0 || vec == nullptr) { - vecs.resize(0); - } else { - vecs.resize(dim); - vecs.assign(vec, vec + dim); + ret = Step(); + if (ret != E_OK && ret != E_NO_MORE_ROWS) { + LOG_ERROR("RdConnection Execute : err %{public}d", ret); + return { ret, ValueObject() }; } - return E_OK; + return GetColumn(0); } -int RdStatement::GetColumnBlob(int index, std::vector &value) const +int32_t RdStatement::Changes() const { - int ret = IsValid(index); - if (ret != E_OK) { - // It has already logged inside - return ret; - } - ColumnType type = RdUtils::RdSqlColType(stmtHandle_, index); - if (type != ColumnType::TYPE_BLOB && type != ColumnType::TYPE_STRING && type != ColumnType::TYPE_NULL) { - LOG_ERROR("invalid type %{public}d.", type); - return E_INVALID_COLUMN_TYPE; - } - int size = RdUtils::RdSqlColBytes(stmtHandle_, index); - const uint8_t *blob = RdUtils::RdSqlColBlob(stmtHandle_, index); - if (size == 0 || blob == nullptr) { - value.resize(0); - } else { - value.resize(size); - value.assign(blob, blob + size); - } - return E_OK; + return 0; } -int RdStatement::GetColumnString(int index, std::string &value) const +int64_t RdStatement::LastInsertRowId() const { - int ret = IsValid(index); - if (ret != E_OK) { - return ret; - } - ColumnType type = RdUtils::RdSqlColType(stmtHandle_, index); - switch (type) { - case ColumnType::TYPE_STRING: { - auto val = reinterpret_cast(RdUtils::RdSqlColText(stmtHandle_, index)); - value = (val == nullptr) ? "" : std::string(val, RdUtils::RdSqlColBytes(stmtHandle_, index) - 1); - break; - } - case ColumnType::TYPE_INTEGER: { - int64_t val = static_cast(RdUtils::RdSqlColInt64(stmtHandle_, index)); - value = std::to_string(val); - break; - } - case ColumnType::TYPE_FLOAT: { - double val = RdUtils::RdSqlColDouble(stmtHandle_, index); - std::ostringstream os; - if (os << std::setprecision(SET_DATA_PRECISION) << val) - value = os.str(); - break; - } - case ColumnType::TYPE_NULL: { - value = ""; - return E_OK; - } - case ColumnType::TYPE_BLOB: { - return E_INVALID_COLUMN_TYPE; - } - default: - return E_ERROR; - } - return E_OK; + return 0; } -int RdStatement::GetColumnInt(int index, int &value) +int32_t RdStatement::GetColumnCount() const { - int ret = IsValid(index); - if (ret != E_OK) { - return ret; - } - ColumnType type = RdUtils::RdSqlColType(stmtHandle_, index); - if (type != ColumnType::TYPE_INTEGER) { - return E_ERROR; - } - value = RdUtils::RdSqlColInt(stmtHandle_, index); - return E_OK; + return columnCount_; } -int RdStatement::GetColumnLong(int index, int64_t &value) const +std::pair RdStatement::GetColumnName(int32_t index) const { int ret = IsValid(index); if (ret != E_OK) { - return ret; + return { ret, "" }; } - char *errStr = nullptr; - ColumnType type = RdUtils::RdSqlColType(stmtHandle_, index); - if (type == ColumnType::TYPE_INTEGER) { - value = RdUtils::RdSqlColInt64(stmtHandle_, index); - } else if (type == ColumnType::TYPE_STRING) { - auto val = reinterpret_cast(RdUtils::RdSqlColText(stmtHandle_, index)); - value = (val == nullptr) ? 0 : strtoll(val, &errStr, 0); - } else if (type == ColumnType::TYPE_FLOAT) { - double val = RdUtils::RdSqlColDouble(stmtHandle_, index); - value = static_cast(val); - } else if (type == ColumnType::TYPE_NULL) { - value = 0; - } else if (type == ColumnType::TYPE_BLOB) { - return E_INVALID_COLUMN_TYPE; - } else { - return E_ERROR; + const char* name = RdUtils::RdSqlColName(stmtHandle_, index); + if (name == nullptr) { + LOG_ERROR("column_name is null."); + return { E_ERROR, "" }; } - return E_OK; + return { E_OK, name }; } -int RdStatement::GetColumnDouble(int index, double &value) const +std::pair RdStatement::GetColumnType(int32_t index) const { int ret = IsValid(index); if (ret != E_OK) { - return ret; + return { ret, static_cast(ColumnType::TYPE_NULL) }; } - char *ptr = nullptr; ColumnType type = RdUtils::RdSqlColType(stmtHandle_, index); - if (type == ColumnType::TYPE_FLOAT) { - value = RdUtils::RdSqlColDouble(stmtHandle_, index); - } else if (type == ColumnType::TYPE_INTEGER) { - int64_t val = static_cast(RdUtils::RdSqlColInt64(stmtHandle_, index)); - value = static_cast(val); - } else if (type == ColumnType::TYPE_STRING) { - auto val = reinterpret_cast(RdUtils::RdSqlColText(stmtHandle_, index)); - value = (val == nullptr) ? 0.0 : std::strtod(val, &ptr); - } else if (type == ColumnType::TYPE_NULL) { - value = 0.0; - } else if (type == ColumnType::TYPE_BLOB) { - return E_INVALID_COLUMN_TYPE; - } else { - LOG_ERROR("invalid type %{public}d.", type); - return E_ERROR; + switch (type) { + case ColumnType::TYPE_INTEGER: + case ColumnType::TYPE_FLOAT: + case ColumnType::TYPE_NULL: + case ColumnType::TYPE_STRING: + case ColumnType::TYPE_BLOB: + case ColumnType::TYPE_FLOAT32_ARRAY: + break; + default: + LOG_ERROR("invalid type %{public}d.", type); + return { E_ERROR, static_cast(ColumnType::TYPE_NULL) }; } - return E_OK; + return { ret, static_cast(type) }; } -int RdStatement::GetSize(int index, size_t &size) const +std::pair RdStatement::GetSize(int32_t index) const { - size = 0; int ret = IsValid(index); if (ret != E_OK) { - return ret; + return { ret, 0 }; } ColumnType type = RdUtils::RdSqlColType(stmtHandle_, index); if (type == ColumnType::TYPE_BLOB || type == ColumnType::TYPE_STRING || type == ColumnType::TYPE_NULL || type == ColumnType::TYPE_FLOAT32_ARRAY) { - size = static_cast(RdUtils::RdSqlColBytes(stmtHandle_, index)); - return E_OK; + return { E_OK, static_cast(RdUtils::RdSqlColBytes(stmtHandle_, index)) }; } - return E_INVALID_COLUMN_TYPE; + return { E_INVALID_COLUMN_TYPE, 0 }; } -int RdStatement::GetColumn(int index, ValueObject &value) const +std::pair RdStatement::GetColumn(int32_t index) const { + ValueObject object; int ret = IsValid(index); if (ret != E_OK) { - return ret; + return { ret, object }; } ColumnType type = RdUtils::RdSqlColType(stmtHandle_, index); switch (type) { case ColumnType::TYPE_FLOAT: - value = RdUtils::RdSqlColDouble(stmtHandle_, index); - return E_OK; + object = RdUtils::RdSqlColDouble(stmtHandle_, index); + break; case ColumnType::TYPE_INTEGER: - value = static_cast(RdUtils::RdSqlColInt64(stmtHandle_, index)); - return E_OK; + object = static_cast(RdUtils::RdSqlColInt64(stmtHandle_, index)); + break; case ColumnType::TYPE_STRING: - value = reinterpret_cast(RdUtils::RdSqlColText(stmtHandle_, index)); - return E_OK; + object = reinterpret_cast(RdUtils::RdSqlColText(stmtHandle_, index)); + break; case ColumnType::TYPE_NULL: - return E_OK; + break; case ColumnType::TYPE_FLOAT32_ARRAY: { uint32_t dim = 0; auto vectors = @@ -443,8 +433,8 @@ int RdStatement::GetColumn(int index, ValueObject &value) const vecData.resize(dim); vecData.assign(vectors, vectors + dim); } - value = std::move(vecData); - return E_OK; + object = std::move(vecData); + break; } case ColumnType::TYPE_BLOB: { int size = RdUtils::RdSqlColBytes(stmtHandle_, index); @@ -454,27 +444,33 @@ int RdStatement::GetColumn(int index, ValueObject &value) const rawData.resize(size); rawData.assign(blob, blob + size); } - value = std::move(rawData); - return E_OK; + object = std::move(rawData); + break; } default: break; } - return E_OK; + return { ret, std::move(object) }; +} + +bool RdStatement::ReadOnly() const +{ + return readOnly_; +} + +bool RdStatement::SupportBlockInfo() const +{ + return false; } -bool RdStatement::IsReadOnly() const +int32_t RdStatement::FillBlockInfo(SharedBlockInfo* info) const { return E_NOT_SUPPORT; } -int RdStatement::IsValid(int index) const +void RdStatement::GetProperties() { - if (stmtHandle_ == nullptr) { - LOG_ERROR("statement already close."); - return E_ALREADY_CLOSED; - } - return E_OK; + columnCount_ = RdUtils::RdSqlColCnt(stmtHandle_); } } // namespace NativeRdb diff --git a/relational_store/frameworks/native/rdb/src/rd_utils.cpp b/relational_store/frameworks/native/rdb/src/rd_utils.cpp index dc916a2f..e5c60772 100644 --- a/relational_store/frameworks/native/rdb/src/rd_utils.cpp +++ b/relational_store/frameworks/native/rdb/src/rd_utils.cpp @@ -29,10 +29,6 @@ using namespace OHOS::Rdb; static GRD_APIInfo GRD_KVApiInfo; -const std::string RdUtils::BEGIN_TRANSACTION_SQL = "begin;"; -const std::string RdUtils::COMMIT_TRANSACTION_SQL = "commit;"; -const std::string RdUtils::ROLLBACK_TRANSACTION_SQL = "rollback;"; - struct GrdErrnoPair { int32_t grdCode; int kvDbCode; @@ -42,6 +38,8 @@ const GrdErrnoPair GRD_ERRNO_MAP[] = { { GRD_OK, E_OK }, { GRD_NO_DATA, E_NO_MORE_ROWS }, { GRD_INNER_ERR, E_ERROR }, + { GRD_DATA_CORRUPTED, E_SQLITE_CORRUPT }, + { GRD_INVALID_FILE_FORMAT, E_SQLITE_CORRUPT }, }; int RdUtils::TransferGrdErrno(int err) @@ -99,6 +97,18 @@ int RdUtils::RdDbClose(GRD_DB *db, uint32_t flags) return TransferGrdErrno(GRD_KVApiInfo.DBCloseApi(db, flags)); } +int RdUtils::RdDbRepair(const char *dbPath, const char *configStr) +{ + LOG_DEBUG("[RdUtils::RdDbRepair]"); + if (GRD_KVApiInfo.DBRepairApi == nullptr) { + GRD_KVApiInfo = GetApiInfoInstance(); + } + if (GRD_KVApiInfo.DBRepairApi == nullptr) { + return TransferGrdErrno(GRD_INNER_ERR); + } + return TransferGrdErrno(GRD_KVApiInfo.DBRepairApi(dbPath, configStr)); +} + int RdUtils::RdSqlPrepare(GRD_DB *db, const char *str, uint32_t strLen, GRD_SqlStmt **stmt, const char **unusedStr) { LOG_DEBUG("[RdUtils::RdSqlPrepare]"); @@ -135,6 +145,10 @@ int RdUtils::RdSqlFinalize(GRD_SqlStmt *stmt) return TransferGrdErrno(GRD_KVApiInfo.DBSqlFinalize(stmt)); } +void RdSqlFreeBlob(void *blobElementSize) +{ + delete[] ((uint8_t *)blobElementSize); +} int RdUtils::RdSqlBindBlob(GRD_SqlStmt *stmt, uint32_t idx, const void *val, int32_t len, void (*freeFunc)(void *)) { @@ -145,7 +159,24 @@ int RdUtils::RdSqlBindBlob(GRD_SqlStmt *stmt, uint32_t idx, const void *val, int if (GRD_KVApiInfo.DBSqlBindBlob == nullptr) { return TransferGrdErrno(GRD_INNER_ERR); } - return TransferGrdErrno(GRD_KVApiInfo.DBSqlBindBlob(stmt, idx, val, len, freeFunc)); + if (len <= 0) { + LOG_ERROR("Invalid len %{public}d", len); + return E_INVALID_ARGS; + } + uint8_t *tmpVal = new uint8_t[len](); + if (tmpVal == nullptr) { + return E_ERROR; + } + errno_t err = memcpy_s(tmpVal, len * sizeof(uint8_t), val, len * sizeof(uint8_t)); + if (err < 0) { + delete[] tmpVal; + LOG_ERROR("BindBlob failed due to memcpy %{public}d, len is %{public}d", err, len); + return TransferGrdErrno(GRD_INNER_ERR); + } + if (freeFunc == nullptr) { + freeFunc = RdSqlFreeBlob; + } + return TransferGrdErrno(GRD_KVApiInfo.DBSqlBindBlob(stmt, idx, tmpVal, len, freeFunc)); } void RdSqlFreeCharStr(void *charStr) @@ -162,7 +193,14 @@ int RdUtils::RdSqlBindText(GRD_SqlStmt *stmt, uint32_t idx, const void *val, int if (GRD_KVApiInfo.DBSqlBindText == nullptr) { return TransferGrdErrno(GRD_INNER_ERR); } + if (len <= 0) { + LOG_ERROR("Invalid len %{public}d", len); + return E_INVALID_ARGS; + } char *tmpVal = new char[len + 1](); + if (tmpVal == nullptr) { + return E_ERROR; + } errno_t err = strcpy_s(tmpVal, len + 1, (const char *)val); if (err < 0) { LOG_ERROR("BindText failed due to strycpy %{public}d, len is %{public}d", err, len + 1); @@ -223,6 +261,11 @@ int RdUtils::RdSqlBindNull(GRD_SqlStmt *stmt, uint32_t idx) return TransferGrdErrno(GRD_KVApiInfo.DBSqlBindNull(stmt, idx)); } +void RdSqlFreeFloatArr(void *floatElement) +{ + delete[] ((float *)floatElement); +} + int RdUtils::RdSqlBindFloatVector(GRD_SqlStmt *stmt, uint32_t idx, float *val, uint32_t dim, void (*freeFunc)(void *)) { @@ -233,7 +276,24 @@ int RdUtils::RdSqlBindFloatVector(GRD_SqlStmt *stmt, uint32_t idx, float *val, if (GRD_KVApiInfo.DBSqlBindFloatVector == nullptr) { return TransferGrdErrno(GRD_INNER_ERR); } - return TransferGrdErrno(GRD_KVApiInfo.DBSqlBindFloatVector(stmt, idx, val, dim, freeFunc)); + if (dim <= 0) { + LOG_ERROR("Invalid dim %{public}d", dim); + return E_INVALID_ARGS; + } + float *tmpVal = new float[dim](); + if (tmpVal == nullptr) { + return E_ERROR; + } + errno_t err = memcpy_s(tmpVal, dim * sizeof(float), val, dim * sizeof(float)); + if (err < 0) { + delete[] tmpVal; + LOG_ERROR("BindFloat failed due to memcpy %{public}d, dim is %{public}d", err, dim); + return TransferGrdErrno(GRD_INNER_ERR); + } + if (freeFunc == nullptr) { + freeFunc = RdSqlFreeFloatArr; + } + return TransferGrdErrno(GRD_KVApiInfo.DBSqlBindFloatVector(stmt, idx, tmpVal, dim, freeFunc)); } int RdUtils::RdSqlStep(GRD_SqlStmt *stmt) @@ -380,5 +440,56 @@ const float *RdUtils::RdSqlColumnFloatVector(GRD_SqlStmt *stmt, uint32_t idx, ui return GRD_KVApiInfo.DBSqlColumnFloatVector(stmt, idx, dim); } +int RdUtils::RdDbBackup(GRD_DB *db, const char *backupDbFile, uint8_t *encryptedKey, uint32_t encryptedKeyLen) +{ + LOG_DEBUG("[RdUtils::RdDbBackup]"); + if (GRD_KVApiInfo.DBBackupApi == nullptr) { + GRD_KVApiInfo = GetApiInfoInstance(); + } + if (GRD_KVApiInfo.DBBackupApi == nullptr) { + return TransferGrdErrno(GRD_INNER_ERR); + } + return TransferGrdErrno(GRD_KVApiInfo.DBBackupApi(db, backupDbFile, encryptedKey, encryptedKeyLen)); +} + +int RdUtils::RdDbRestore(GRD_DB *db, const char *backupDbFile, uint8_t *encryptedKey, uint32_t encryptedKeyLen) +{ + LOG_DEBUG("[RdUtils::RdDbRestore]"); + if (GRD_KVApiInfo.DBRestoreApi == nullptr) { + GRD_KVApiInfo = GetApiInfoInstance(); + } + if (GRD_KVApiInfo.DBRestoreApi == nullptr) { + return TransferGrdErrno(GRD_INNER_ERR); + } + return TransferGrdErrno(GRD_KVApiInfo.DBRestoreApi(db, backupDbFile, encryptedKey, encryptedKeyLen)); +} + +int RdUtils::RdDbGetVersion(GRD_DB *db, GRD_ConfigTypeE type, int &version) +{ + if (GRD_KVApiInfo.DBGetConfigApi == nullptr) { + GRD_KVApiInfo = GetApiInfoInstance(); + } + if (GRD_KVApiInfo.DBGetConfigApi == nullptr) { + return TransferGrdErrno(GRD_INNER_ERR); + } + GRD_DbValueT value = GRD_KVApiInfo.DBGetConfigApi(db, type); + version = value.value.longValue; + return E_OK; +} + +int RdUtils::RdDbSetVersion(GRD_DB *db, GRD_ConfigTypeE type, int version) +{ + if (GRD_KVApiInfo.DBSetConfigApi == nullptr) { + GRD_KVApiInfo = GetApiInfoInstance(); + } + if (GRD_KVApiInfo.DBSetConfigApi == nullptr) { + return TransferGrdErrno(GRD_INNER_ERR); + } + GRD_DbValueT value; + value.type = GRD_SQL_DATATYPE_INTEGER; + value.value.longValue = version; + return TransferGrdErrno(GRD_KVApiInfo.DBSetConfigApi(db, type, value)); +} + } // namespace NativeRdb } // namespace OHOS diff --git a/relational_store/frameworks/native/rdb/src/rdb_connection.cpp b/relational_store/frameworks/native/rdb/src/rdb_connection.cpp deleted file mode 100644 index dea38fe1..00000000 --- a/relational_store/frameworks/native/rdb/src/rdb_connection.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#define LOG_TAG "RdbConnection" -#include "rdb_connection.h" -#include "logger.h" -#include "rd_connection.h" -#include "rdb_errno.h" -#include "sqlite_connection.h" -#include "sqlite_global_config.h" - -namespace OHOS { -namespace NativeRdb { -using namespace OHOS::Rdb; - -std::shared_ptr RdbConnection::Open(const RdbStoreConfig &config, bool isWriteConnection, int &errCode) -{ - if (config.IsVector()) { - return RdConnection::Open(config, isWriteConnection, errCode); - } - return nullptr; -} - -RdbConnection::RdbConnection(bool isWriteConnection) : isWriteConnection_(isWriteConnection), isReadOnly_(false), - openFlags(0) -{ -} - -bool RdbConnection::IsWriteConnection() const -{ - return isWriteConnection_; -} - -int RdbConnection::Prepare(const std::string &sql, bool &outIsReadOnly) -{ - return E_NOT_SUPPORT; -} - -int RdbConnection::ExecuteSql(const std::string &sql, const std::vector &bindArgs) -{ - return E_NOT_SUPPORT; -} - -std::shared_ptr RdbConnection::BeginStepQuery( - int &errCode, const std::string &sql, const std::vector &args) const -{ - return nullptr; -} - -int RdbConnection::DesFinalize() -{ - return E_NOT_SUPPORT; -} - -int RdbConnection::EndStepQuery() -{ - return E_NOT_SUPPORT; -} - -int RdbConnection::ExecuteForChangedRowCount( - int &changedRows, const std::string &sql, const std::vector &bindArgs) -{ - return E_NOT_SUPPORT; -} - -int RdbConnection::ExecuteForLastInsertedRowId(int64_t &outRowId, const std::string &sql, - const std::vector &bindArgs) -{ - return E_NOT_SUPPORT; -} - -int RdbConnection::ExecuteGetLong(int64_t &outValue, const std::string &sql, - const std::vector &bindArgs) -{ - return E_NOT_SUPPORT; -} - -int RdbConnection::ExecuteGetString(std::string &outValue, const std::string &sql, - const std::vector &bindArgs) -{ - return E_NOT_SUPPORT; -} - -int RdbConnection::ExecuteEncryptSql(const RdbStoreConfig &config, uint32_t iter) -{ - return E_NOT_SUPPORT; -} - -int RdbConnection::ReSetKey(const RdbStoreConfig &config) -{ - return E_NOT_SUPPORT; -} - -void RdbConnection::SetInTransaction(bool transaction) -{ - return; -} - -bool RdbConnection::IsInTransaction() -{ - return E_NOT_SUPPORT; -} - -int RdbConnection::TryCheckPoint() -{ - return E_NOT_SUPPORT; -} - -int RdbConnection::LimitWalSize() -{ - return E_NOT_SUPPORT; -} - -int RdbConnection::ConfigLocale(const std::string &localeStr) -{ - return E_NOT_SUPPORT; -} - -int RdbConnection::ExecuteForSharedBlock(int &rowNum, std::string sql, const std::vector &bindArgs, - AppDataFwk::SharedBlock *sharedBlock, int startPos, int requiredPos, bool isCountAllRows) -{ - return E_NOT_SUPPORT; -} - -int RdbConnection::CleanDirtyData(const std::string &table, uint64_t cursor) -{ - return E_NOT_SUPPORT; -} - -int RdbConnection::RegisterCallBackObserver(const DataChangeCallback &clientChangedData) -{ - return E_NOT_SUPPORT; -} - -int RdbConnection::GetMaxVariableNumber() -{ - return E_NOT_SUPPORT; -} - -uint32_t RdbConnection::GetId() const -{ - return 0; -} - -int32_t RdbConnection::SetId(uint32_t id) -{ - (void)id; - return 0; -} - -JournalMode RdbConnection::GetJournalMode() -{ - return JournalMode::MODE_WAL; -} - -int RdbConnection::GetDbPath(const RdbStoreConfig &config, std::string &dbPath) -{ - if (config.GetStorageMode() == StorageMode::MODE_MEMORY) { - dbPath = SqliteGlobalConfig::GetMemoryDbPath(); - } else if (config.GetPath().empty()) { - LOG_ERROR("RdbConnection GetDbPath input empty database path"); - return E_INVALID_FILE_PATH; - } else if (config.GetPath().front() != '/' && config.GetPath().at(1) != ':') { - LOG_ERROR("RdbConnection GetDbPath input relative path"); - return E_RELATIVE_PATH; - } else { - dbPath = config.GetPath(); - } - return E_OK; -} - -} // namespace NativeRdb -} // namespace OHOS \ No newline at end of file diff --git a/relational_store/frameworks/native/rdb/src/rdb_connection_pool.cpp b/relational_store/frameworks/native/rdb/src/rdb_connection_pool.cpp deleted file mode 100644 index 5c175b99..00000000 --- a/relational_store/frameworks/native/rdb/src/rdb_connection_pool.cpp +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#define LOG_TAG "RdbConnectionPool" -#include "rdb_connection_pool.h" -#include "logger.h" -#include "rd_connection.h" -#include "sqlite_connection_pool.h" -#include "rdb_errno.h" - -namespace OHOS { -namespace NativeRdb { -using namespace OHOS::Rdb; - -RdbConnectionPool::RdbConnectionPool(const RdbStoreConfig &storeConfig) : transactionStack_(), config_(storeConfig) -{ -} - -int RdbConnectionPool::Init() -{ - std::unique_lock lock(idleConnsMutex_); - int errCode = E_OK; - while (writeConnNum_ < DEFAULT_WRITE_CONN_NUM) { - auto connection = RdConnection::Open(config_, true, errCode); - if (connection == nullptr) { - CloseAllConns(); - return errCode; - } - idleWriteConns_.push_back(connection); - writeConnNum_++; - } - while (readConnNum_ < DEFAULT_READ_CONN_NUM) { - auto connection = RdConnection::Open(config_, false, errCode); - if (connection == nullptr) { - CloseAllConns(); - return errCode; - } - idleReadConns_.push_back(connection); - readConnNum_++; - } - return E_OK; -} - -std::shared_ptr RdbConnectionPool::Create(const RdbStoreConfig &storeConfig, int &errCode) -{ - std::shared_ptr pool = std::make_shared(storeConfig); - if (pool == nullptr) { - LOG_ERROR("RdbConnectionPool::Create new failed, pool is nullptr"); - return nullptr; - } - errCode = pool->Init(); - if (errCode != E_OK) { - pool = nullptr; - return nullptr; - } - return pool; -} - -RdbConnectionPool::~RdbConnectionPool() -{ - CloseAllConns(); -} - -std::shared_ptr RdbConnectionPool::AcquireConnection(bool isReadOnly, int64_t trxId) -{ - return AcquireConnectionByTrxId(isReadOnly, trxId); -} - -int RdbConnectionPool::RestartReaders() -{ - return E_NOT_SUPPORTED; -} - -std::pair, std::vector>> RdbConnectionPool::AcquireAll( - int32_t time) -{ - return {}; -} - -std::shared_ptr RdbConnectionPool::AcquireWriteConnByTrxId(int64_t trxId) -{ - if (trxId != 0) { - auto it = trxConnMap_.find(trxId); - if (it != trxConnMap_.end()) { - return it->second; - } - return nullptr; - } - std::shared_ptr connection = nullptr; - if (idleWriteConns_.empty()) { - if (writeConnNum_ >= MAX_WRITE_CONN_NUM) { - LOG_INFO("Open rdbConnection has exceed the limit"); - return nullptr; - } - int errCode = E_OK; - connection = RdConnection::Open(config_, true, errCode); - if (errCode != E_OK) { - LOG_ERROR("Open rdbConnection ret %{public}d", errCode); - return nullptr; - } - writeConnNum_++; - } else { - connection = idleWriteConns_.back(); - idleWriteConns_.pop_back(); - } - if (trxId != 0) { - trxConnMap_[trxId] = connection; - } - return connection; -} - -std::shared_ptr RdbConnectionPool::AcquireReadConnByTrxId(int64_t trxId) -{ - if (trxId != 0) { - LOG_ERROR("Read connection should not bind with transaction id"); - return nullptr; - } - std::shared_ptr connection = nullptr; - if (idleReadConns_.empty()) { - if (readConnNum_ >= MAX_READ_CONN_NUM) { - LOG_WARN("Read connection is out of limit"); - return nullptr; - } - int errCode = E_OK; - connection = RdbConnection::Open(config_, false, errCode); - if (errCode != E_OK) { - LOG_ERROR("Open rdbConnection ret %{public}d", errCode); - return nullptr; - } - readConnNum_++; - } else { - connection = idleReadConns_.back(); - idleReadConns_.pop_back(); - } - return connection; -} - -std::shared_ptr RdbConnectionPool::AcquireNewConnection(bool isReadOnly, int64_t &trxId) -{ - std::shared_ptr conn = AcquireConnectionByTrxId(isReadOnly, 0); - if (isReadOnly) { - trxId = 0; - return conn; - } - std::unique_lock lock(idleConnsMutex_); - if (trxConnMap_.find(newtrxId_) != trxConnMap_.end()) { - LOG_ERROR("trxId has appeared before"); - conn = nullptr; - return nullptr; - } - trxConnMap_[newtrxId_] = conn; - trxId = newtrxId_; - newtrxId_++; - return conn; -} - - -std::shared_ptr RdbConnectionPool::AcquireConnectionByTrxId(bool isReadOnly, int64_t trxId) -{ - std::unique_lock lock(idleConnsMutex_); - return isReadOnly ? AcquireReadConnByTrxId(trxId) : AcquireWriteConnByTrxId(trxId); -} - -void RdbConnectionPool::ReleaseConnection(std::shared_ptr rdbConnection, int64_t trxId) -{ - std::unique_lock lock(idleConnsMutex_); - if (rdbConnection->IsWriteConnection()) { - if (trxId != 0) { - if (trxConnMap_.find(trxId) == trxConnMap_.end()) { - LOG_ERROR("RdbConnectionPool cannot find connection according to trxId"); - return; - } - trxConnMap_.erase(trxId); - } - if (writeConnNum_ >= MAX_WRITE_CONN_NUM) { - rdbConnection = nullptr; - --writeConnNum_; - return; - } - idleWriteConns_.push_back(rdbConnection); - return; - } - if (readConnNum_ >= MAX_READ_CONN_NUM) { - rdbConnection = nullptr; - --readConnNum_; - return; - } - idleReadConns_.push_back(rdbConnection); - return; -} - -void RdbConnectionPool::CloseAllConns() -{ - std::unique_lock lock(idleConnsMutex_); - for (auto &item : idleWriteConns_) { - item = nullptr; - } - for (auto &item : idleReadConns_) { - item = nullptr; - } - idleReadConns_.clear(); -} - -int RdbConnectionPool::ConfigLocale(const std::string &localeStr) -{ - return E_NOT_SUPPORTED; -} - -int RdbConnectionPool::ChangeDbFileForRestore(const std::string &newPath, const std::string &backupPath, - const std::vector &newKey) - { - return E_NOT_SUPPORTED; - } - -std::stack &RdbConnectionPool::GetTransactionStack() -{ - return transactionStack_; -} - -std::mutex &RdbConnectionPool::GetTransactionStackMutex() -{ - return transactionStackMutex_; -} - -std::pair> RdbConnectionPool::DisableWalMode() -{ - return {}; -} - -int RdbConnectionPool::AcquireTransaction() -{ - return 0; -} - -void RdbConnectionPool::ReleaseTransaction() -{ - return; -} - -int RdbConnectionPool::EnableWalMode() -{ - return 0; -} - -void RdbConnectionPool::CloseAllConnections() -{ - return; -} - -} // namespace NativeRdb -} // namespace OHOS diff --git a/relational_store/frameworks/native/rdb/src/rdb_helper.cpp b/relational_store/frameworks/native/rdb/src/rdb_helper.cpp index 05ddd4df..be61323d 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_helper.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_helper.cpp @@ -40,6 +40,7 @@ std::shared_ptr RdbHelper::GetRdbStore( void RdbHelper::ClearCache() { + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); RdbStoreManager::GetInstance().Clear(); } @@ -55,7 +56,9 @@ static std::vector rdPostFixes = { ".redo", ".undo", ".ctrl", + ".ctrl.dwr", ".safe", + ".map", }; int DeleteRdFiles(const std::string &dbFileName) diff --git a/relational_store/frameworks/native/rdb/src/rdb_manager_impl.cpp b/relational_store/frameworks/native/rdb/src/rdb_manager_impl.cpp index d46a08dd..a13dab6f 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_manager_impl.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_manager_impl.cpp @@ -106,19 +106,20 @@ std::pair> RdbManagerImpl::GetRdbService(co } if (distributedDataMgr_ == nullptr) { LOG_ERROR("get distributed data manager failed"); - return { E_ERROR, nullptr }; + return { E_SERVICE_NOT_FOUND, nullptr }; } auto remote = distributedDataMgr_->GetFeatureInterface(DistributedRdb::RdbService::SERVICE_NAME); if (remote == nullptr) { LOG_ERROR("get rdb service failed"); - return { E_NOT_SUPPORTED, nullptr }; + return { E_NOT_SUPPORT, nullptr }; } - sptr rdbService = nullptr; - if (remote->IsProxyObject()) { - rdbService = iface_cast(remote); + + if (!remote->IsProxyObject()) { + return { E_NOT_SUPPORT, nullptr }; } + sptr rdbService = iface_cast(remote); if (rdbService == nullptr) { rdbService = new (std::nothrow) RdbServiceProxy(remote); } @@ -173,7 +174,7 @@ RdbStoreDataServiceProxy::RdbStoreDataServiceProxy(const sptr &im sptr RdbStoreDataServiceProxy::GetFeatureInterface(const std::string &name) { - LOG_INFO("%{public}s", name.c_str()); + LOG_DEBUG("%{public}s", name.c_str()); MessageParcel data; if (!data.WriteInterfaceToken(RdbStoreDataServiceProxy::GetDescriptor())) { LOG_ERROR("write descriptor failed"); diff --git a/relational_store/frameworks/native/rdb/src/rdb_security_manager.cpp b/relational_store/frameworks/native/rdb/src/rdb_security_manager.cpp index 5810153e..8c8d4d55 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_security_manager.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_security_manager.cpp @@ -18,14 +18,18 @@ #include #include +#include #include #include "directory_ex.h" #include "file_ex.h" +#include "hks_api.h" #include "hks_param.h" #include "logger.h" +#include "rdb_platform.h" #include "rdb_sql_utils.h" #include "sqlite_utils.h" +#include "string_utils.h" namespace OHOS { namespace NativeRdb { @@ -191,7 +195,7 @@ bool RdbSecurityManager::SaveSecretKeyToFile(const std::string &dbPath, RdbSecur } key.assign(key.size(), 0); - if (!RdbSecurityManager::InitPath(ExtractFilePath(dbPath) + std::string("key/"))) { + if (!RdbSecurityManager::InitPath(StringUtils::ExtractFilePath(dbPath) + std::string("key/"))) { LOG_ERROR("InitPath err."); return false; } @@ -386,7 +390,7 @@ int32_t RdbSecurityManager::Init(const std::string &bundleName) retryCount++; usleep(RETRY_TIME_INTERVAL_MILLISECOND); } - LOG_INFO("retry:%{public}u, error:%{public}d", retryCount, ret); + LOG_INFO("bundleName:%{public}s, retry:%{public}u, error:%{public}d", bundleName.c_str(), retryCount, ret); return ret; } @@ -437,7 +441,7 @@ bool RdbSecurityManager::InitPath(const std::string &dbKeyDir) return true; } umask(DEFAULT_UMASK); - if (mkdir(dbKeyDir.c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) != 0 && errno != EEXIST) { + if (MkDir(dbKeyDir, (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) != 0 && errno != EEXIST) { LOG_ERROR("mkdir error:%{public}d, dbDir:%{public}s", errno, SqliteUtils::Anonymous(dbKeyDir).c_str()); return false; } @@ -447,7 +451,7 @@ bool RdbSecurityManager::InitPath(const std::string &dbKeyDir) RdbPassword RdbSecurityManager::LoadSecretKeyFromFile(const std::string &dbPath, KeyFileType keyFileType) { std::string keyPath = GetKeyPath(dbPath, keyFileType); - if (!FileExists(keyPath)) { + if (!(access(keyPath.c_str(), F_OK) == 0)) { LOG_ERROR("Key file not exists."); return {}; } @@ -555,8 +559,8 @@ static std::string RemoveSuffix(const std::string &name) std::pair RdbSecurityManager::ConcatenateKeyPath(const std::string &dbPath) { - const std::string dbName = RemoveSuffix(ExtractFileName(dbPath)); - const std::string dbKeyDir = ExtractFilePath(dbPath) + "key/"; + const std::string dbName = RemoveSuffix(StringUtils::ExtractFileName(dbPath)); + const std::string dbKeyDir = StringUtils::ExtractFilePath(dbPath) + "key/"; const std::string keyPath = dbKeyDir + dbName + RdbSecurityManager::SUFFIX_PUB_KEY; const std::string newKeyPath = dbKeyDir + dbName + RdbSecurityManager::SUFFIX_PUB_KEY_NEW; return std::make_pair(keyPath, newKeyPath); @@ -564,7 +568,7 @@ std::pair RdbSecurityManager::ConcatenateKeyPath(const bool RdbSecurityManager::IsKeyFileExists(const std::string &dbPath, RdbSecurityManager::KeyFileType keyFileType) { - return FileExists(GetKeyPath(dbPath, keyFileType)); + return (access(GetKeyPath(dbPath, keyFileType).c_str(), F_OK) == 0); } std::string RdbSecurityManager::GetKeyPath(const std::string &dbPath, RdbSecurityManager::KeyFileType keyFileType) 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 b972a122..83879ac3 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_service_proxy.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_service_proxy.cpp @@ -289,7 +289,8 @@ std::pair> RdbServiceProxy: 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()); + param.bundleName_.c_str(), SqliteUtils::Anonymous(param.storeName_).c_str(), + SqliteUtils::Anonymous(device).c_str()); return { status, nullptr }; } diff --git a/relational_store/frameworks/native/rdb/src/rdb_sql_statistic.cpp b/relational_store/frameworks/native/rdb/src/rdb_sql_statistic.cpp new file mode 100644 index 00000000..75281f5c --- /dev/null +++ b/relational_store/frameworks/native/rdb/src/rdb_sql_statistic.cpp @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "RdbSqlStatistic" + +#include "rdb_sql_statistic.h" +#include "task_executor.h" +#include "rdb_errno.h" +#include "rdb_platform.h" +#include "logger.h" +#include + +namespace OHOS::DistributedRdb { +using namespace OHOS::Rdb; +using namespace OHOS::NativeRdb; +ConcurrentMap> SqlStatistic::observers_; +ConcurrentMap> SqlStatistic::execInfos_; +bool SqlStatistic::enabled_ = false; +std::atomic_uint32_t SqlStatistic::seqId_ = 0; +int SqlStatistic::Subscribe(std::shared_ptr observer) +{ + observers_.ComputeIfAbsent(observer.get(), [observer](auto &) { + enabled_ = true; + return observer; + }); + return E_OK; +} + +int SqlStatistic::Unsubscribe(std::shared_ptr observer) +{ + observers_.Erase(observer.get()); + observers_.DoActionIfEmpty([]() { + enabled_ = false; + execInfos_.Clear(); + }); + return E_OK; +} + +uint32_t SqlStatistic::GenerateId() +{ + return ++seqId_; +} + +SqlStatistic::SqlStatistic(const std::string &sql, int32_t step, uint32_t seqId) +{ + if (!enabled_) { + return; + } + step_ = step; + key_ = seqId == 0 ? GetThreadId() : uint64_t(seqId); + time_ = std::chrono::steady_clock::now(); + auto it = execInfos_.Find(key_); + if (it.first) { + execInfo_ = it.second; + } + + if (execInfo_ == nullptr && seqId != 0) { + it = execInfos_.Find(GetThreadId()); + execInfo_ = it.second; + } + + if (execInfo_ == nullptr) { + execInfo_ = std::shared_ptr(new (std::nothrow) SqlExecInfo(), Release); + execInfos_.Insert(key_, execInfo_); + } + + if (step_ == STEP_PREPARE && !sql.empty()) { + execInfo_->sql_.emplace_back(sql); + } +} + +SqlStatistic::~SqlStatistic() +{ + if (!enabled_) { + return; + } + if (execInfo_ == nullptr) { + return; + } + auto interval = std::chrono::duration_cast(std::chrono::steady_clock::now() - time_); + switch (step_) { + case STEP_WAIT: + execInfo_->waitTime_ += interval.count(); + break; + case STEP_PREPARE: + execInfo_->prepareTime_ += interval.count(); + break; + case STEP_EXECUTE: + execInfo_->executeTime_ += interval.count(); + break; + case STEP_TOTAL: + case STEP_TOTAL_RES: + execInfo_->totalTime_ += interval.count(); + execInfos_.Erase(key_); + break; + default: + execInfo_->totalTime_ += interval.count(); + break; + } +} + +void SqlStatistic::Release(SqlExecInfo *execInfo) +{ + if (execInfo == nullptr) { + return; + } + if (execInfo->sql_.empty()) { + delete execInfo; + return; + } + auto executor = TaskExecutor::GetInstance().GetExecutor(); + if (executor == nullptr) { + delete execInfo; + return; + } + executor->Execute([info = std::move(*execInfo)]() { + observers_.ForEachCopies([&info](auto key, std::shared_ptr &observer) { + if (observer == nullptr) { + return false; + } + observer->OnStatistic(info); + return false; + }); + }); + delete execInfo; +} +} \ No newline at end of file diff --git a/relational_store/frameworks/native/rdb/src/rdb_sql_utils.cpp b/relational_store/frameworks/native/rdb/src/rdb_sql_utils.cpp index af04e831..e738a8a4 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_sql_utils.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_sql_utils.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ +#define LOG_TAG "RdbSqlUtils" #include "rdb_sql_utils.h" #include @@ -22,10 +23,12 @@ #include #include "acl.h" +#include "logger.h" #include "rdb_errno.h" #include "rdb_platform.h" #include "sqlite_sql_builder.h" namespace OHOS { +using namespace Rdb; namespace NativeRdb { using namespace OHOS::DATABASE_UTILS; constexpr int32_t SERVICE_GID = 3012; @@ -48,6 +51,7 @@ int RdbSqlUtils::CreateDirectory(const std::string &databaseDir) databaseDirectory = databaseDirectory + "/" + directory; if (access(databaseDirectory.c_str(), F_OK) != 0) { if (MkDir(databaseDirectory)) { + LOG_ERROR("failed to mkdir errno[%{public}d] %{public}s", errno, databaseDirectory.c_str()); return E_CREATE_FOLDER_FAIL; } // Set the default ACL attribute to the database root directory to ensure that files created by the server @@ -75,6 +79,10 @@ std::pair RdbSqlUtils::GetDefaultDatabasePath(const std::strin databaseDir.append(baseDir).append("/rdb/").append(customDir); errorCode = CreateDirectory(databaseDir); + if (errorCode != E_OK) { + LOG_ERROR("failed errno[%{public}d] baseDir : %{public}s name : %{public}s customDir : %{public}s", + errno, baseDir.c_str(), name.c_str(), customDir.c_str()); + } return std::make_pair(databaseDir.append("/").append(name), errorCode); } @@ -85,6 +93,10 @@ std::string RdbSqlUtils::GetDefaultDatabasePath(const std::string &baseDir, cons { std::string databaseDir = baseDir + "/rdb"; errorCode = CreateDirectory(databaseDir); + if (errorCode != E_OK) { + LOG_ERROR( + "failed errno[%{public}d] baseDir : %{public}s name : %{public}s", errno, baseDir.c_str(), name.c_str()); + } return databaseDir.append("/").append(name); } diff --git a/relational_store/frameworks/native/rdb/src/rdb_statement.cpp b/relational_store/frameworks/native/rdb/src/rdb_statement.cpp deleted file mode 100644 index 1943b122..00000000 --- a/relational_store/frameworks/native/rdb/src/rdb_statement.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#define LOG_TAG "RdbStatement" -#include "rdb_statement.h" - -#include -#include -#include -#include -#include "logger.h" -#include "raw_data_parser.h" -#include "rdb_errno.h" -#include "sqlite_errno.h" -#include "sqlite_utils.h" -#include "sqlite_connection.h" - -namespace OHOS { -namespace NativeRdb { -using namespace OHOS::Rdb; - -RdbStatement::RdbStatement() -{ -} - -RdbStatement::~RdbStatement() -{ -} - -int RdbStatement::PrepareStmt(const std::string &sql) -{ - return E_NOT_SUPPORT; -} - -int RdbStatement::Finalize() -{ - return E_NOT_SUPPORT; -} - -int RdbStatement::BindArguments(const std::vector &bindArgs) const -{ - return E_NOT_SUPPORT; -} - -int RdbStatement::ResetStatementAndClearBindings() const -{ - return E_NOT_SUPPORT; -} - -int RdbStatement::Step() const -{ - return E_NOT_SUPPORT; -} - -int RdbStatement::GetColumnCount(int &count) const -{ - return E_NOT_SUPPORT; -} - -int RdbStatement::GetColumnName(int index, std::string &columnName) const -{ - return E_NOT_SUPPORT; -} - -int RdbStatement::GetColumnType(int index, int &columnType) const -{ - return E_NOT_SUPPORT; -} - -int RdbStatement::GetColumnBlob(int index, std::vector &value) const -{ - return E_NOT_SUPPORT; -} - -int RdbStatement::GetColumnString(int index, std::string &value) const -{ - return E_NOT_SUPPORT; -} - -int RdbStatement::GetFloat32Array(int index, std::vector &vecs) const -{ - return E_NOT_SUPPORT; -} - -int RdbStatement::GetColumnLong(int index, int64_t &value) const -{ - return E_NOT_SUPPORT; -} - -int RdbStatement::GetColumnDouble(int index, double &value) const -{ - return E_NOT_SUPPORT; -} - -int RdbStatement::GetSize(int index, size_t &size) const -{ - return E_NOT_SUPPORT; -} - -int RdbStatement::GetColumn(int index, ValueObject &value) const -{ - return E_NOT_SUPPORT; -} - -bool RdbStatement::IsReadOnly() const -{ - return E_NOT_SUPPORT; -} - -bool RdbStatement::SupportSharedBlock() const -{ - return false; -} - -} // namespace NativeRdb -} // namespace OHOS diff --git a/relational_store/frameworks/native/rdb/src/rdb_store_config.cpp b/relational_store/frameworks/native/rdb/src/rdb_store_config.cpp index 416a49c3..30b22bfe 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_store_config.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_store_config.cpp @@ -17,6 +17,7 @@ #include "logger.h" #include "rdb_errno.h" +#include "rdb_security_manager.h" namespace OHOS::NativeRdb { using namespace OHOS::Rdb; @@ -346,9 +347,65 @@ std::vector RdbStoreConfig::GetEncryptKey() const return encryptKey_; } +void RdbStoreConfig::ChangeEncryptKey() const +{ + if (encryptKey_.size() == newEncryptKey_.size()) { + encryptKey_.assign(encryptKey_.size(), 0); + encryptKey_.assign(newEncryptKey_.data(), newEncryptKey_.data() + newEncryptKey_.size()); + newEncryptKey_.assign(newEncryptKey_.size(), 0); + newEncryptKey_.resize(0); + } +} + +std::vector RdbStoreConfig::GetNewEncryptKey() const +{ + return newEncryptKey_; +} + +void RdbStoreConfig::Initialize() const +{ + GenerateEncryptedKey(); +} + +void RdbStoreConfig::GenerateEncryptedKey() const +{ + if (!isEncrypt_) { + return; + } + + auto name = bundleName_; + if (name.empty()) { + name = std::string(path).substr(0, path.rfind("/") + 1); + } + auto errCode = RdbSecurityManager::GetInstance().Init(name); + if (errCode != E_OK) { + LOG_ERROR("generate root encrypt key failed, bundleName_:%{public}s", bundleName_.c_str()); + return; + } + auto rdbPwd = RdbSecurityManager::GetInstance().GetRdbPassword(path, RdbSecurityManager::KeyFileType::PUB_KEY_FILE); + if (!rdbPwd.IsValid()) { + LOG_ERROR("key is inValid, bundleName_:%{public}s", bundleName_.c_str()); + return; + } + encryptKey_ = std::vector(rdbPwd.GetData(), rdbPwd.GetData() + rdbPwd.GetSize()); + rdbPwd.Clear(); + + if (rdbPwd.isKeyExpired) { + auto rdbNewPwd = RdbSecurityManager::GetInstance().GetRdbPassword(path, + RdbSecurityManager::KeyFileType::PUB_KEY_FILE_NEW_KEY); + if (!rdbNewPwd.IsValid()) { + LOG_ERROR("key is inValid, bundleName_:%{public}s", bundleName_.c_str()); + return; + } + newEncryptKey_ = std::vector(rdbNewPwd.GetData(), rdbNewPwd.GetData() + rdbNewPwd.GetSize()); + rdbPwd.Clear(); + } +} + void RdbStoreConfig::ClearEncryptKey() { encryptKey_.assign(encryptKey_.size(), 0); + newEncryptKey_.assign(newEncryptKey_.size(), 0); } void RdbStoreConfig::SetScalarFunction(const std::string &functionName, int argc, ScalarFunction function) @@ -384,6 +441,7 @@ bool RdbStoreConfig::GetAutoClean() const void RdbStoreConfig::SetIsVector(bool isVector) { isVector_ = isVector; + isVector ? SetDBType(DB_VECTOR) : SetDBType(DB_SQLITE); } bool RdbStoreConfig::IsVector() const 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 5fcec1e4..c22b0972 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_store_impl.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_store_impl.cpp @@ -30,8 +30,12 @@ #include "logger.h" #include "rdb_common.h" #include "rdb_errno.h" +#include "rdb_radar_reporter.h" +#include "rdb_sql_statistic.h" #include "rdb_store.h" #include "rdb_trace.h" +#include "rdb_types.h" +#include "relational_store_client.h" #include "sqlite_global_config.h" #include "sqlite_sql_builder.h" #include "sqlite_statement.h" @@ -48,7 +52,6 @@ #include "rdb_device_manager_adapter.h" #include "rdb_manager_impl.h" #include "rdb_security_manager.h" -#include "relational_store_client.h" #include "relational_store_manager.h" #include "runtime_config.h" #include "security_policy.h" @@ -64,9 +67,15 @@ namespace OHOS::NativeRdb { using namespace OHOS::Rdb; using namespace std::chrono; +using SqlStatistic = DistributedRdb::SqlStatistic; #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) using RdbMgr = DistributedRdb::RdbManagerImpl; #endif + +static constexpr const char *BEGIN_TRANSACTION_SQL = "begin;"; +static constexpr const char *COMMIT_TRANSACTION_SQL = "commit;"; +static constexpr const char *ROLLBACK_TRANSACTION_SQL = "rollback;"; + int RdbStoreImpl::InnerOpen() { LOG_DEBUG("open %{public}s.", SqliteUtils::Anonymous(path_).c_str()); @@ -111,36 +120,40 @@ std::string RdbStoreImpl::GetSecManagerName(const RdbStoreConfig &config) void RdbStoreImpl::AfterOpen(const RdbStoreConfig &config) { std::vector key = config.GetEncryptKey(); - RdbPassword rdbPwd; - if (config.IsEncrypt()) { - auto ret = RdbSecurityManager::GetInstance().Init(GetSecManagerName(config)); - if (ret != E_OK) { - return; - } - rdbPwd = RdbSecurityManager::GetInstance().GetRdbPassword(config.GetPath(), - RdbSecurityManager::KeyFileType::PUB_KEY_FILE); - key.assign(key.size(), 0); - key = std::vector(rdbPwd.GetData(), rdbPwd.GetData() + rdbPwd.GetSize()); - } syncerParam_.password_ = std::vector(key.data(), key.data() + key.size()); key.assign(key.size(), 0); if (pool_ != nullptr) { auto param = syncerParam_; - pool_->Execute([param]() { - auto [err, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(param); - if (err != E_OK || service == nullptr) { - LOG_DEBUG("GetRdbService failed, err is %{public}d.", err); - return; - } - err = service->AfterOpen(param); - LOG_ERROR("AfterOpen RdbStoreImpl::AfterOpen leve %{public}d.", param.level_); - if (err != E_OK) { - LOG_ERROR("AfterOpen failed, err is %{public}d.", err); - } - }); + auto retry = 0; + UploadSchema(param, retry); } } +void RdbStoreImpl::UploadSchema(const DistributedRdb::RdbSyncerParam ¶m, uint32_t retry) +{ + auto [err, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(param); + if (err == E_NOT_SUPPORT) { + return; + } + if (err != E_OK || service == nullptr) { + LOG_ERROR("GetRdbService failed, err: %{public}d, storeName: %{public}s.", err, param.storeName_.c_str()); + auto pool = TaskExecutor::GetInstance().GetExecutor(); + if (err == E_SERVICE_NOT_FOUND && pool != nullptr && retry++ < MAX_RETRY_TIMES) { + pool->Schedule(std::chrono::seconds(RETRY_INTERVAL), [param, retry]() { UploadSchema(param, retry); }); + } + return; + } + err = service->AfterOpen(param); + if (err != E_OK) { + LOG_ERROR("AfterOpen failed, err: %{public}d, storeName: %{public}s.", err, param.storeName_.c_str()); + } +} + +int32_t RdbStoreImpl::GetDbType() const +{ + return config_.GetDBType(); +} + RdbStore::ModifyTime::ModifyTime(std::shared_ptr result, std::map, PRIKey> hashKeys, bool isFromRowId) : result_(std::move(result)), hash_(std::move(hashKeys)), isFromRowId_(isFromRowId) @@ -240,7 +253,7 @@ RdbStore::ModifyTime RdbStoreImpl::GetModifyTime(const std::string &table, const sql.append("select hash_key as key, timestamp/10000 as modify_time from "); sql.append(logTable); sql.append(" where hash_key in ("); - sql.append(GetSqlArgs(hashKeys.size())); + sql.append(SqliteSqlBuilder::GetSqlArgs(hashKeys.size())); sql.append(")"); auto resultSet = QueryByStep(sql, hashKeys); int count = 0; @@ -257,7 +270,7 @@ RdbStore::ModifyTime RdbStoreImpl::GetModifyTimeByRowId(const std::string &logTa sql.append("select data_key as key, timestamp/10000 as modify_time from "); sql.append(logTable); sql.append(" where data_key in ("); - sql.append(GetSqlArgs(keys.size())); + sql.append(SqliteSqlBuilder::GetSqlArgs(keys.size())); sql.append(")"); std::vector args; args.reserve(keys.size()); @@ -277,7 +290,7 @@ RdbStore::ModifyTime RdbStoreImpl::GetModifyTimeByRowId(const std::string &logTa int RdbStoreImpl::CleanDirtyData(const std::string &table, uint64_t cursor) { - if (config_.GetRoleType() == VISITOR) { + if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR) || (config_.IsReadOnly())) { return E_NOT_SUPPORT; } if (table.empty()) { @@ -292,15 +305,6 @@ int RdbStoreImpl::CleanDirtyData(const std::string &table, uint64_t cursor) } #endif -std::string RdbStoreImpl::GetSqlArgs(size_t size) -{ - std::string args((size << 1) - 1, '?'); - for (size_t i = 1; i < size; ++i) { - args[(i << 1) - 1] = ','; - } - return args; -} - RdbStoreImpl::RdbStoreImpl(const RdbStoreConfig &config) : config_(config), isOpen_(false), isReadOnly_(config.IsReadOnly()), isMemoryRdb_(config.IsMemoryRdb()), isEncrypt_(config.IsEncrypt()), path_(config.GetPath()), @@ -316,18 +320,13 @@ RdbStoreImpl::RdbStoreImpl(const RdbStoreConfig &config, int &errCode) { path_ = (config.GetRoleType() == VISITOR) ? config.GetVisitorDir() : config.GetPath(); connectionPool_ = SqliteConnectionPool::Create(config_, errCode); - if (connectionPool_ == nullptr && errCode == E_SQLITE_CORRUPT && config.GetAllowRebuild()) { - auto realPath = config.GetPath(); - RemoveDbFiles(realPath); - connectionPool_ = SqliteConnectionPool::Create(config_, errCode); - if (errCode == E_OK) { - rebuild_ = RebuiltType::REBUILT; - } + if (connectionPool_ == nullptr && errCode == E_SQLITE_CORRUPT && config.GetAllowRebuild() && !config.IsReadOnly()) { + LOG_ERROR("database corrupt, rebuild database %{public}s", name_.c_str()); + std::tie(rebuild_, connectionPool_) = SqliteConnectionPool::HandleDataCorruption(config_, errCode); } if (connectionPool_ == nullptr || errCode != E_OK) { connectionPool_ = nullptr; - LOG_ERROR("Create connPool failed, err is %{public}d, path:%{public}s", - errCode, path_.c_str()); + LOG_ERROR("Create connPool failed, err is %{public}d, path:%{public}s", errCode, path_.c_str()); return; } @@ -354,13 +353,19 @@ const RdbStoreConfig &RdbStoreImpl::GetConfig() int RdbStoreImpl::Insert(int64_t &outRowId, const std::string &table, const ValuesBucket &values) { - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); - return InsertWithConflictResolution(outRowId, table, values, ConflictResolution::ON_CONFLICT_NONE); + return InsertWithConflictResolutionEntry(outRowId, table, values, ConflictResolution::ON_CONFLICT_NONE); } int RdbStoreImpl::BatchInsert(int64_t &outInsertNum, const std::string &table, const std::vector &values) { - if (config_.GetRoleType() == VISITOR) { + SqlStatistic sqlStatistic("", SqlStatistic::Step::STEP_TOTAL); + return BatchInsertEntry(outInsertNum, table, values); +} + +int RdbStoreImpl::BatchInsertEntry(int64_t &outInsertNum, const std::string &table, + const std::vector &values) +{ + if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR) || (config_.IsReadOnly())) { return E_NOT_SUPPORT; } if (values.empty()) { @@ -442,63 +447,26 @@ RdbStoreImpl::ExecuteSqls RdbStoreImpl::GenerateSql(const std::string& table, co } sql.pop_back(); sql.append(") VALUES "); - return MakeExecuteSqls(sql, std::move(args), fields.size(), limit); -} - -RdbStoreImpl::ExecuteSqls RdbStoreImpl::MakeExecuteSqls(const std::string& sql, std::vector&& args, - int fieldSize, int limit) -{ - if (fieldSize == 0) { - return ExecuteSqls(); - } - size_t rowNumbers = args.size() / static_cast(fieldSize); - size_t maxRowNumbersOneTimes = static_cast(limit / fieldSize); - size_t executeTimes = rowNumbers / maxRowNumbersOneTimes; - size_t remainingRows = rowNumbers % maxRowNumbersOneTimes; - LOG_DEBUG("rowNumbers %{public}zu, maxRowNumbersOneTimes %{public}zu, executeTimes %{public}zu," - "remainingRows %{public}zu, fieldSize %{public}d, limit %{public}d", - rowNumbers, maxRowNumbersOneTimes, executeTimes, remainingRows, fieldSize, limit); - std::string singleRowSqlArgs = "(" + GetSqlArgs(fieldSize) + ")"; - auto appendAgsSql = [&singleRowSqlArgs, &sql] (size_t rowNumber) { - std::string sqlStr = sql; - for (size_t i = 0; i < rowNumber; ++i) { - sqlStr.append(singleRowSqlArgs).append(","); - } - sqlStr.pop_back(); - return sqlStr; - }; - std::string executeSql; - ExecuteSqls executeSqls; - auto start = args.begin(); - if (executeTimes != 0) { - executeSql = appendAgsSql(maxRowNumbersOneTimes); - std::vector> sqlArgs; - size_t maxVariableNumbers = maxRowNumbersOneTimes * static_cast(fieldSize); - for (size_t i = 0; i < executeTimes; ++i) { - std::vector bindValueArgs(start, start + maxVariableNumbers); - sqlArgs.emplace_back(std::move(bindValueArgs)); - start += maxVariableNumbers; - } - executeSqls.emplace_back(std::make_pair(executeSql, std::move(sqlArgs))); - } - - if (remainingRows != 0) { - executeSql = appendAgsSql(remainingRows); - std::vector> sqlArgs(1, std::vector(start, args.end())); - executeSqls.emplace_back(std::make_pair(executeSql, std::move(sqlArgs))); - } - return executeSqls; + return SqliteSqlBuilder::MakeExecuteSqls(sql, std::move(args), fields.size(), limit); } int RdbStoreImpl::Replace(int64_t &outRowId, const std::string &table, const ValuesBucket &values) { - return InsertWithConflictResolution(outRowId, table, values, ConflictResolution::ON_CONFLICT_REPLACE); + return InsertWithConflictResolutionEntry(outRowId, table, values, ConflictResolution::ON_CONFLICT_REPLACE); } int RdbStoreImpl::InsertWithConflictResolution(int64_t &outRowId, const std::string &table, const ValuesBucket &values, ConflictResolution conflictResolution) { - if (config_.GetRoleType() == VISITOR) { + return InsertWithConflictResolutionEntry(outRowId, table, values, conflictResolution); +} + +int RdbStoreImpl::InsertWithConflictResolutionEntry(int64_t &outRowId, const std::string &table, + const ValuesBucket &values, ConflictResolution conflictResolution) +{ + SqlStatistic sqlStatistic("", SqlStatistic::Step::STEP_TOTAL); + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); + if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR) || (config_.IsReadOnly())) { return E_NOT_SUPPORT; } if (table.empty()) { @@ -535,7 +503,7 @@ int RdbStoreImpl::InsertWithConflictResolution(int64_t &outRowId, const std::str sql.append(") VALUES ("); if (bindArgsSize > 0) { - sql.append(GetSqlArgs(bindArgsSize)); + sql.append(SqliteSqlBuilder::GetSqlArgs(bindArgsSize)); } sql.append(")"); @@ -578,7 +546,6 @@ int RdbStoreImpl::Update(int &changedRows, const std::string &table, const Value int RdbStoreImpl::Update(int &changedRows, const std::string &table, const ValuesBucket &values, const std::string &whereClause, const std::vector &bindArgs) { - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); return UpdateWithConflictResolution( changedRows, table, values, whereClause, bindArgs, ConflictResolution::ON_CONFLICT_NONE); } @@ -595,14 +562,24 @@ int RdbStoreImpl::UpdateWithConflictResolution(int &changedRows, const std::stri std::vector bindArgs; std::for_each( whereArgs.begin(), whereArgs.end(), [&bindArgs](const auto &it) { bindArgs.push_back(ValueObject(it)); }); - return UpdateWithConflictResolution( + return UpdateWithConflictResolutionEntry( changedRows, table, values, whereClause, bindArgs, conflictResolution); } int RdbStoreImpl::UpdateWithConflictResolution(int &changedRows, const std::string &table, const ValuesBucket &values, const std::string &whereClause, const std::vector &bindArgs, ConflictResolution conflictResolution) { - if (config_.GetRoleType() == VISITOR) { + SqlStatistic sqlStatistic("", SqlStatistic::Step::STEP_TOTAL); + return UpdateWithConflictResolutionEntry(changedRows, table, values, whereClause, bindArgs, conflictResolution); +} + +int RdbStoreImpl::UpdateWithConflictResolutionEntry(int &changedRows, const std::string &table, + const ValuesBucket &values, const std::string &whereClause, const std::vector &bindArgs, + ConflictResolution conflictResolution) +{ + SqlStatistic sqlStatistic("", SqlStatistic::Step::STEP_TOTAL); + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); + if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR) || (config_.IsReadOnly())) { return E_NOT_SUPPORT; } if (table.empty()) { @@ -653,13 +630,14 @@ int RdbStoreImpl::UpdateWithConflictResolution(int &changedRows, const std::stri int RdbStoreImpl::Delete(int &deletedRows, const AbsRdbPredicates &predicates) { - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); + SqlStatistic sqlStatistic("", SqlStatistic::Step::STEP_TOTAL); return Delete(deletedRows, predicates.GetTableName(), predicates.GetWhereClause(), predicates.GetBindArgs()); } int RdbStoreImpl::Delete(int &deletedRows, const std::string &table, const std::string &whereClause, const std::vector &whereArgs) { + SqlStatistic sqlStatistic("", SqlStatistic::Step::STEP_TOTAL); std::vector bindArgs; std::for_each( whereArgs.begin(), whereArgs.end(), [&bindArgs](const auto &it) { bindArgs.push_back(ValueObject(it)); }); @@ -669,7 +647,8 @@ int RdbStoreImpl::Delete(int &deletedRows, const std::string &table, const std:: int RdbStoreImpl::Delete(int &deletedRows, const std::string &table, const std::string &whereClause, const std::vector &bindArgs) { - if (config_.GetRoleType() == VISITOR) { + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); + if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR) || (config_.IsReadOnly())) { return E_NOT_SUPPORT; } if (table.empty()) { @@ -691,11 +670,29 @@ int RdbStoreImpl::Delete(int &deletedRows, const std::string &table, const std:: return E_OK; } +std::shared_ptr RdbStoreImpl::QueryByStep( + const AbsRdbPredicates &predicates, const std::vector &columns) +{ + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); + std::string sql; + if (predicates.HasSpecificField()) { + std::string table = predicates.GetTableName(); + std::string logTable = DistributedDB::RelationalStoreManager::GetDistributedLogTableName(table); + sql = SqliteSqlBuilder::BuildLockRowQueryString(predicates, columns, logTable); + } else { + sql = SqliteSqlBuilder::BuildQueryString(predicates, columns); + } + return QueryByStep(sql, predicates.GetBindArgs()); +} + #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) std::shared_ptr RdbStoreImpl::Query( const AbsRdbPredicates &predicates, const std::vector &columns) { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); + if (config_.GetDBType() == DB_VECTOR) { + return nullptr; + } std::string sql; std::pair queryStatus = { ColHasSpecificField(columns), predicates.HasSpecificField() }; if (queryStatus.first || queryStatus.second) { @@ -711,6 +708,9 @@ std::shared_ptr RdbStoreImpl::Query( std::pair> RdbStoreImpl::QuerySharingResource( const AbsRdbPredicates &predicates, const std::vector &columns) { + if (config_.GetDBType() == DB_VECTOR) { + return { E_NOT_SUPPORT, nullptr }; + } auto [errCode, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(syncerParam_); if (errCode != E_OK) { return { errCode, nullptr }; @@ -723,28 +723,20 @@ std::pair> RdbStoreImpl::QuerySharingResourc return { status, resultSet }; } -std::shared_ptr RdbStoreImpl::QueryByStep( - const AbsRdbPredicates &predicates, const std::vector &columns) -{ - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); - std::string sql; - if (predicates.HasSpecificField()) { - std::string table = predicates.GetTableName(); - std::string logTable = DistributedDB::RelationalStoreManager::GetDistributedLogTableName(table); - sql = SqliteSqlBuilder::BuildLockRowQueryString(predicates, columns, logTable); - } else { - sql = SqliteSqlBuilder::BuildQueryString(predicates, columns); - } - return QueryByStep(sql, predicates.GetBindArgs()); -} - std::shared_ptr RdbStoreImpl::RemoteQuery(const std::string &device, const AbsRdbPredicates &predicates, const std::vector &columns, int &errCode) { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); + if (config_.GetDBType() == DB_VECTOR) { + return nullptr; + } std::vector selectionArgs = predicates.GetWhereArgs(); std::string sql = SqliteSqlBuilder::BuildQueryString(predicates, columns); auto [err, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(syncerParam_); + if (err == E_NOT_SUPPORT) { + errCode = err; + return nullptr; + } if (err != E_OK) { LOG_ERROR("RdbStoreImpl::RemoteQuery get service failed"); errCode = err; @@ -775,6 +767,10 @@ std::shared_ptr RdbStoreImpl::Query(int &errCode, bool disti std::shared_ptr RdbStoreImpl::QuerySql(const std::string &sql, const std::vector &sqlArgs) { + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); + if (config_.GetDBType() == DB_VECTOR) { + return nullptr; + } std::vector bindArgs; std::for_each(sqlArgs.begin(), sqlArgs.end(), [&bindArgs](const auto &it) { bindArgs.push_back(ValueObject(it)); }); return std::make_shared(connectionPool_, path_, sql, bindArgs); @@ -783,7 +779,11 @@ std::shared_ptr RdbStoreImpl::QuerySql(const std::string &sq std::shared_ptr RdbStoreImpl::QuerySql(const std::string &sql, const std::vector &bindArgs) { + SqlStatistic sqlStatistic("", SqlStatistic::Step::STEP_TOTAL); DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); + if (config_.GetDBType() == DB_VECTOR) { + return nullptr; + } return std::make_shared(connectionPool_, path_, sql, bindArgs); } #endif @@ -801,14 +801,25 @@ std::shared_ptr RdbStoreImpl::Query( int RdbStoreImpl::Count(int64_t &outValue, const AbsRdbPredicates &predicates) { + if (config_.GetDBType() == DB_VECTOR) { + return E_NOT_SUPPORT; + } std::string sql = SqliteSqlBuilder::BuildCountString(predicates); - return ExecuteAndGetLong(outValue, sql, predicates.GetBindArgs()); } int RdbStoreImpl::ExecuteSql(const std::string &sql, const std::vector &bindArgs) { + return ExecuteSqlEntry(sql, bindArgs); +} + +int RdbStoreImpl::ExecuteSqlEntry(const std::string &sql, const std::vector &bindArgs) +{ + SqlStatistic sqlStatistic("", SqlStatistic::Step::STEP_TOTAL); DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); + if (config_.GetDBType() == DB_VECTOR || (config_.IsReadOnly())) { + return E_NOT_SUPPORT; + } int ret = CheckAttach(sql); if (ret != E_OK) { return ret; @@ -846,29 +857,13 @@ int RdbStoreImpl::ExecuteSql(const std::string &sql, const std::vector RdbStoreImpl::Execute(const std::string &sql, const std::vector &bindArgs, int64_t trxId) { - ValueObject object; - int sqlType = SqliteUtils::GetSqlStatementType(sql); - if (!SqliteUtils::IsSupportSqlForExecute(sqlType)) { - LOG_ERROR("Not support the sqlType: %{public}d, sql: %{public}s", sqlType, sql.c_str()); - return { E_NOT_SUPPORT_THE_SQL, object }; - } - - auto connect = connectionPool_->AcquireConnection(false); - if (connect == nullptr) { - return { E_CON_OVER_LIMIT, object }; - } - - auto [errCode, statement] = GetStatement(sql, connect); - if (errCode != E_OK) { - return { errCode, object }; - } - - errCode = statement->Execute(bindArgs); - if (errCode != E_OK) { - LOG_ERROR("execute sql failed, sql: %{public}s, error: %{public}d.", sql.c_str(), errCode); - return { errCode, object }; - } + return ExecuteEntry(sql, bindArgs, trxId); +} +std::pair RdbStoreImpl::HandleDifferentSqlTypes(std::shared_ptr statement, + const std::string &sql, const ValueObject &object, int sqlType) +{ + int32_t errCode = E_OK; if (sqlType == SqliteUtils::STATEMENT_INSERT) { int outValue = statement->Changes() > 0 ? statement->LastInsertRowId() : -1; return { errCode, ValueObject(outValue) }; @@ -904,8 +899,53 @@ std::pair RdbStoreImpl::Execute(const std::string &sql, co return { errCode, object }; } +std::pair RdbStoreImpl::ExecuteEntry(const std::string &sql, + const std::vector &bindArgs, int64_t trxId) +{ + ValueObject object; + if (config_.IsReadOnly()) { + return { E_NOT_SUPPORT, object }; + } + + SqlStatistic sqlStatistic("", SqlStatistic::Step::STEP_TOTAL); + int sqlType = SqliteUtils::GetSqlStatementType(sql); + if (!SqliteUtils::IsSupportSqlForExecute(sqlType)) { + LOG_ERROR("Not support the sqlType: %{public}d, sql: %{public}s", sqlType, sql.c_str()); + return { E_NOT_SUPPORT_THE_SQL, object }; + } + + if (config_.IsVector() && trxId > 0) { + return { ExecuteByTrxId(sql, trxId, false, bindArgs), ValueObject() }; + } + + auto connect = connectionPool_->AcquireConnection(false); + if (connect == nullptr) { + return { E_DATABASE_BUSY, object }; + } + + auto [errCode, statement] = GetStatement(sql, connect); + if (errCode != E_OK) { + return { errCode, object }; + } + + errCode = statement->Execute(bindArgs); + if (errCode != E_OK) { + LOG_ERROR("execute sql failed, sql: %{public}s, error: %{public}d.", sql.c_str(), errCode); + return { errCode, object }; + } + + if (config_.IsVector()) { + return { errCode, object }; + } + + return HandleDifferentSqlTypes(statement, sql, object, sqlType); +} + int RdbStoreImpl::ExecuteAndGetLong(int64_t &outValue, const std::string &sql, const std::vector &bindArgs) { + if (config_.GetDBType() == DB_VECTOR) { + return E_NOT_SUPPORT; + } auto [errCode, statement] = BeginExecuteSql(sql); if (statement == nullptr) { return errCode; @@ -921,6 +961,9 @@ int RdbStoreImpl::ExecuteAndGetLong(int64_t &outValue, const std::string &sql, c int RdbStoreImpl::ExecuteAndGetString( std::string &outValue, const std::string &sql, const std::vector &bindArgs) { + if (config_.GetDBType() == DB_VECTOR) { + return E_NOT_SUPPORT; + } auto [errCode, statement] = BeginExecuteSql(sql); if (statement == nullptr) { return errCode; @@ -937,7 +980,7 @@ int RdbStoreImpl::ExecuteAndGetString( int RdbStoreImpl::ExecuteForLastInsertedRowId(int64_t &outValue, const std::string &sql, const std::vector &bindArgs) { - if (config_.GetRoleType() == VISITOR) { + if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR) || (config_.IsReadOnly())) { return E_NOT_SUPPORT; } auto [errCode, statement] = GetStatement(sql, false); @@ -955,7 +998,7 @@ int RdbStoreImpl::ExecuteForLastInsertedRowId(int64_t &outValue, const std::stri int RdbStoreImpl::ExecuteForChangedRowCount(int64_t &outValue, const std::string &sql, const std::vector &bindArgs) { - if (config_.GetRoleType() == VISITOR) { + if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR) || (config_.IsReadOnly())) { return E_NOT_SUPPORT; } auto [errCode, statement] = GetStatement(sql, false); @@ -1017,7 +1060,7 @@ int RdbStoreImpl::ExecuteSqlInner(const std::string &sql, const std::vector &destEncryptKey) { - if (config_.GetRoleType() == VISITOR) { + if ((config_.GetRoleType() == VISITOR)) { return E_NOT_SUPPORT; } std::string backupFilePath; @@ -1050,8 +1093,16 @@ int RdbStoreImpl::InnerBackup(const std::string &databasePath, const std::vector { if (config_.GetRoleType() == VISITOR) { return E_NOT_SUPPORT; + } else if (config_.GetDBType() == DB_VECTOR) { + auto conn = connectionPool_->AcquireConnection(false); + if (conn == nullptr) { + return E_BASE; + } + if (isEncrypt_) { + return E_NOT_SUPPORT; + } + return conn->Backup(databasePath, {}); } - auto [errCode, statement] = GetStatement(GlobalExpr::CIPHER_DEFAULT_ATTACH_HMAC_ALGO, true); if (statement == nullptr) { return E_BASE; @@ -1063,17 +1114,15 @@ int RdbStoreImpl::InnerBackup(const std::string &databasePath, const std::vector statement->Execute(); #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) } else if (isEncrypt_) { - RdbPassword rdbPwd = RdbSecurityManager::GetInstance().GetRdbPassword( - config_.GetPath(), RdbSecurityManager::KeyFileType::PUB_KEY_FILE); - std::vector key = std::vector(rdbPwd.GetData(), rdbPwd.GetData() + rdbPwd.GetSize()); + std::vector key = config_.GetEncryptKey(); bindArgs.emplace_back(key); + key.assign(key.size(), 0); statement->Execute(); #endif } else { std::string str = ""; bindArgs.emplace_back(str); } - errCode = statement->Prepare(GlobalExpr::ATTACH_BACKUP_SQL); errCode = statement->Execute(bindArgs); if (errCode != E_OK) { @@ -1090,7 +1139,7 @@ std::pair RdbStoreImpl::BeginExecuteSql(const std:: { int type = SqliteUtils::GetSqlStatementType(sql); if (SqliteUtils::IsSpecial(type)) { - return { E_NOT_SUPPORTED, nullptr }; + return { E_NOT_SUPPORT, nullptr }; } bool assumeReadOnly = SqliteUtils::IsSqlReadOnly(type); @@ -1171,7 +1220,7 @@ int RdbStoreImpl::AttachInner( std::pair RdbStoreImpl::Attach( const RdbStoreConfig &config, const std::string &attachName, int32_t waitTime) { - if (config_.GetRoleType() == VISITOR) { + if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR) || (config_.IsReadOnly())) { return { E_NOT_SUPPORT, 0 }; } std::string dbPath; @@ -1182,7 +1231,7 @@ std::pair RdbStoreImpl::Attach( // encrypted databases are not supported to attach a non encrypted database. if (!config.IsEncrypt() && isEncrypt_) { - return { E_NOT_SUPPORTED, 0 }; + return { E_NOT_SUPPORT, 0 }; } if (attachedInfo_.Contains(attachName)) { @@ -1195,6 +1244,7 @@ std::pair RdbStoreImpl::Attach( RdbPassword rdbPwd = RdbSecurityManager::GetInstance().GetRdbPassword(dbPath, RdbSecurityManager::KeyFileType::PUB_KEY_FILE); key = std::vector(rdbPwd.GetData(), rdbPwd.GetData() + rdbPwd.GetSize()); + rdbPwd.Clear(); } #endif err = AttachInner(attachName, dbPath, key, waitTime); @@ -1215,7 +1265,7 @@ std::pair RdbStoreImpl::Attach( std::pair RdbStoreImpl::Detach(const std::string &attachName, int32_t waitTime) { - if (config_.GetRoleType() == VISITOR) { + if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR) || (config_.IsReadOnly())) { return { E_NOT_SUPPORT, 0 }; } if (!attachedInfo_.Contains(attachName)) { @@ -1259,9 +1309,10 @@ std::pair RdbStoreImpl::Detach(const std::string &attachName, */ int RdbStoreImpl::GetVersion(int &version) { - auto [errCode, statement] = GetStatement(GlobalExpr::PRAGMA_VERSION, config_.GetRoleType() == VISITOR); + bool isRead = (config_.IsReadOnly()) || (config_.GetRoleType() == VISITOR); + auto [errCode, statement] = GetStatement(GlobalExpr::PRAGMA_VERSION, isRead); if (statement == nullptr) { - return E_CON_OVER_LIMIT; + return errCode; } ValueObject value; std::tie(errCode, value) = statement->ExecuteForValue(); @@ -1277,14 +1328,13 @@ int RdbStoreImpl::GetVersion(int &version) */ int RdbStoreImpl::SetVersion(int version) { - if (config_.GetRoleType() == VISITOR) { + if ((config_.GetRoleType() == VISITOR) || (config_.IsReadOnly())) { return E_NOT_SUPPORT; } - std::string sql = std::string(GlobalExpr::PRAGMA_VERSION) + " = " + std::to_string(version); auto [errCode, statement] = GetStatement(sql); if (statement == nullptr) { - return E_CON_OVER_LIMIT; + return errCode; } return statement->Execute(); } @@ -1295,7 +1345,7 @@ int RdbStoreImpl::BeginTransaction() { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); std::lock_guard lockGuard(connectionPool_->GetTransactionStackMutex()); - if (config_.GetRoleType() == VISITOR) { + if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR) || (config_.IsReadOnly())) { return E_NOT_SUPPORT; } // size + 1 means the number of transactions in process @@ -1303,7 +1353,7 @@ int RdbStoreImpl::BeginTransaction() BaseTransaction transaction(connectionPool_->GetTransactionStack().size()); auto [errCode, statement] = GetStatement(transaction.GetTransactionStr()); if (statement == nullptr) { - return E_CON_OVER_LIMIT; + return errCode; } errCode = statement->Execute(); if (errCode != E_OK) { @@ -1325,7 +1375,26 @@ int RdbStoreImpl::BeginTransaction() std::pair RdbStoreImpl::BeginTrans() { - return { E_NOT_SUPPORT, 0 }; + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); + if (!config_.IsVector() || config_.IsReadOnly()) { + return {E_NOT_SUPPORT, 0}; + } + + auto time = static_cast(duration_cast(system_clock::now().time_since_epoch()).count()); + int64_t tmpTrxId = 0; + auto [errCode, connection] = connectionPool_->CreateConnection(false); + if (connection == nullptr) { + LOG_ERROR("Get null connection, storeName: %{public}s time:%{public}" PRIu64 ".", name_.c_str(), time); + return {errCode, 0}; + } + tmpTrxId = newTrxId_; + newTrxId_++; + trxConnMap_[tmpTrxId] = connection; + errCode = ExecuteByTrxId(BEGIN_TRANSACTION_SQL, tmpTrxId); + if (errCode != E_OK) { + trxConnMap_.erase(tmpTrxId); + } + return {errCode, tmpTrxId}; } /** @@ -1335,7 +1404,7 @@ int RdbStoreImpl::RollBack() { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); std::lock_guard lockGuard(connectionPool_->GetTransactionStackMutex()); - if (config_.GetRoleType() == VISITOR) { + if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR) || (config_.IsReadOnly())) { return E_NOT_SUPPORT; } size_t transactionId = connectionPool_->GetTransactionStack().size(); @@ -1367,10 +1436,47 @@ int RdbStoreImpl::RollBack() return E_OK; } +int RdbStoreImpl::ExecuteByTrxId(const std::string &sql, int64_t trxId, bool closeConnAfterExecute, + const std::vector &bindArgs) +{ + if ((!config_.IsVector()) || (config_.IsReadOnly())) { + return E_NOT_SUPPORT; + } + if (trxId == 0) { + return E_INVALID_ARGS; + } + if (trxConnMap_.find(trxId) == trxConnMap_.end()) { + LOG_ERROR("trxId hasn't appeared before %{public}" PRIu64, trxId); + return E_INVALID_ARGS; + } + auto time = static_cast(duration_cast(system_clock::now().time_since_epoch()).count()); + auto connection = trxConnMap_[trxId]; + if (connection == nullptr) { + LOG_ERROR("Get null connection, storeName: %{public}s time:%{public}" PRIu64 ".", name_.c_str(), time); + return E_ERROR; + } + auto [ret, statement] = GetStatement(sql, connection); + if (ret != E_OK) { + return ret; + } + ret = statement->Execute(bindArgs); + if (ret != E_OK) { + LOG_ERROR( + "transaction id: %{public}" PRIu64 ", storeName: %{public}s, errCode: %{public}d" PRIu64, trxId, + name_.c_str(), ret); + trxConnMap_.erase(trxId); + return ret; + } + if (closeConnAfterExecute) { + trxConnMap_.erase(trxId); + } + return E_OK; +} + int RdbStoreImpl::RollBack(int64_t trxId) { - (void)trxId; - return E_NOT_SUPPORT; + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); + return ExecuteByTrxId(ROLLBACK_TRANSACTION_SQL, trxId, true); } /** @@ -1380,33 +1486,32 @@ int RdbStoreImpl::Commit() { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); std::lock_guard lockGuard(connectionPool_->GetTransactionStackMutex()); - if (config_.GetRoleType() == VISITOR) { + if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR) || (config_.IsReadOnly())) { return E_NOT_SUPPORT; } size_t transactionId = connectionPool_->GetTransactionStack().size(); if (connectionPool_->GetTransactionStack().empty()) { - LOG_ERROR("transaction id: %{public}zu, storeName: %{public}s", transactionId, name_.c_str()); return E_OK; } BaseTransaction transaction = connectionPool_->GetTransactionStack().top(); std::string sqlStr = transaction.GetCommitStr(); if (sqlStr.size() <= 1) { - LOG_INFO("transaction id: %{public}zu, storeName: %{public}s", transactionId, name_.c_str()); + LOG_WARN("id: %{public}zu, storeName: %{public}s, sql: %{public}s", + transactionId, name_.c_str(), sqlStr.c_str()); connectionPool_->GetTransactionStack().pop(); return E_OK; } auto [errCode, statement] = GetStatement(sqlStr); if (statement == nullptr) { - LOG_ERROR("transaction id: %{public}zu, storeName: %{public}s", transactionId, name_.c_str()); + LOG_ERROR("id: %{public}zu, storeName: %{public}s, statement error", transactionId, name_.c_str()); return E_DATABASE_BUSY; } errCode = statement->Execute(); connectionPool_->SetInTransaction(false); // 1 means the number of transactions in process if (transactionId > 1) { - LOG_WARN("transaction id: %{public}zu, storeName: %{public}s, errCode: %{public}d", - transactionId, name_.c_str(), errCode); + LOG_WARN("id: %{public}zu, storeName: %{public}s, errCode: %{public}d", transactionId, name_.c_str(), errCode); } connectionPool_->GetTransactionStack().pop(); return E_OK; @@ -1414,13 +1519,13 @@ int RdbStoreImpl::Commit() int RdbStoreImpl::Commit(int64_t trxId) { - (void)trxId; - return E_NOT_SUPPORT; + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); + return ExecuteByTrxId(COMMIT_TRANSACTION_SQL, trxId, true); } bool RdbStoreImpl::IsInTransaction() { - if (config_.GetRoleType() == VISITOR) { + if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR)) { return false; } return connectionPool_->IsInTransaction(); @@ -1442,7 +1547,7 @@ int RdbStoreImpl::CheckAttach(const std::string &sql) auto [errCode, statement] = GetStatement(GlobalExpr::PRAGMA_JOUR_MODE_EXP); if (statement == nullptr) { - return E_CON_OVER_LIMIT; + return errCode; } errCode = statement->Execute(); @@ -1559,11 +1664,14 @@ int RdbStoreImpl::ConfigLocale(const std::string &localeStr) int RdbStoreImpl::Restore(const std::string &backupPath, const std::vector &newKey) { + if (config_.IsReadOnly()) { + return E_NOT_SUPPORT; + } + if (!isOpen_) { LOG_ERROR("The connection pool has been closed."); return E_ERROR; } - if (connectionPool_ == nullptr) { LOG_ERROR("The connectionPool_ is null."); return E_ERROR; @@ -1603,6 +1711,7 @@ int RdbStoreImpl::Restore(const std::string &backupPath, const std::vector RdbStoreImpl::QueryByStep(const std::string &sql, const std::vector &sqlArgs) { + SqlStatistic sqlStatistic("", SqlStatistic::Step::STEP_TOTAL); std::vector bindArgs; std::for_each(sqlArgs.begin(), sqlArgs.end(), [&bindArgs](const auto &it) { bindArgs.push_back(ValueObject(it)); }); return std::make_shared(connectionPool_, sql, bindArgs); @@ -1610,6 +1719,7 @@ std::shared_ptr RdbStoreImpl::QueryByStep(const std::string &sql, std::shared_ptr RdbStoreImpl::QueryByStep(const std::string &sql, const std::vector &args) { + SqlStatistic sqlStatistic("", SqlStatistic::Step::STEP_TOTAL); return std::make_shared(connectionPool_, sql, args); } @@ -1618,6 +1728,9 @@ int RdbStoreImpl::SetDistributedTables(const std::vector &tables, i const DistributedRdb::DistributedConfig &distributedConfig) { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); + if (config_.GetDBType() == DB_VECTOR || config_.IsReadOnly()) { + return E_NOT_SUPPORT; + } if (tables.empty()) { LOG_WARN("The distributed tables to be set is empty."); return E_OK; @@ -1644,7 +1757,9 @@ int RdbStoreImpl::SetDistributedTables(const std::vector &tables, i std::string RdbStoreImpl::ObtainDistributedTableName(const std::string &device, const std::string &table, int &errCode) { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); - + if (config_.GetDBType() == DB_VECTOR) { + return ""; + } std::string uuid; DeviceManagerAdaptor::RdbDeviceManagerAdaptor &deviceManager = DeviceManagerAdaptor::RdbDeviceManagerAdaptor::GetInstance(syncerParam_.bundleName_); @@ -1664,6 +1779,9 @@ std::string RdbStoreImpl::ObtainDistributedTableName(const std::string &device, int RdbStoreImpl::Sync(const SyncOption &option, const AbsRdbPredicates &predicate, const AsyncBrief &callback) { + if (config_.GetDBType() == DB_VECTOR) { + return E_NOT_SUPPORT; + } return Sync(option, predicate, [callback](Details &&details) { Briefs briefs; for (auto &[key, value] : details) { @@ -1686,15 +1804,21 @@ int RdbStoreImpl::Sync(const SyncOption &option, const AbsRdbPredicates &predica DistributedRdb::RdbService::Option rdbOption; rdbOption.mode = option.mode; rdbOption.isAsync = !option.isBlock; - return InnerSync(rdbOption, predicate.GetDistributedPredicates(), async); + RdbRadar ret(Scene::SCENE_SYNC, __FUNCTION__, config_.GetBundleName()); + ret = InnerSync(rdbOption, predicate.GetDistributedPredicates(), async); + return ret; } int RdbStoreImpl::InnerSync(const DistributedRdb::RdbService::Option &option, const DistributedRdb::PredicatesMemo &predicates, const RdbStore::AsyncDetail &async) { auto [errCode, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(syncerParam_); + if (errCode == E_NOT_SUPPORT) { + return errCode; + } if (errCode != E_OK) { - LOG_ERROR("GetRdbService is failed, err is %{public}d.", errCode); + LOG_ERROR("GetRdbService is failed, err is %{public}d, bundleName is %{public}s.", + errCode, syncerParam_.bundleName_.c_str()); return errCode; } errCode = service->Sync(syncerParam_, option, predicates, async); @@ -1764,7 +1888,7 @@ int32_t RdbStoreImpl::SubscribeLocalDetail(const SubscribeOption &option, { auto connection = connectionPool_->AcquireConnection(false); if (connection == nullptr) { - return E_CON_OVER_LIMIT; + return E_DATABASE_BUSY; } int32_t errCode = connection->Subscribe(option.event, observer); if (errCode != E_OK) { @@ -1785,6 +1909,9 @@ int RdbStoreImpl::SubscribeRemote(const SubscribeOption& option, RdbStoreObserve int RdbStoreImpl::Subscribe(const SubscribeOption &option, RdbStoreObserver *observer) { + if (config_.GetDBType() == DB_VECTOR) { + return E_NOT_SUPPORT; + } if (option.mode == SubscribeMode::LOCAL) { return SubscribeLocal(option, observer); } @@ -1894,7 +2021,7 @@ int32_t RdbStoreImpl::UnsubscribeLocalDetail(const SubscribeOption& option, { auto connection = connectionPool_->AcquireConnection(false); if (connection == nullptr) { - return E_CON_OVER_LIMIT; + return E_DATABASE_BUSY; } int32_t errCode = connection->Unsubscribe(option.event, observer); if (errCode != E_OK) { @@ -1915,6 +2042,9 @@ int RdbStoreImpl::UnSubscribeRemote(const SubscribeOption& option, RdbStoreObser int RdbStoreImpl::UnSubscribe(const SubscribeOption &option, RdbStoreObserver *observer) { + if (config_.GetDBType() == DB_VECTOR) { + return E_NOT_SUPPORT; + } if (option.mode == SubscribeMode::LOCAL && observer) { return UnSubscribeLocal(option, observer); } else if (option.mode == SubscribeMode::LOCAL && !observer) { @@ -1929,16 +2059,25 @@ int RdbStoreImpl::UnSubscribe(const SubscribeOption &option, RdbStoreObserver *o int RdbStoreImpl::SubscribeObserver(const SubscribeOption& option, const std::shared_ptr &observer) { + if (config_.GetDBType() == DB_VECTOR) { + return E_NOT_SUPPORT; + } return SubscribeLocalDetail(option, observer); } int RdbStoreImpl::UnsubscribeObserver(const SubscribeOption& option, const std::shared_ptr &observer) { + if (config_.GetDBType() == DB_VECTOR) { + return E_NOT_SUPPORT; + } return UnsubscribeLocalDetail(option, observer); } int RdbStoreImpl::Notify(const std::string &event) { + if (config_.GetDBType() == DB_VECTOR) { + return E_NOT_SUPPORT; + } auto client = OHOS::AAFwk::DataObsMgrClient::GetInstance(); if (client == nullptr) { LOG_ERROR("Failed to get DataObsMgrClient."); @@ -1962,6 +2101,9 @@ int RdbStoreImpl::Notify(const std::string &event) int RdbStoreImpl::RegisterAutoSyncCallback(std::shared_ptr observer) { + if (config_.GetDBType() == DB_VECTOR) { + return E_NOT_SUPPORT; + } auto [errCode, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(syncerParam_); if (errCode != E_OK) { return errCode; @@ -1971,6 +2113,9 @@ int RdbStoreImpl::RegisterAutoSyncCallback(std::shared_ptr observer) { + if (config_.GetDBType() == DB_VECTOR) { + return E_NOT_SUPPORT; + } auto [errCode, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(syncerParam_); if (errCode != E_OK) { return errCode; @@ -1990,6 +2135,9 @@ void RdbStoreImpl::InitDelayNotifier() delayNotifier_->SetExecutorPool(pool_); delayNotifier_->SetTask([param = syncerParam_](const DistributedRdb::RdbChangedData& rdbChangedData) -> int { auto [errCode, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(param); + if (errCode == E_NOT_SUPPORT) { + return errCode; + } if (errCode != E_OK || service == nullptr) { LOG_ERROR("GetRdbService is failed, err is %{public}d.", errCode); return errCode; @@ -2003,7 +2151,8 @@ int RdbStoreImpl::RegisterDataChangeCallback() if (!config_.IsSearchable()) { return E_OK; } - if (config_.GetRoleType() == VISITOR) { + + if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR) || (config_.IsReadOnly())) { return E_NOT_SUPPORT; } InitDelayNotifier(); @@ -2056,8 +2205,9 @@ int RdbStoreImpl::GetHashKeyForLockRow(const AbsRdbPredicates &predicates, std:: } int count = 0; if (result->GetRowCount(count) != E_OK) { - return E_ERROR; + return E_NO_ROW_IN_QUERY; } + if (count <= 0) { return E_NO_ROW_IN_QUERY; } @@ -2101,7 +2251,7 @@ std::pair> RdbStoreImpl::GetStatement( const std::string &sql, std::shared_ptr conn) const { if (conn == nullptr) { - return { E_CON_OVER_LIMIT, nullptr }; + return { E_DATABASE_BUSY, nullptr }; } return conn->CreateStatement(sql, conn); } @@ -2110,7 +2260,7 @@ std::pair> RdbStoreImpl::GetStatement(const { auto conn = connectionPool_->AcquireConnection(read); if (conn == nullptr) { - return { E_CON_OVER_LIMIT, nullptr }; + return { E_DATABASE_BUSY, nullptr }; } return conn->CreateStatement(sql, conn); } diff --git a/relational_store/frameworks/native/rdb/src/rdb_store_manager.cpp b/relational_store/frameworks/native/rdb/src/rdb_store_manager.cpp index 07368b88..4b964a62 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_store_manager.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_store_manager.cpp @@ -24,7 +24,7 @@ #include "rdb_trace.h" #include "sqlite_global_config.h" #include "task_executor.h" -#include "vdb_store_impl.h" +#include "rdb_radar_reporter.h" #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) #if !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) @@ -74,16 +74,13 @@ std::shared_ptr RdbStoreManager::GetRdbStore(const RdbStoreConfig &con storeCache_.erase(path); } - std::shared_ptr rdbStore = nullptr; - rdbStore = config.IsVector() ? std::make_shared(config, errCode) - : std::make_shared(config, errCode); - + std::shared_ptr rdbStore = std::make_shared(config, errCode); if (errCode != E_OK) { LOG_ERROR("RdbStoreManager GetRdbStore fail to open RdbStore as memory issue, rc=%{public}d", errCode); return nullptr; } - if (config.GetRoleType() == OWNER) { + if (config.GetRoleType() == OWNER && !config.IsReadOnly()) { errCode = SetSecurityLabel(config); if (errCode != E_OK) { LOG_ERROR("fail, storeName:%{public}s security %{public}d errCode:%{public}d", config.GetName().c_str(), @@ -91,6 +88,7 @@ std::shared_ptr RdbStoreManager::GetRdbStore(const RdbStoreConfig &con return nullptr; } if (config.IsVector()) { + storeCache_[path] = rdbStore; return rdbStore; } errCode = ProcessOpenCallback(*rdbStore, config, version, openCallback); @@ -154,6 +152,9 @@ int32_t RdbStoreManager::GetParamFromService(DistributedRdb::RdbSyncerParam &par { #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) auto [err, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(param); + if (err == E_NOT_SUPPORT) { + return E_ERROR; + } if (err != E_OK || service == nullptr) { LOG_ERROR("GetRdbService failed, err is %{public}d.", err); return E_ERROR; @@ -212,11 +213,6 @@ int RdbStoreManager::ProcessOpenCallback( return openCallback.OnOpen(rdbStore); } - if (config.IsReadOnly()) { - LOG_ERROR("RdbHelper ProcessOpenCallback Can't upgrade read-only store"); - return E_CANNOT_UPDATE_READONLY; - } - if (currentVersion == 0) { errCode = openCallback.OnCreate(rdbStore); } else if (version > currentVersion) { 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 91d1af58..1b23848b 100644 --- a/relational_store/frameworks/native/rdb/src/result_set_proxy.cpp +++ b/relational_store/frameworks/native/rdb/src/result_set_proxy.cpp @@ -120,7 +120,16 @@ int ResultSetProxy::IsAtLastRow(bool &result) int ResultSetProxy::Get(int32_t col, ValueObject &value) { - return Send(Code::CMD_GET, value); + MessageParcel reply; + int status = SendRequest(Code::CMD_GET, reply, col); + if (status != E_OK) { + return status; + } + + if (!ITypesUtil::Unmarshal(reply, value.value)) { + return E_ERROR; + } + return E_OK; } int ResultSetProxy::GetSize(int columnIndex, size_t &size) @@ -161,11 +170,14 @@ int ResultSetProxy::Send(uint32_t code, T &...output) const { MessageParcel reply; auto status = SendRequest(code, reply); - auto success = ITypesUtil::Unmarshal(reply, status, output...); - if (status != E_OK || !success) { - LOG_ERROR("Reply failed, status:%{public}d, code:%{public}d.", status, code); + if (status != E_OK) { + return status; } - return status; + if (!ITypesUtil::Unmarshal(reply, output...)) { + LOG_ERROR("Unmarshal failed, code:%{public}d.", code); + return E_ERROR; + } + return E_OK; } template @@ -200,6 +212,7 @@ int ResultSetProxy::SendRequest(uint32_t code, MessageParcel &reply, const T &.. } auto success = ITypesUtil::Unmarshal(reply, status); if (status != E_OK || !success) { + LOG_ERROR("Reply failed, status:%{public}d, code:%{public}d.", status, code); return E_ERROR; } return status; diff --git a/relational_store/frameworks/native/rdb/src/share_block.cpp b/relational_store/frameworks/native/rdb/src/share_block.cpp index 05d4c730..3b81f8a2 100644 --- a/relational_store/frameworks/native/rdb/src/share_block.cpp +++ b/relational_store/frameworks/native/rdb/src/share_block.cpp @@ -114,16 +114,16 @@ int FillSharedBlockOpt(SharedBlockInfo *info, sqlite3_stmt *stmt) SeriPutNull, SeriPutOther }; auto db = sqlite3_db_handle(stmt); - int rc = sqlite3_db_config(db, SQLITE_DBCONFIG_SET_SHAREDBLOCK, stmt, &sqliteBlock); - if (rc != SQLITE_OK) { - LOG_ERROR("set sqlite shared block methods error. rc=%{private}d", rc); - return SQLiteError::ErrNo(rc); + int err = sqlite3_db_config(db, SQLITE_DBCONFIG_SET_SHAREDBLOCK, stmt, &sqliteBlock); + if (err != SQLITE_OK) { + LOG_ERROR("set sqlite shared block methods error. err=%{public}d, errno=%{public}d", err, errno); + return SQLiteError::ErrNo(err); } int retryCount = 0; while (true) { - int err = sqlite3_step(stmt); + err = sqlite3_step(stmt); if (err == SQLITE_LOCKED || err == SQLITE_BUSY) { - LOG_WARN("Database locked, retrying"); + LOG_WARN("Database locked, retrying err=%{public}d, errno=%{public}d", err, errno); if (retryCount <= RETRY_TIME) { usleep(SLEEP_TIME); retryCount++; @@ -136,12 +136,11 @@ int FillSharedBlockOpt(SharedBlockInfo *info, sqlite3_stmt *stmt) info->startPos = serializer.GetStartPos(); info->addedRows = serializer.GetAddedRows(); - rc = sqlite3_db_config(db, SQLITE_DBCONFIG_SET_SHAREDBLOCK, stmt, nullptr); - if (rc != SQLITE_OK) { - LOG_ERROR("clear sqlite shared block methods error. rc=%{public}d", rc); - return SQLiteError::ErrNo(rc); + err = sqlite3_db_config(db, SQLITE_DBCONFIG_SET_SHAREDBLOCK, stmt, nullptr); + if (err != SQLITE_OK) { + LOG_ERROR("clear sqlite shared block methods error. err=%{public}d, errno=%{public}d", err, errno); } - return E_OK; + return SQLiteError::ErrNo(err); } int FillSharedBlock(SharedBlockInfo *info, sqlite3_stmt *stmt) diff --git a/relational_store/frameworks/native/rdb/src/sqlite_connection.cpp b/relational_store/frameworks/native/rdb/src/sqlite_connection.cpp index 1f250bc2..0e73fd96 100644 --- a/relational_store/frameworks/native/rdb/src/sqlite_connection.cpp +++ b/relational_store/frameworks/native/rdb/src/sqlite_connection.cpp @@ -32,10 +32,11 @@ #include -#include "file_ex.h" #include "logger.h" #include "raw_data_parser.h" +#include "rdb_store_config.h" #include "rdb_errno.h" +#include "rdb_sql_statistic.h" #include "relational_store_client.h" #include "sqlite_errno.h" #include "sqlite_global_config.h" @@ -55,7 +56,9 @@ using RdbKeyFile = RdbSecurityManager::KeyFileType; #endif __attribute__((used)) -const int32_t SqliteConnection::g_reg = Connection::RegisterCreator(DB_SQLITE, SqliteConnection::Create); +const int32_t SqliteConnection::regCreater_ = Connection::RegisterCreator(DB_SQLITE, SqliteConnection::Create); +const int32_t SqliteConnection::regFileDeleter_ = + Connection::RegisterFileDeleter(DB_SQLITE, SqliteConnection::DeleteDbFile); std::pair> SqliteConnection::Create(const RdbStoreConfig &config, bool isWrite) { @@ -85,36 +88,26 @@ SqliteConnection::SqliteConnection(bool isWriteConnection) int SqliteConnection::InnerOpen(const RdbStoreConfig &config, uint32_t retry) { std::string dbPath; - auto ret = SqliteGlobalConfig::GetDbPath(config, dbPath); - if (ret != E_OK) { - return ret; + auto errCode = SqliteGlobalConfig::GetDbPath(config, dbPath); + if (errCode != E_OK) { + return errCode; } #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) bool isDbFileExist = access(dbPath.c_str(), F_OK) == 0; if (!isDbFileExist && (!config.IsCreateNecessary())) { - LOG_ERROR("SqliteConnection InnerOpen db not exist"); + LOG_ERROR("db not exist errno is %{public}d", errno); return E_DB_NOT_EXIST; } #endif isReadOnly = !isWriter_ || config.IsReadOnly(); int openFileFlags = config.IsReadOnly() ? (SQLITE_OPEN_READONLY | SQLITE_OPEN_FULLMUTEX) : (SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX); - int errCode = sqlite3_open_v2(dbPath.c_str(), &dbHandle, openFileFlags, nullptr); - if (errCode != SQLITE_OK) { - LOG_ERROR("SqliteConnection InnerOpen fail to open database err = %{public}d", errCode); -#if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) - auto const pos = dbPath.find_last_of("\\/"); - if (pos != std::string::npos) { - std::string filepath = dbPath.substr(0, pos); - if (access(filepath.c_str(), F_OK | W_OK) != 0) { - LOG_ERROR("The path to the database file to be created is not valid, err = %{public}d", errno); - return E_INVALID_FILE_PATH; - } - } -#endif - return SQLiteError::ErrNo(errCode); + errCode = OpenDatabase(dbPath, openFileFlags); + if (errCode != E_OK) { + return errCode; } + maxVariableNumber_ = sqlite3_limit(dbHandle, SQLITE_LIMIT_VARIABLE_NUMBER, -1); errCode = Configure(config, retry, dbPath); isConfigured_ = true; @@ -124,6 +117,11 @@ int SqliteConnection::InnerOpen(const RdbStoreConfig &config, uint32_t retry) if (isWriter_) { TryCheckPoint(); + auto [ret, object] = ExecuteForValue("PRAGMA integrity_check"); + if (ret == E_OK && static_cast(object) != "ok") { + LOG_ERROR("integrity check result is %{public}s", static_cast(object).c_str()); + return E_SQLITE_CORRUPT; + } } filePath = dbPath; @@ -132,6 +130,51 @@ int SqliteConnection::InnerOpen(const RdbStoreConfig &config, uint32_t retry) return E_OK; } +int32_t SqliteConnection::OpenDatabase(const std::string &dbPath, int openFileFlags) +{ + int errCode = sqlite3_open_v2(dbPath.c_str(), &dbHandle, openFileFlags, nullptr); + if (errCode != SQLITE_OK) { + LOG_ERROR("fail to open database errCode=%{public}d, dbPath=%{public}s, flags=%{public}d, errno=%{public}d", + errCode, dbPath.c_str(), openFileFlags, errno); +#if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) + auto const pos = dbPath.find_last_of("\\/"); + if (pos != std::string::npos) { + std::string filepath = dbPath.substr(0, pos); + if (access(filepath.c_str(), F_OK | W_OK) != 0) { + LOG_ERROR("The path to the database file to be created is not valid, err = %{public}d", errno); + return E_INVALID_FILE_PATH; + } + } + if (errCode == SQLITE_NOTADB) { + ReadFile2Buffer(dbPath.c_str()); + } +#endif + return SQLiteError::ErrNo(errCode); + } + return E_OK; +} + +void SqliteConnection::ReadFile2Buffer(const char* fileName) +{ + uint64_t buffer[BUFFER_LEN] = {0x0}; + FILE *file = fopen(fileName, "r"); + if (file == nullptr) { + LOG_ERROR("open db file failed: %{public}s, errno is %{public}d", fileName, errno); + return; + } + size_t readSize = fread(buffer, sizeof(uint64_t), BUFFER_LEN, file); + if (readSize != BUFFER_LEN) { + LOG_ERROR("read db file size: %{public}zu, errno is %{public}d", readSize, errno); + (void)fclose(file); + return; + } + for (uint32_t i = 0; i < BUFFER_LEN; i += 4) { + LOG_WARN("line%{public}d: %{public}" PRIx64 "%{public}" PRIx64 "%{public}" PRIx64 "%{public}" PRIx64, + i >> 2, buffer[i], buffer[i + 1], buffer[i + 2], buffer[i + 3]); + } + (void)fclose(file); +} + int SqliteConnection::SetCustomFunctions(const RdbStoreConfig &config) { customScalarFunctions_ = config.GetScalarFunctions(); @@ -160,7 +203,7 @@ static void CustomScalarFunctionCallback(sqlite3_context *ctx, int argc, sqlite3 for (int i = 0; i < argc; ++i) { auto arg = reinterpret_cast(sqlite3_value_text(argv[i])); if (arg == nullptr) { - LOG_ERROR("arg is nullptr, index is %{public}d", i); + LOG_ERROR("arg is nullptr, index is %{public}d, errno is %{public}d", i, errno); sqlite3_result_null(ctx); return; } @@ -180,7 +223,7 @@ int SqliteConnection::SetCustomScalarFunction(const std::string &functionName, i int err = sqlite3_create_function_v2(dbHandle, functionName.c_str(), argc, SQLITE_UTF8, function, &CustomScalarFunctionCallback, nullptr, nullptr, nullptr); if (err != SQLITE_OK) { - LOG_ERROR("SetCustomScalarFunction errCode is %{public}d", err); + LOG_ERROR("SetCustomScalarFunction errCode is %{public}d, errno is %{public}d.", err, errno); } return err; } @@ -258,7 +301,8 @@ SqliteConnection::~SqliteConnection() int errCode = sqlite3_close_v2(dbHandle); if (errCode != SQLITE_OK) { - LOG_ERROR("SqliteConnection ~SqliteConnection: could not close database err = %{public}d", errCode); + LOG_ERROR("SqliteConnection ~SqliteConnection: could not close database " + "err = %{public}d, errno = %{public}d", errCode, errno); } } } @@ -268,26 +312,14 @@ int32_t SqliteConnection::OnInitialize() return 0; } -std::pair> SqliteConnection::CreateStatement(const std::string &sql, - std::shared_ptr conn) +std::pair> SqliteConnection::CreateStatement( + const std::string &sql, std::shared_ptr conn) { - sqlite3_stmt *stmt = nullptr; - int errCode = sqlite3_prepare_v2(dbHandle, sql.c_str(), sql.length(), &stmt, nullptr); - if (errCode != SQLITE_OK) { - auto time = static_cast(duration_cast(system_clock::now().time_since_epoch()).count()); - LOG_ERROR("prepare_v2 ret is %{public}d %{public}" PRIu64 ".", errCode, time); - if (stmt != nullptr) { - sqlite3_finalize(stmt); - } - return { SQLiteError::ErrNo(errCode), nullptr }; - } std::shared_ptr statement = std::make_shared(); - statement->stmt_ = stmt; - statement->sql_ = sql; - statement->readOnly_ = (sqlite3_stmt_readonly(stmt) != 0); - statement->columnCount_ = sqlite3_column_count(stmt); - statement->numParameters_ = sqlite3_bind_parameter_count(stmt); - statement->types_ = std::vector(statement->columnCount_, 0); + int errCode = statement->Prepare(dbHandle, sql); + if (errCode != E_OK) { + return { errCode, nullptr }; + } statement->conn_ = conn; return { E_OK, statement }; } @@ -343,14 +375,13 @@ int SqliteConnection::SetPageSize(const RdbStoreConfig &config) } int targetValue = config.GetPageSize(); - int64_t value = 0; - int errCode = ExecuteGetLong(value, "PRAGMA page_size"); + auto [errCode, object] = ExecuteForValue("PRAGMA page_size"); if (errCode != E_OK) { LOG_ERROR("SqliteConnection SetPageSize fail to get page size : %{public}d", errCode); return errCode; } - if (value == targetValue) { + if (static_cast(object) == targetValue) { return E_OK; } @@ -389,9 +420,9 @@ int SqliteConnection::ExecuteEncryptSql(const RdbStoreConfig &config, uint32_t i return errCode; } - std::string version; - errCode = ExecuteGetString(version, GlobalExpr::PRAGMA_VERSION); - if (errCode != E_OK || version.empty()) { + ValueObject version; + std::tie(errCode, version) = ExecuteForValue(GlobalExpr::PRAGMA_VERSION); + if (errCode != E_OK || version.GetType() == ValueObject::TYPE_NULL) { LOG_ERROR("test failed, iter = %{public}d, err = %{public}d, name = %{public}s", iter, errCode, config.GetName().c_str()); return errCode; @@ -403,18 +434,11 @@ int SqliteConnection::ExecuteEncryptSql(const RdbStoreConfig &config, uint32_t i int SqliteConnection::ReSetKey(const RdbStoreConfig &config) { #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) - auto rdbPwd = RdbSecurityManager::GetInstance().GetRdbPassword(config.GetPath(), RdbKeyFile::PUB_KEY_FILE_NEW_KEY); - if (!rdbPwd.IsValid()) { - RdbSecurityManager::GetInstance().DelRdbSecretDataFile(config.GetPath(), RdbKeyFile::PUB_KEY_FILE_NEW_KEY); - LOG_ERROR("new key is not valid."); - return E_OK; - } - - auto key = std::vector(rdbPwd.GetData(), rdbPwd.GetData() + rdbPwd.GetSize()); - int errCode = sqlite3_rekey(dbHandle, static_cast(key.data()), static_cast(key.size())); - key.assign(key.size(), 0); + std::vector newKey = config.GetNewEncryptKey(); + int errCode = sqlite3_rekey(dbHandle, static_cast(newKey.data()), static_cast(newKey.size())); + newKey.assign(newKey.size(), 0); if (errCode != SQLITE_OK) { - LOG_ERROR("ReKey failed, err = %{public}d", errCode); + LOG_ERROR("ReKey failed, err = %{public}d, errno = %{public}d", errCode, errno); RdbSecurityManager::GetInstance().DelRdbSecretDataFile(config.GetPath(), RdbKeyFile::PUB_KEY_FILE_NEW_KEY); return E_OK; } @@ -438,39 +462,26 @@ int SqliteConnection::SetEncryptKey(const RdbStoreConfig &config, uint32_t iter) { #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) std::vector key = config.GetEncryptKey(); - bool isKeyExpired = false; - int32_t errCode = E_OK; - if (config.IsEncrypt()) { - errCode = RdbSecurityManager::GetInstance().Init(GetSecManagerName(config)); - if (errCode != E_OK) { - key.assign(key.size(), 0); - return errCode; - } - auto rdbPwd = RdbSecurityManager::GetInstance().GetRdbPassword(config.GetPath(), RdbKeyFile::PUB_KEY_FILE); - key.assign(key.size(), 0); - key = std::vector(rdbPwd.GetData(), rdbPwd.GetData() + rdbPwd.GetSize()); - isKeyExpired = rdbPwd.isKeyExpired; - } else if (key.empty()) { + if (key.size() == 0) { return E_OK; } - errCode = sqlite3_key(dbHandle, static_cast(key.data()), static_cast(key.size())); + auto errCode = sqlite3_key(dbHandle, static_cast(key.data()), static_cast(key.size())); key.assign(key.size(), 0); if (errCode != SQLITE_OK) { if (RdbSecurityManager::GetInstance().IsKeyFileExists(config.GetPath(), RdbKeyFile::PUB_KEY_FILE_NEW_KEY)) { - auto rdbPwd = - RdbSecurityManager::GetInstance().GetRdbPassword(config.GetPath(), RdbKeyFile::PUB_KEY_FILE_NEW_KEY); - key = std::vector(rdbPwd.GetData(), rdbPwd.GetData() + rdbPwd.GetSize()); - errCode = sqlite3_key(dbHandle, static_cast(key.data()), static_cast(key.size())); - key.assign(key.size(), 0); + std::vector newKey = config.GetNewEncryptKey(); + errCode = sqlite3_key(dbHandle, static_cast(newKey.data()), static_cast(newKey.size())); + newKey.assign(newKey.size(), 0); if (errCode != SQLITE_OK) { - LOG_ERROR("SqliteConnection SetEncryptKey fail with new key, err = %{public}d", errCode); + LOG_ERROR("SqliteConnection SetEncryptKey fail with new key, err = %{public}d errno = %{public}d", + errCode, errno); return SQLiteError::ErrNo(errCode); } RdbSecurityManager::GetInstance().UpdateKeyFile(config.GetPath()); } if (errCode != SQLITE_OK) { - LOG_ERROR("SqliteConnection SetEncryptKey fail, err = %{public}d", errCode); + LOG_ERROR("SqliteConnection SetEncryptKey fail, err = %{public}d, errno = %{public}d", errCode, errno); return SQLiteError::ErrNo(errCode); } } @@ -481,9 +492,10 @@ int SqliteConnection::SetEncryptKey(const RdbStoreConfig &config, uint32_t iter) return errCode; } - if (isKeyExpired) { + if (RdbSecurityManager::GetInstance().IsKeyFileExists(config.GetPath(), RdbKeyFile::PUB_KEY_FILE_NEW_KEY)) { ReSetKey(config); } + #endif return E_OK; } @@ -503,7 +515,7 @@ int SqliteConnection::SetBusyTimeout(int timeout) { auto errCode = sqlite3_busy_timeout(dbHandle, timeout); if (errCode != SQLITE_OK) { - LOG_ERROR("set buys timeout failed, errCode=%{public}d", errCode); + LOG_ERROR("set buys timeout failed, errCode=%{public}d, errno=%{public}d", errCode, errno); return errCode; } return E_OK; @@ -524,27 +536,26 @@ int SqliteConnection::SetJournalMode(const RdbStoreConfig &config) if (isReadOnly) { return E_OK; } - std::string currentMode; - int errCode = ExecuteGetString(currentMode, "PRAGMA journal_mode"); + + auto [errCode, object] = ExecuteForValue("PRAGMA journal_mode"); if (errCode != E_OK) { LOG_ERROR("SqliteConnection SetJournalMode fail to get journal mode : %{public}d", errCode); return errCode; } - if (config.GetJournalMode().compare(currentMode) == 0) { + if (config.GetJournalMode().compare(static_cast(object)) == 0) { return E_OK; } - currentMode = SqliteUtils::StrToUpper(currentMode); + std::string currentMode = SqliteUtils::StrToUpper(static_cast(object)); if (currentMode != config.GetJournalMode()) { - std::string result; - int errorCode = ExecuteGetString(result, "PRAGMA journal_mode=" + config.GetJournalMode()); + auto [errorCode, journalMode] = ExecuteForValue("PRAGMA journal_mode=" + config.GetJournalMode()); if (errorCode != E_OK) { LOG_ERROR("SqliteConnection SetJournalMode: fail to set journal mode err=%{public}d", errorCode); return errorCode; } - if (SqliteUtils::StrToUpper(result) != config.GetJournalMode()) { + if (SqliteUtils::StrToUpper(static_cast(journalMode)) != config.GetJournalMode()) { LOG_ERROR("SqliteConnection SetJournalMode: result incorrect"); return E_EXECUTE_RESULT_INCORRECT; } @@ -566,19 +577,17 @@ int SqliteConnection::SetJournalSizeLimit(const RdbStoreConfig &config) } int targetValue = SqliteGlobalConfig::GetJournalFileSize(); - int64_t currentValue = 0; - int errCode = ExecuteGetLong(currentValue, "PRAGMA journal_size_limit"); + auto [errCode, currentValue] = ExecuteForValue("PRAGMA journal_size_limit"); if (errCode != E_OK) { LOG_ERROR("SqliteConnection SetJournalSizeLimit fail to get journal_size_limit : %{public}d", errCode); return errCode; } - if (currentValue == targetValue) { + if (static_cast(currentValue) == targetValue) { return E_OK; } - int64_t result; - errCode = ExecuteGetLong(result, "PRAGMA journal_size_limit=" + std::to_string(targetValue)); + std::tie(errCode, currentValue) = ExecuteForValue("PRAGMA journal_size_limit=" + std::to_string(targetValue)); if (errCode != E_OK) { LOG_ERROR("SqliteConnection SetJournalSizeLimit fail to set journal_size_limit : %{public}d", errCode); } @@ -592,19 +601,17 @@ int SqliteConnection::SetAutoCheckpoint(const RdbStoreConfig &config) } int targetValue = SqliteGlobalConfig::GetWalAutoCheckpoint(); - int64_t value = 0; - int errCode = ExecuteGetLong(value, "PRAGMA wal_autocheckpoint"); + auto [errCode, value] = ExecuteForValue("PRAGMA wal_autocheckpoint"); if (errCode != E_OK) { LOG_ERROR("SqliteConnection SetAutoCheckpoint fail to get wal_autocheckpoint : %{public}d", errCode); return errCode; } - if (value == targetValue) { + if (static_cast(value) == targetValue) { return E_OK; } - int64_t result; - errCode = ExecuteGetLong(result, "PRAGMA wal_autocheckpoint=" + std::to_string(targetValue)); + std::tie(errCode, value) = ExecuteForValue("PRAGMA wal_autocheckpoint=" + std::to_string(targetValue)); if (errCode != E_OK) { LOG_ERROR("SqliteConnection SetAutoCheckpoint fail to set wal_autocheckpoint : %{public}d", errCode); } @@ -618,21 +625,20 @@ int SqliteConnection::SetWalSyncMode(const std::string &syncMode) targetValue = syncMode; } - std::string value; - int errCode = ExecuteGetString(value, "PRAGMA synchronous"); + auto [errCode, object] = ExecuteForValue("PRAGMA synchronous"); if (errCode != E_OK) { - LOG_ERROR("SqliteConnection setWalSyncMode fail to get synchronous mode : %{public}d", errCode); + LOG_ERROR("get wal sync mode fail, errCode:%{public}d", errCode); return errCode; } - value = SqliteUtils::StrToUpper(value); - if (value == targetValue) { + std::string walSyncMode = SqliteUtils::StrToUpper(static_cast(object)); + if (walSyncMode == targetValue) { return E_OK; } errCode = ExecuteSql("PRAGMA synchronous=" + targetValue); if (errCode != E_OK) { - LOG_ERROR("SqliteConnection setWalSyncMode fail to set synchronous mode : %{public}d", errCode); + LOG_ERROR("set wal sync mode fail, errCode:%{public}d", errCode); } return errCode; } @@ -646,38 +652,29 @@ int SqliteConnection::ExecuteSql(const std::string &sql, const std::vectorExecute(bindArgs); } -int SqliteConnection::ExecuteGetLong(int64_t &outValue, const std::string &sql, +std::pair SqliteConnection::ExecuteForValue(const std::string &sql, const std::vector &bindArgs) { auto [errCode, statement] = CreateStatement(sql, nullptr); if (statement == nullptr || errCode != E_OK) { - return errCode; + return { static_cast(errCode), ValueObject() }; } + ValueObject object; std::tie(errCode, object) = statement->ExecuteForValue(bindArgs); if (errCode != E_OK) { - LOG_ERROR("failed, %{public}d sql:%{public}s, args size:%{public}zu", SQLiteError::ErrNo(errCode), sql.c_str(), - bindArgs.size()); + LOG_ERROR("execute sql failed, errCode:%{public}d, sql:%{public}s, args size:%{public}zu", + SQLiteError::ErrNo(errCode), sql.c_str(), bindArgs.size()); } - outValue = object; - return errCode; + return { errCode, object }; } -int SqliteConnection::ExecuteGetString(std::string &outValue, const std::string &sql, - const std::vector &bindArgs) +int SqliteConnection::ClearCache() { - auto [errCode, statement] = CreateStatement(sql, nullptr); - if (statement == nullptr || errCode != E_OK) { - return errCode; - } - ValueObject object; - std::tie(errCode, object) = statement->ExecuteForValue(bindArgs); - if (errCode != E_OK) { - LOG_ERROR("failed, %{public}d sql:%{public}s, args size:%{public}zu", SQLiteError::ErrNo(errCode), sql.c_str(), - bindArgs.size()); + if (dbHandle != nullptr && mode_ == JournalMode::MODE_WAL) { + sqlite3_db_release_memory(dbHandle); } - outValue = static_cast(object); - return errCode; + return E_OK; } void SqliteConnection::LimitPermission(const std::string &dbPath) const @@ -868,15 +865,18 @@ void SqliteConnection::MergeAsset(ValueObject::Asset &oldAsset, ValueObject::Ass case Status::STATUS_UPDATE: // fallthrough if (oldAsset.modifyTime != newAsset.modifyTime || oldAsset.size != newAsset.size || oldAsset.uri != newAsset.uri || oldAsset.path != newAsset.path) { + if (oldAsset.modifyTime != newAsset.modifyTime || oldAsset.size != newAsset.size || + oldAsset.uri == newAsset.uri || oldAsset.path == newAsset.path) { + oldAsset.expiresTime = newAsset.expiresTime; + oldAsset.hash = newAsset.hash; + oldAsset.status = Status::STATUS_UPDATE; + } oldAsset.version = newAsset.version; - oldAsset.expiresTime = newAsset.expiresTime; oldAsset.uri = newAsset.uri; oldAsset.createTime = newAsset.createTime; oldAsset.modifyTime = newAsset.modifyTime; oldAsset.size = newAsset.size; - oldAsset.hash = newAsset.hash; oldAsset.path = newAsset.path; - oldAsset.status = Status ::STATUS_UPDATE; } return; default: @@ -884,6 +884,15 @@ void SqliteConnection::MergeAsset(ValueObject::Asset &oldAsset, ValueObject::Ass } } +void SqliteConnection::DeleteDbFile(const RdbStoreConfig &config) +{ + auto path = config.GetPath(); + SqliteUtils::DeleteFile(path); + SqliteUtils::DeleteFile(path + "-shm"); + SqliteUtils::DeleteFile(path + "-wal"); + SqliteUtils::DeleteFile(path + "-journal"); +} + int32_t SqliteConnection::Subscribe(const std::string &event, const std::shared_ptr &observer) { if (!isWriter_ || observer == nullptr) { @@ -968,5 +977,15 @@ int32_t SqliteConnection::UnsubscribeLocalDetailAll(const std::string &event) rdbStoreLocalDbObservers_.erase(event); return E_OK; } + +int32_t SqliteConnection::Backup(const std::string &databasePath, const std::vector &destEncryptKey) +{ + return E_NOT_SUPPORT; +} + +int32_t SqliteConnection::Restore(const std::string &databasePath, const std::vector &destEncryptKey) +{ + return E_NOT_SUPPORT; +}; } // namespace NativeRdb } // namespace OHOS diff --git a/relational_store/frameworks/native/rdb/src/sqlite_connection_pool.cpp b/relational_store/frameworks/native/rdb/src/sqlite_connection_pool.cpp index e33bfbc8..dd73bac2 100644 --- a/relational_store/frameworks/native/rdb/src/sqlite_connection_pool.cpp +++ b/relational_store/frameworks/native/rdb/src/sqlite_connection_pool.cpp @@ -16,6 +16,7 @@ #include "sqlite_connection_pool.h" #include + #include #include #include @@ -23,8 +24,10 @@ #include #include "logger.h" +#include "connection.h" #include "rdb_common.h" #include "rdb_errno.h" +#include "rdb_sql_statistic.h" #include "sqlite_global_config.h" #include "sqlite_utils.h" @@ -35,7 +38,7 @@ using Conn = Connection; using ConnPool = SqliteConnectionPool; using SharedConn = std::shared_ptr; using SharedConns = std::vector>; - +using SqlStatistic = DistributedRdb::SqlStatistic; constexpr int32_t TRANSACTION_TIMEOUT(2); std::shared_ptr ConnPool::Create(const RdbStoreConfig &storeConfig, int &errCode) @@ -43,6 +46,7 @@ std::shared_ptr ConnPool::Create(const RdbStoreConfig &storeConfig, in std::shared_ptr pool(new (std::nothrow) ConnPool(storeConfig)); if (pool == nullptr) { LOG_ERROR("ConnPool::Create new failed, pool is nullptr"); + errCode = E_ERROR; return nullptr; } std::shared_ptr conn; @@ -50,6 +54,28 @@ std::shared_ptr ConnPool::Create(const RdbStoreConfig &storeConfig, in return errCode == E_OK ? pool : nullptr; } +std::pair> ConnPool::HandleDataCorruption + (const RdbStoreConfig &storeConfig, int &errCode) +{ + std::pair> result; + auto &[rebuiltTpye, pool] = result; + + errCode = Connection::Repair(storeConfig); + if (errCode == E_OK) { + rebuiltTpye = RebuiltType::REPAIRED; + } else { + Connection::DeleteDbFile(storeConfig); + rebuiltTpye = RebuiltType::REBUILT; + } + pool = Create(storeConfig, errCode); + if (errCode != E_OK) { + LOG_WARN("failed, type %{public}d db %{public}s encrypt %{public}d error %{public}d, errno", + rebuiltTpye, storeConfig.GetName().c_str(), storeConfig.IsEncrypt(), errCode, errno); + } + + return result; +} + ConnPool::SqliteConnectionPool(const RdbStoreConfig &storeConfig) : config_(storeConfig), writers_(), readers_(), transactionStack_(), transactionUsed_(false) { @@ -57,14 +83,18 @@ ConnPool::SqliteConnectionPool(const RdbStoreConfig &storeConfig) std::pair> ConnPool::Init(const RdbStoreConfig &config, bool needWriter) { + if (config_.IsEncrypt()) { + config_.Initialize(); + } + std::pair> result; auto &[errCode, conn] = result; - if (config.GetRoleType() == OWNER) { + if (config.GetRoleType() == OWNER && !config.IsReadOnly()) { // write connect count is 1 std::shared_ptr node; std::tie(errCode, node) = writers_.Initialize( - [config]() { - return Connection::Create(config, true); + [this]() { + return Connection::Create(config_, true); }, 1, config.GetWriteTime(), true, needWriter); conn = Convert2AutoConn(node); @@ -73,14 +103,15 @@ std::pair> ConnPool::Init(const RdbStoreCon } } + config_.ChangeEncryptKey(); maxReader_ = GetMaxReaders(config); // max read connect count is 64 if (maxReader_ > 64) { return { E_ARGS_READ_CON_OVERLOAD, nullptr }; } auto [ret, node] = readers_.Initialize( - [config]() { - return Connection::Create(config, false); + [this]() { + return Connection::Create(config_, false); }, maxReader_, config.GetReadTime(), maxReader_ == 0); errCode = ret; @@ -137,13 +168,20 @@ void ConnPool::SetInTransaction(bool isInTransaction) isInTransaction_.store(isInTransaction); } +std::pair> ConnPool::CreateConnection(bool isReadOnly) +{ + return Connection::Create(config_, true); +} + std::shared_ptr ConnPool::AcquireConnection(bool isReadOnly) { + SqlStatistic sqlStatistic("", SqlStatistic::Step::STEP_WAIT); return Acquire(isReadOnly); } std::pair ConnPool::AcquireAll(int32_t time) { + SqlStatistic sqlStatistic("", SqlStatistic::Step::STEP_WAIT); using namespace std::chrono; std::pair result; auto &[writer, readers] = result; @@ -191,6 +229,7 @@ std::shared_ptr ConnPool::Acquire(bool isReadOnly, std::chrono::millisecon SharedConn ConnPool::AcquireRef(bool isReadOnly, std::chrono::milliseconds ms) { + SqlStatistic sqlStatistic("", SqlStatistic::Step::STEP_WAIT); if (maxReader_ != 0) { return Acquire(isReadOnly, ms); } @@ -279,19 +318,36 @@ int ConnPool::ChangeDbFileForRestore(const std::string &newPath, const std::stri return E_ERROR; } - CloseAllConnections(); - RemoveDBFile(); + if (config_.GetDBType() == DB_VECTOR) { + CloseAllConnections(); + auto [retVal, connection] = CreateConnection(false); - if (config_.GetPath() != newPath) { - RemoveDBFile(newPath); - } + if (connection == nullptr) { + LOG_ERROR("Get null connection"); + return retVal; + } - int retVal = SqliteUtils::RenameFile(backupPath, newPath); - if (retVal != E_OK) { - LOG_ERROR("RenameFile error"); - return retVal; - } + retVal = connection->Restore(backupPath, {}); + if (retVal != E_OK) { + LOG_ERROR("RdDbRestore error"); + return retVal; + } + CloseAllConnections(); + } else { + CloseAllConnections(); + RemoveDBFile(); + + if (config_.GetPath() != newPath) { + RemoveDBFile(newPath); + } + auto retVal = SqliteUtils::RenameFile(backupPath, newPath); + if (retVal != E_OK) { + LOG_ERROR("RenameFile filed error:%{public}d, errno:%{public}d, path:%{public}s", + retVal, errno, newPath.c_str()); + return retVal; + } + } auto [errCode, node] = Init(config_); return errCode; } @@ -341,6 +397,7 @@ void ConnPool::ConnNode::Unused() tid_ = 0; time_ = std::chrono::steady_clock::now(); if (connect_ != nullptr) { + connect_->ClearCache(); connect_->TryCheckPoint(); } } @@ -607,5 +664,6 @@ void ConnPool::RemoveDBFile(const std::string &path) SqliteUtils::DeleteFile(path + "-wal"); SqliteUtils::DeleteFile(path + "-journal"); } + } // namespace NativeRdb } // namespace OHOS 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 bf5489a8..cdb1ba15 100644 --- a/relational_store/frameworks/native/rdb/src/sqlite_global_config.cpp +++ b/relational_store/frameworks/native/rdb/src/sqlite_global_config.cpp @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#define LOG_TAG "SqliteGlobalConfig" +#define LOG_TAG "Config" #include "sqlite_global_config.h" #include @@ -40,7 +40,7 @@ SqliteGlobalConfig::SqliteGlobalConfig() sqlite3_config(SQLITE_CONFIG_MULTITHREAD); - sqlite3_config(SQLITE_CONFIG_LOG, &SqliteLogCallback, + sqlite3_config(SQLITE_CONFIG_LOG, &Log, GlobalExpr::CALLBACK_LOG_SWITCH ? reinterpret_cast(1) : NULL); sqlite3_soft_heap_limit(GlobalExpr::SOFT_HEAP_LIMIT); @@ -52,7 +52,7 @@ SqliteGlobalConfig::~SqliteGlobalConfig() { } -void SqliteGlobalConfig::SqliteLogCallback(const void *data, int err, const char *msg) +void SqliteGlobalConfig::Log(const void *data, int err, const char *msg) { bool verboseLog = (data != nullptr); auto errType = static_cast(err); @@ -60,12 +60,12 @@ void SqliteGlobalConfig::SqliteLogCallback(const void *data, int err, const char if (errType == 0 || errType == SQLITE_CONSTRAINT || errType == SQLITE_SCHEMA || errType == SQLITE_NOTICE || err == SQLITE_WARNING_AUTOINDEX) { if (verboseLog) { - LOG_INFO("SQLite Error(%{public}d) %{public}s ", err, msg); + LOG_INFO("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()); + LOG_WARN("WARNING(%{public}d) %{public}s ", err, SqliteUtils::Anonymous(msg).c_str()); } else { - LOG_ERROR("SQLite Error(%{public}d) errno is:%{public}d %{public}s" PRIu64 ".", err, errno, msg); + LOG_ERROR("Error(%{public}d) errno is:%{public}d %{public}s" PRIu64 ".", err, errno, msg); } } diff --git a/relational_store/frameworks/native/rdb/src/sqlite_shared_result_set.cpp b/relational_store/frameworks/native/rdb/src/sqlite_shared_result_set.cpp index d1a1960c..6db163ba 100644 --- a/relational_store/frameworks/native/rdb/src/sqlite_shared_result_set.cpp +++ b/relational_store/frameworks/native/rdb/src/sqlite_shared_result_set.cpp @@ -24,43 +24,91 @@ #include "logger.h" #include "rdb_sql_utils.h" +#include "rdb_sql_statistic.h" #include "result_set.h" #include "share_block.h" #include "sqlite_connection.h" #include "sqlite_statement.h" #include "sqlite_utils.h" +#include "sqlite_errno.h" namespace OHOS { namespace NativeRdb { using namespace OHOS::Rdb; SqliteSharedResultSet::SqliteSharedResultSet(std::shared_ptr pool, std::string path, std::string sql, const std::vector& bindArgs) - : AbsSharedResultSet(path), isOnlyFillBlock_(false), blockCapacity_(0), rowNum_(NO_COUNT), - qrySql_(sql), bindArgs_(std::move(bindArgs)) + : AbsSharedResultSet(path), isOnlyFillBlock_(false), blockCapacity_(0), qrySql_(std::move(sql)), + bindArgs_(std::move(bindArgs)) { conn_ = pool->AcquireRef(true); + if (conn_ == nullptr) { + isClosed_ = true; + } + auto [statement, errCode] = PrepareStep(); + if (errCode != E_OK) { + LOG_ERROR("step resultset ret %{public}d", errCode); + } + statement_ = statement; + rowCount_ = InitRowCount(); } -std::pair, int> SqliteSharedResultSet::PrepareStep() + +int SqliteSharedResultSet::InitRowCount() { - auto type = SqliteUtils::GetSqlStatementType(qrySql_); - if (type != SqliteUtils::STATEMENT_SELECT && type != SqliteUtils::STATEMENT_OTHER) { - LOG_ERROR("StoreSession BeginStepQuery fail : not select sql !"); - return {nullptr, E_NOT_SELECT}; + if (statement_ == nullptr) { + return NO_COUNT; + } + int32_t count = NO_COUNT; + int32_t status = E_OK; + int32_t retry = 0; + do { + status = statement_->Step(); + if (status == E_SQLITE_BUSY || status == E_SQLITE_LOCKED) { + retry++; + usleep(RETRY_INTERVAL); + continue; + } + count++; + } while (status == E_OK || ((status == E_SQLITE_BUSY || status == E_SQLITE_LOCKED) && retry < MAX_RETRY_TIMES)); + if (status != E_NO_MORE_ROWS) { + count = NO_COUNT; } + statement_->Reset(); + return count; +} + +std::pair, int> SqliteSharedResultSet::PrepareStep() +{ if (conn_ == nullptr) { LOG_ERROR("Already close"); - return {nullptr, E_ALREADY_CLOSED}; + return { nullptr, E_ALREADY_CLOSED }; + } + + if (statement_ != nullptr) { + return { statement_, E_OK }; + } + + auto type = SqliteUtils::GetSqlStatementType(qrySql_); + if (type == SqliteUtils::STATEMENT_ERROR) { + LOG_ERROR("invalid sql_ %{public}s!", qrySql_.c_str()); + return { nullptr, E_INVALID_ARGS }; } + auto [errCode, statement] = conn_->CreateStatement(qrySql_, conn_); - if (statement == nullptr || errCode != E_OK) { - return { nullptr, E_ERROR }; + if (statement == nullptr) { + return { statement, errCode }; } + + if (!statement->ReadOnly()) { + LOG_ERROR("failed, %{public}s is not query sql!", SqliteUtils::Anonymous(qrySql_).c_str()); + return { nullptr, E_NOT_SELECT }; + } + errCode = statement->Bind(bindArgs_); if (errCode != E_OK) { LOG_ERROR("Bind arg faild! Ret is %{public}d", errCode); statement->Reset(); statement = nullptr; - return { nullptr, E_ERROR }; + return { nullptr, errCode }; } return { statement, E_OK }; } @@ -70,6 +118,8 @@ SqliteSharedResultSet::~SqliteSharedResultSet() {} std::pair> SqliteSharedResultSet::GetColumnNames() { if (isClosed_) { + LOG_ERROR("fail, result set has been closed, ret %{public}d, sql %{public}s", + E_ALREADY_CLOSED, qrySql_.c_str()); return { E_ALREADY_CLOSED, {} }; } @@ -92,52 +142,32 @@ std::pair> SqliteSharedResultSet::GetColumnNames() return { E_OK, std::move(colNames) }; } -int SqliteSharedResultSet::GetRowCount(int &count) -{ - if (rowNum_ != NO_COUNT) { - count = rowNum_; - return E_OK; - } - - if (isClosed_) { - return E_ALREADY_CLOSED; - } - - auto errCode = FillBlock(0); - count = rowNum_; - - if (count == 0) { - rowNum_ = NO_COUNT; - errCode = FillBlock(0); - count = rowNum_; - } - return errCode; -} - int SqliteSharedResultSet::Close() { AbsSharedResultSet::Close(); conn_ = nullptr; + statement_ = nullptr; + rowCount_ = NO_COUNT; auto qrySql = std::move(qrySql_); auto bindArgs = std::move(bindArgs_); - auto columnNames = std::move(columnNames_); return E_OK; } int SqliteSharedResultSet::OnGo(int oldPosition, int newPosition) { if (isClosed_) { + LOG_ERROR("fail, result set has been closed, ret %{public}d, sql %{public}s", + E_ALREADY_CLOSED, qrySql_.c_str()); return E_ALREADY_CLOSED; } - auto errCode = E_ERROR; if (GetBlock() == nullptr) { - return FillBlock(newPosition); + return E_ERROR; } if ((uint32_t)newPosition < GetBlock()->GetStartPos() || (uint32_t)newPosition >= GetBlock()->GetLastPos() - || oldPosition == rowNum_) { - errCode = FillBlock(newPosition); + || oldPosition == rowCount_) { + return FillBlock(newPosition); } - return errCode; + return E_OK; } /** @@ -156,24 +186,15 @@ int SqliteSharedResultSet::FillBlock(int requiredPos) return E_ERROR; } ClearBlock(); - if (rowNum_ == NO_COUNT) { - auto [errCode, rowNum] = ExecuteForSharedBlock(block.get(), requiredPos, requiredPos, true); - if (errCode != E_OK) { - return errCode; - } - blockCapacity_ = static_cast(block->GetRowNum()); - rowNum_ = rowNum; - } else { - int startPos = isOnlyFillBlock_ ? requiredPos : PickFillBlockStartPosition(requiredPos, blockCapacity_); - auto [errCode, rowNum] = ExecuteForSharedBlock(block.get(), startPos, requiredPos, false); - if (errCode != E_OK) { - return errCode; - } - blockCapacity_ = block->GetRowNum(); - LOG_INFO("blockRowNum=%{public}d, requiredPos= %{public}d, startPos_= %{public}" PRIu32 - ", lastPos_= %{public}" PRIu32 ", blockPos_= %{public}" PRIu32 ".", - rowNum_, requiredPos, block->GetStartPos(), block->GetLastPos(), block->GetBlockPos()); + int startPos = isOnlyFillBlock_ ? requiredPos : PickFillBlockStartPosition(requiredPos, blockCapacity_); + auto errCode = ExecuteForSharedBlock(block.get(), startPos, requiredPos); + if (errCode != E_OK) { + return errCode; } + blockCapacity_ = block->GetRowNum(); + LOG_INFO("blockRowNum=%{public}d, requiredPos= %{public}d, startPos_= %{public}" PRIu32 + ", lastPos_= %{public}" PRIu32 ", blockPos_= %{public}" PRIu32 ".", + rowCount_, requiredPos, block->GetStartPos(), block->GetLastPos(), block->GetBlockPos()); return E_OK; } @@ -199,46 +220,40 @@ void SqliteSharedResultSet::Finalize() /** * Executes a statement and populates the specified with a range of results. */ -std::pair SqliteSharedResultSet::ExecuteForSharedBlock(AppDataFwk::SharedBlock* block, int start, - int required, bool needCount) +int32_t SqliteSharedResultSet::ExecuteForSharedBlock(AppDataFwk::SharedBlock *block, int start, int required) { - int32_t rowNum = NO_COUNT; auto [statement, errCode] = PrepareStep(); if (errCode != E_OK) { LOG_ERROR("PrepareStep error = %{public}d ", errCode); - return { errCode, rowNum }; + return errCode; } auto code = block->Clear(); if (code != AppDataFwk::SharedBlock::SHARED_BLOCK_OK) { LOG_ERROR("Clear %{public}d.", code); - return { E_ERROR, rowNum }; + return E_ERROR; } SharedBlockInfo blockInfo(block); blockInfo.requiredPos = required; blockInfo.columnNum = statement->GetColumnCount(); - blockInfo.isCountAllRows = needCount; + blockInfo.isCountAllRows = false; blockInfo.startPos = start; code = block->SetColumnNum(blockInfo.columnNum); if (code != AppDataFwk::SharedBlock::SHARED_BLOCK_OK) { LOG_ERROR("SetColumnNum %{public}d.", code); - return { E_ERROR, rowNum }; + return E_ERROR; } - - code = statement->FillBlockInfo(&blockInfo); - if (code != E_OK) { - LOG_ERROR("Fill shared block failed, ret is %{public}d", code); - return { code, rowNum }; + errCode = statement->FillBlockInfo(&blockInfo); + if (errCode != E_OK) { + LOG_ERROR("Fill shared block failed, ret is %{public}d", errCode); + return errCode; } block->SetStartPos(blockInfo.startPos); block->SetBlockPos(required - blockInfo.startPos); block->SetLastPos(blockInfo.startPos + block->GetRowNum()); - if (needCount) { - rowNum = static_cast(GetCombinedData(blockInfo.startPos, blockInfo.totalRows)); - } - return { statement->Reset(), rowNum }; + return E_OK; } } // namespace NativeRdb } // namespace OHOS \ No newline at end of file diff --git a/relational_store/frameworks/native/rdb/src/sqlite_sql_builder.cpp b/relational_store/frameworks/native/rdb/src/sqlite_sql_builder.cpp index 1fa86123..229edd4c 100644 --- a/relational_store/frameworks/native/rdb/src/sqlite_sql_builder.cpp +++ b/relational_store/frameworks/native/rdb/src/sqlite_sql_builder.cpp @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +#define LOG_TAG "SqliteSqlBuilder" #include "sqlite_sql_builder.h" #include @@ -321,5 +321,62 @@ std::string SqliteSqlBuilder::BuildLockRowQueryString( AppendClause(sql, " OFFSET ", offsetClause); return sql; } + +std::string SqliteSqlBuilder::GetSqlArgs(size_t size) +{ + std::string args((size << 1) - 1, '?'); + for (size_t i = 1; i < size; ++i) { + args[(i << 1) - 1] = ','; + } + return args; +} + +SqliteSqlBuilder::ExecuteSqls SqliteSqlBuilder::MakeExecuteSqls( + const std::string &sql, std::vector &&args, int fieldSize, int limit) +{ + if (fieldSize == 0) { + return ExecuteSqls(); + } + size_t rowNumbers = args.size() / static_cast(fieldSize); + size_t maxRowNumbersOneTimes = static_cast(limit / fieldSize); + if (maxRowNumbersOneTimes == 0) { + return ExecuteSqls(); + } + size_t executeTimes = rowNumbers / maxRowNumbersOneTimes; + size_t remainingRows = rowNumbers % maxRowNumbersOneTimes; + LOG_DEBUG("rowNumbers %{public}zu, maxRowNumbersOneTimes %{public}zu, executeTimes %{public}zu," + "remainingRows %{public}zu, fieldSize %{public}d, limit %{public}d", + rowNumbers, maxRowNumbersOneTimes, executeTimes, remainingRows, fieldSize, limit); + std::string singleRowSqlArgs = "(" + SqliteSqlBuilder::GetSqlArgs(fieldSize) + ")"; + auto appendAgsSql = [&singleRowSqlArgs, &sql] (size_t rowNumber) { + std::string sqlStr = sql; + for (size_t i = 0; i < rowNumber; ++i) { + sqlStr.append(singleRowSqlArgs).append(","); + } + sqlStr.pop_back(); + return sqlStr; + }; + std::string executeSql; + ExecuteSqls executeSqls; + auto start = args.begin(); + if (executeTimes != 0) { + executeSql = appendAgsSql(maxRowNumbersOneTimes); + std::vector> sqlArgs; + size_t maxVariableNumbers = maxRowNumbersOneTimes * static_cast(fieldSize); + for (size_t i = 0; i < executeTimes; ++i) { + std::vector bindValueArgs(start, start + maxVariableNumbers); + sqlArgs.emplace_back(std::move(bindValueArgs)); + start += maxVariableNumbers; + } + executeSqls.emplace_back(std::make_pair(executeSql, std::move(sqlArgs))); + } + + if (remainingRows != 0) { + executeSql = appendAgsSql(remainingRows); + std::vector> sqlArgs(1, std::vector(start, args.end())); + executeSqls.emplace_back(std::make_pair(executeSql, std::move(sqlArgs))); + } + return executeSqls; +} } // namespace NativeRdb } // namespace OHOS diff --git a/relational_store/frameworks/native/rdb/src/sqlite_statement.cpp b/relational_store/frameworks/native/rdb/src/sqlite_statement.cpp index 52bbc976..3475d473 100644 --- a/relational_store/frameworks/native/rdb/src/sqlite_statement.cpp +++ b/relational_store/frameworks/native/rdb/src/sqlite_statement.cpp @@ -24,7 +24,9 @@ #include "logger.h" #include "raw_data_parser.h" #include "rdb_errno.h" +#include "rdb_sql_statistic.h" #include "relational_store_client.h" +#include "remote_result_set.h" #include "share_block.h" #include "shared_block_serializer_info.h" #include "sqlite3.h" @@ -38,12 +40,18 @@ namespace OHOS { namespace NativeRdb { using namespace OHOS::Rdb; using namespace std::chrono; +using SqlStatistic = DistributedRdb::SqlStatistic; // Setting Data Precision constexpr SqliteStatement::Action SqliteStatement::ACTIONS[ValueObject::TYPE_MAX]; -SqliteStatement::SqliteStatement() : readOnly_(false), columnCount_(0), numParameters_(0), stmt_(nullptr), sql_("") {} +SqliteStatement::SqliteStatement() : readOnly_(false), columnCount_(0), numParameters_(0), stmt_(nullptr), sql_("") +{ + seqId_ = SqlStatistic::GenerateId(); + SqlStatistic sqlStatistic("", SqlStatistic::Step::STEP_TOTAL_REF, seqId_); +} SqliteStatement::~SqliteStatement() { + SqlStatistic sqlStatistic("", SqlStatistic::Step::STEP_TOTAL_RES, seqId_); Finalize(); conn_ = nullptr; } @@ -55,6 +63,7 @@ int SqliteStatement::Prepare(sqlite3 *dbHandle, const std::string &newSql) } // prepare the new sqlite3_stmt sqlite3_stmt *stmt = nullptr; + SqlStatistic sqlStatistic(newSql, SqlStatistic::Step::STEP_PREPARE, seqId_); int errCode = sqlite3_prepare_v2(dbHandle, newSql.c_str(), newSql.length(), &stmt, nullptr); if (errCode != SQLITE_OK) { if (stmt != nullptr) { @@ -67,15 +76,17 @@ int SqliteStatement::Prepare(sqlite3 *dbHandle, const std::string &newSql) stmt_ = stmt; readOnly_ = (sqlite3_stmt_readonly(stmt_) != 0); columnCount_ = sqlite3_column_count(stmt_); - types_ = std::vector(columnCount_, 0); + types_ = std::vector(columnCount_, COLUMN_TYPE_INVALID); numParameters_ = sqlite3_bind_parameter_count(stmt_); return E_OK; } int SqliteStatement::BindArgs(const std::vector &bindArgs) { + SqlStatistic sqlStatistic("", SqlStatistic::Step::STEP_PREPARE, seqId_); if (bound_) { - Reset(); + sqlite3_reset(stmt_); + sqlite3_clear_bindings(stmt_); } bound_ = true; int index = 1; @@ -87,7 +98,7 @@ int SqliteStatement::BindArgs(const std::vector &bindArgs) } auto errCode = action(stmt_, index, arg.value); if (errCode != SQLITE_OK) { - LOG_ERROR("Bind has error: %{public}d, sql: %{public}s", errCode, sql_.c_str()); + LOG_ERROR("Bind has error: %{public}d, sql: %{public}s, errno %{public}d", errCode, sql_.c_str(), errno); return SQLiteError::ErrNo(errCode); } index++; @@ -150,7 +161,8 @@ int SqliteStatement::Bind(const std::vector &args) int SqliteStatement::Step() { - return sqlite3_step(stmt_); + SqlStatistic sqlStatistic("", SqlStatistic::Step::STEP_EXECUTE, seqId_); + return SQLiteError::ErrNo(sqlite3_step(stmt_)); } int SqliteStatement::Reset() @@ -161,13 +173,7 @@ int SqliteStatement::Reset() int errCode = sqlite3_reset(stmt_); if (errCode != SQLITE_OK) { - LOG_ERROR("reset ret is %{public}d", errCode); - return SQLiteError::ErrNo(errCode); - } - - errCode = sqlite3_clear_bindings(stmt_); - if (errCode != SQLITE_OK) { - LOG_ERROR("clear_bindings ret is %{public}d", errCode); + LOG_ERROR("reset ret is %{public}d, errno is %{public}d", errCode, errno); return SQLiteError::ErrNo(errCode); } return E_OK; @@ -187,7 +193,7 @@ int SqliteStatement::Finalize() numParameters_ = 0; types_ = std::vector(); if (errCode != SQLITE_OK) { - LOG_ERROR("finalize ret is %{public}d", errCode); + LOG_ERROR("finalize ret is %{public}d, errno is %{public}d", errCode, errno); return SQLiteError::ErrNo(errCode); } return E_OK; @@ -217,10 +223,10 @@ int SqliteStatement::Execute(const std::vector &args) if (errCode != E_OK) { return errCode; } - errCode = sqlite3_step(stmt_); - if (errCode != SQLITE_DONE && errCode != SQLITE_ROW) { - LOG_ERROR("sqlite3_step failed %{public}d, sql is %{public}s", errCode, sql_.c_str()); - return SQLiteError::ErrNo(errCode); + errCode = Step(); + if (errCode != E_NO_MORE_ROWS && errCode != E_OK) { + LOG_ERROR("sqlite3_step failed %{public}d, sql is %{public}s, errno %{public}d", errCode, sql_.c_str(), errno); + return errCode; } return E_OK; } @@ -272,38 +278,56 @@ std::pair SqliteStatement::GetColumnName(int index) const return { E_OK, std::string(name) }; } +static int32_t Convert2ColumnType(int32_t type) +{ + switch (type) { + case SQLITE_INTEGER: + return int32_t(ColumnType::TYPE_INTEGER); + case SQLITE_FLOAT: + return int32_t(ColumnType::TYPE_FLOAT); + case SQLITE_BLOB: + return int32_t(ColumnType::TYPE_BLOB); + case SQLITE_TEXT: + return int32_t(ColumnType::TYPE_STRING); + default: + break; + } + return int32_t(ColumnType::TYPE_NULL); +} + std::pair SqliteStatement::GetColumnType(int index) const { int ret = IsValid(index); if (ret != E_OK) { - return { ret, SQLITE_NULL }; + return { ret, int32_t(ColumnType::TYPE_NULL) }; } int type = sqlite3_column_type(stmt_, index); if (type != SQLITE_BLOB) { - return { E_OK, type }; + return { E_OK, Convert2ColumnType(type) }; } - if (types_[index] != 0) { + + if (types_[index] != COLUMN_TYPE_INVALID) { return { E_OK, types_[index] }; } const char *decl = sqlite3_column_decltype(stmt_, index); if (decl == nullptr) { - LOG_ERROR("invalid type %{public}d.", type); - return { E_ERROR, SQLITE_NULL }; + LOG_ERROR("invalid type %{public}d, errno %{public}d.", type, errno); + return { E_ERROR, int32_t(ColumnType::TYPE_NULL) }; } auto declType = SqliteUtils::StrToUpper(std::string(decl)); if (declType == ValueObject::DeclType()) { - types_[index] = COLUMN_TYPE_ASSET; + types_[index] = int32_t(ColumnType::TYPE_ASSET); } else if (declType == ValueObject::DeclType()) { - types_[index] = COLUMN_TYPE_ASSETS; + types_[index] = int32_t(ColumnType::TYPE_ASSETS); } else if (declType == ValueObject::DeclType()) { - types_[index] = COLUMN_TYPE_FLOATS; + types_[index] = int32_t(ColumnType::TYPE_FLOAT32_ARRAY); } else if (declType == ValueObject::DeclType()) { - types_[index] = COLUMN_TYPE_BIGINT; + types_[index] = int32_t(ColumnType::TYPE_BIGINT); } else { - types_[index] = SQLITE_BLOB; + types_[index] = int32_t(ColumnType::TYPE_BLOB); } return { E_OK, types_[index] }; @@ -316,7 +340,8 @@ std::pair SqliteStatement::GetSize(int index) const return { errCode, 0 }; } - if (type == SQLITE_TEXT || type == SQLITE_BLOB || type == SQLITE_NULL) { + if (type == int32_t(ColumnType::TYPE_STRING) || type == int32_t(ColumnType::TYPE_BLOB) || + type == int32_t(ColumnType::TYPE_NULL)) { auto size = static_cast(sqlite3_column_bytes(stmt_, index)); return { E_OK, size }; } @@ -330,17 +355,17 @@ std::pair SqliteStatement::GetColumn(int index) const return { errCode, ValueObject() }; } - switch (type) { - case SQLITE_FLOAT: + switch (static_cast(type)) { + case ColumnType::TYPE_FLOAT: return { E_OK, ValueObject(sqlite3_column_double(stmt_, index)) }; - case SQLITE_INTEGER: + case ColumnType::TYPE_INTEGER: return { E_OK, ValueObject(static_cast(sqlite3_column_int64(stmt_, index))) }; - case SQLITE_TEXT: { + case ColumnType::TYPE_STRING: { int size = sqlite3_column_bytes(stmt_, index); auto text = reinterpret_cast(sqlite3_column_text(stmt_, index)); return { E_OK, ValueObject(text == nullptr ? std::string("") : std::string(text, size)) }; } - case SQLITE_NULL: + case ColumnType::TYPE_NULL: return { E_OK, ValueObject() }; default: break; @@ -355,23 +380,23 @@ ValueObject SqliteStatement::GetValueFromBlob(int32_t index, int32_t type) const if (blob == nullptr || size <= 0) { return ValueObject(); } - switch (type) { - case COLUMN_TYPE_ASSET: { + switch (static_cast(type)) { + case ColumnType::TYPE_ASSET: { Asset asset; RawDataParser::ParserRawData(blob, size, asset); return ValueObject(std::move(asset)); } - case COLUMN_TYPE_ASSETS: { + case ColumnType::TYPE_ASSETS: { Assets assets; RawDataParser::ParserRawData(blob, size, assets); return ValueObject(std::move(assets)); } - case COLUMN_TYPE_FLOATS: { + case ColumnType::TYPE_FLOAT32_ARRAY: { Floats floats; RawDataParser::ParserRawData(blob, size, floats); return ValueObject(std::move(floats)); } - case COLUMN_TYPE_BIGINT: { + case ColumnType::TYPE_BIGINT: { BigInt bigint; RawDataParser::ParserRawData(blob, size, bigint); return ValueObject(std::move(bigint)); @@ -395,6 +420,7 @@ bool SqliteStatement::SupportBlockInfo() const int32_t SqliteStatement::FillBlockInfo(SharedBlockInfo *info) const { + SqlStatistic sqlStatistic("", SqlStatistic::Step::STEP_EXECUTE, seqId_); if (info == nullptr) { return E_ERROR; } diff --git a/relational_store/frameworks/native/rdb/src/sqlite_utils.cpp b/relational_store/frameworks/native/rdb/src/sqlite_utils.cpp index f0e9939d..359f0476 100644 --- a/relational_store/frameworks/native/rdb/src/sqlite_utils.cpp +++ b/relational_store/frameworks/native/rdb/src/sqlite_utils.cpp @@ -133,14 +133,11 @@ std::string SqliteUtils::Anonymous(const std::string &srcFile) int SqliteUtils::GetFileSize(const std::string &fileName) { - if (fileName.empty() || access(fileName.c_str(), F_OK) != 0) { - return 0; - } - struct stat fileStat; - if (stat(fileName.c_str(), &fileStat) < 0) { - LOG_ERROR("Failed to get file information, errno: %{public}d", errno); - return INT_MAX; + if (fileName.empty() || stat(fileName.c_str(), &fileStat) < 0) { + LOG_ERROR("Failed to get file infos, errno: %{public}d, fileName:%{public}s", + errno, Anonymous(fileName).c_str()); + return 0; } return static_cast(fileStat.st_size); diff --git a/relational_store/frameworks/native/rdb/src/step_result_set.cpp b/relational_store/frameworks/native/rdb/src/step_result_set.cpp index be32e876..0f77f2a1 100644 --- a/relational_store/frameworks/native/rdb/src/step_result_set.cpp +++ b/relational_store/frameworks/native/rdb/src/step_result_set.cpp @@ -31,10 +31,11 @@ namespace NativeRdb { using namespace OHOS::Rdb; StepResultSet::StepResultSet(std::shared_ptr pool, const std::string &sql, const std::vector &args) - : AbsResultSet(), sql_(sql), args_(std::move(args)), rowCount_(INIT_POS), isAfterLast_(false), isStarted_(false) + : AbsResultSet(), sql_(sql), args_(std::move(args)) { conn_ = pool->AcquireRef(true); if (conn_ == nullptr) { + isClosed_ = true; return; } @@ -42,6 +43,7 @@ StepResultSet::StepResultSet(std::shared_ptr pool, const s if (errCode != E_OK) { LOG_ERROR("step resultset ret %{public}d", errCode); } + rowCount_ = InitRowCount(); } StepResultSet::~StepResultSet() @@ -49,6 +51,31 @@ StepResultSet::~StepResultSet() Close(); } +int StepResultSet::InitRowCount() +{ + auto statement = GetStatement(); + if (statement == nullptr) { + return NO_COUNT; + } + int32_t count = NO_COUNT; + int32_t status = E_OK; + int32_t retry = 0; + do { + status = statement->Step(); + if (status == E_SQLITE_BUSY || status == E_SQLITE_LOCKED) { + retry++; + usleep(STEP_QUERY_RETRY_INTERVAL); + continue; + } + count++; + } while (status == E_OK || + ((status == E_SQLITE_BUSY || status == E_SQLITE_LOCKED) && retry < STEP_QUERY_RETRY_MAX_TIMES)); + if (status != E_NO_MORE_ROWS) { + count = NO_COUNT; + } + statement->Reset(); + return count; +} /** * Obtain session and prepare precompile statement for step query */ @@ -63,9 +90,9 @@ int StepResultSet::PrepareStep() } auto type = SqliteUtils::GetSqlStatementType(sql_); - if (type != SqliteUtils::STATEMENT_SELECT && type != SqliteUtils::STATEMENT_OTHER) { - LOG_ERROR("not a select sql_!"); - return E_NOT_SELECT; + if (type == SqliteUtils::STATEMENT_ERROR) { + LOG_ERROR("invalid sql_ %{public}s!", sql_.c_str()); + return E_INVALID_ARGS; } auto [errCode, statement] = conn_->CreateStatement(sql_, conn_); @@ -73,6 +100,11 @@ int StepResultSet::PrepareStep() return E_STATEMENT_NOT_PREPARED; } + if (!statement->ReadOnly()) { + LOG_ERROR("failed, %{public}s is not query sql!", SqliteUtils::Anonymous(sql_).c_str()); + return E_NOT_SELECT; + } + errCode = statement->Bind(args_); if (errCode != E_OK) { LOG_ERROR("Bind arg faild! Ret is %{public}d", errCode); @@ -120,7 +152,7 @@ int StepResultSet::GetColumnType(int columnIndex, ColumnType &columnType) if (isClosed_) { return E_ALREADY_CLOSED; } - if (rowPos_ == INIT_POS || isAfterLast_) { + if (rowPos_ == INIT_POS || IsEnded().second) { LOG_ERROR("query not executed."); return E_ROW_OUT_RANGE; } @@ -130,68 +162,12 @@ int StepResultSet::GetColumnType(int columnIndex, ColumnType &columnType) return E_ALREADY_CLOSED; } - auto [errCode, sqliteType] = statement->GetColumnType(columnIndex); + auto [errCode, outPutType] = statement->GetColumnType(columnIndex); if (errCode != E_OK) { LOG_ERROR("GetColumnType ret %{public}d", errCode); return errCode; } - - switch (sqliteType) { - case SQLITE_INTEGER: - columnType = ColumnType::TYPE_INTEGER; - break; - case SQLITE_FLOAT: - columnType = ColumnType::TYPE_FLOAT; - break; - case SQLITE_BLOB: - columnType = ColumnType::TYPE_BLOB; - break; - case SqliteStatement::COLUMN_TYPE_ASSET: - columnType = ColumnType::TYPE_ASSET; - break; - case SqliteStatement::COLUMN_TYPE_ASSETS: - columnType = ColumnType::TYPE_ASSETS; - break; - case SqliteStatement::COLUMN_TYPE_FLOATS: - columnType = ColumnType::TYPE_FLOAT32_ARRAY; - break; - case SqliteStatement::COLUMN_TYPE_BIGINT: - columnType = ColumnType::TYPE_BIGINT; - break; - case SQLITE_NULL: - columnType = ColumnType::TYPE_NULL; - break; - default: - columnType = ColumnType::TYPE_STRING; - break; - } - - return E_OK; -} - -int StepResultSet::GetRowCount(int &count) -{ - if (isClosed_) { - return E_ALREADY_CLOSED; - } - if (rowCount_ != INIT_POS) { - count = rowCount_; - return E_OK; - } - int oldPosition = 0; - // Get the start position of the query result - GetRowIndex(oldPosition); - - while (GoToNextRow() == E_OK) { - } - count = rowCount_; - // Reset the start position of the query result - if (oldPosition != INIT_POS) { - GoToRow(oldPosition); - } else { - Reset(); - isStarted_ = false; - } + columnType = static_cast(outPutType); return E_OK; } @@ -203,13 +179,13 @@ int StepResultSet::GoToRow(int position) if (isClosed_) { return E_ALREADY_CLOSED; } - if (position < 0) { - LOG_ERROR("position %{public}d.", position); - return E_ERROR; - } - if (position == rowPos_) { - return E_OK; + + if (position >= rowCount_ || position < 0) { + rowPos_ = (position >= rowCount_ && rowCount_ != 0) ? rowCount_ : rowPos_; + LOG_ERROR("position[%{public}d] rowCount[%{public}d] rowPos_[%{public}d]!", position, rowCount_, rowPos_); + return E_ROW_OUT_RANGE; } + if (position < rowPos_) { Reset(); return GoToRow(position); @@ -218,7 +194,7 @@ int StepResultSet::GoToRow(int position) int errCode = GoToNextRow(); if (errCode != E_OK) { LOG_WARN("GoToNextRow ret %{public}d", errCode); - return errCode == E_NO_MORE_ROWS ? E_ROW_OUT_RANGE : errCode; + return errCode; } } return E_OK; @@ -248,7 +224,7 @@ int StepResultSet::GoToNextRow() int retryCount = 0; errCode = statement->Step(); - while (errCode == SQLITE_LOCKED || errCode == SQLITE_BUSY) { + while (errCode == E_SQLITE_LOCKED || errCode == E_SQLITE_BUSY) { // The table is locked, retry if (retryCount > STEP_QUERY_RETRY_MAX_TIMES) { LOG_ERROR("Step in busy ret is %{public}d", errCode); @@ -261,23 +237,16 @@ int StepResultSet::GoToNextRow() } } - if (errCode == SQLITE_ROW) { + if (errCode == E_OK) { rowPos_++; - isStarted_ = true; return E_OK; - } else if (errCode == SQLITE_DONE) { - if (!isAfterLast_ && rowCount_ != EMPTY_ROW_COUNT) { - rowCount_ = rowPos_ + 1; - } - isAfterLast_ = rowCount_ != EMPTY_ROW_COUNT; - isStarted_ = true; - FinishStep(); - rowPos_ = rowCount_; - return E_NO_MORE_ROWS; + } else if (errCode == E_NO_MORE_ROWS) { + rowPos_ = rowCount_ != 0 ? rowCount_ : rowPos_; + return E_ROW_OUT_RANGE; } else { - FinishStep(); + Reset(); rowPos_ = rowCount_; - return SQLiteError::ErrNo(errCode); + return errCode; } } @@ -290,56 +259,20 @@ int StepResultSet::Close() conn_ = nullptr; sqliteStatement_ = nullptr; auto args = std::move(args_); - return FinishStep(); + Reset(); + return E_OK; } /** - * Release resource of step result set, this method can be called more than once + * Reset the statement */ -int StepResultSet::FinishStep() +int StepResultSet::Reset() { + rowPos_ = INIT_POS; auto statement = GetStatement(); if (statement != nullptr) { - statement->Reset(); - sqliteStatement_ = nullptr; + return statement->Reset(); } - rowPos_ = INIT_POS; - return E_OK; -} - -/** - * Reset the statement - */ -void StepResultSet::Reset() -{ - FinishStep(); - isAfterLast_ = false; -} - -/** - * Checks whether the result set is positioned after the last row - */ -int StepResultSet::IsEnded(bool &result) -{ - result = isAfterLast_; - return E_OK; -} - -/** - * Checks whether the result set is moved - */ -int StepResultSet::IsStarted(bool &result) const -{ - result = isStarted_; - return E_OK; -} - -/** - * Check whether the result set is in the first row - */ -int StepResultSet::IsAtFirstRow(bool &result) const -{ - result = (rowPos_ == 0) && (rowCount_ != 0); return E_OK; } @@ -356,7 +289,7 @@ int StepResultSet::GetSize(int columnIndex, size_t &size) if (isClosed_) { return E_ALREADY_CLOSED; } - if (rowPos_ == INIT_POS || isAfterLast_) { + if (rowPos_ == INIT_POS || IsEnded().second) { size = 0; return E_ROW_OUT_RANGE; } @@ -385,7 +318,7 @@ int StepResultSet::GetValue(int32_t col, T &value) std::pair StepResultSet::GetValueObject(int32_t col, size_t index) { - if (rowPos_ == INIT_POS || isAfterLast_) { + if (rowPos_ == INIT_POS || IsEnded().second) { return { E_ROW_OUT_RANGE, ValueObject() }; } auto statement = GetStatement(); diff --git a/relational_store/frameworks/native/rdb/src/string_utils.cpp b/relational_store/frameworks/native/rdb/src/string_utils.cpp index 936b8986..07e6dd06 100644 --- a/relational_store/frameworks/native/rdb/src/string_utils.cpp +++ b/relational_store/frameworks/native/rdb/src/string_utils.cpp @@ -60,6 +60,16 @@ std::vector StringUtils::Split(const std::string &str, const std::s return res; } +std::string StringUtils::ExtractFilePath(const std::string& fileFullName) +{ + return std::string(fileFullName).substr(0, fileFullName.rfind("/") + 1); +} + +std::string StringUtils::ExtractFileName(const std::string& fileFullName) +{ + return std::string(fileFullName).substr(fileFullName.rfind("/") + 1, fileFullName.size()); +} + StringUtils::StringUtils() {} StringUtils::~StringUtils() {} } // namespace NativeRdb diff --git a/relational_store/frameworks/native/rdb/src/value_object.cpp b/relational_store/frameworks/native/rdb/src/value_object.cpp index b102cf44..c950e6f4 100644 --- a/relational_store/frameworks/native/rdb/src/value_object.cpp +++ b/relational_store/frameworks/native/rdb/src/value_object.cpp @@ -257,7 +257,7 @@ static int32_t GetPrecision(double val) ValueObject::operator std::string() const { std::string val; - int type = value.index(); + int type = static_cast(value.index()); if (type == ValueObject::TYPE_INT) { auto temp = std::get(value); val = std::to_string(temp); diff --git a/relational_store/frameworks/native/rdb/src/vdb_store_impl.cpp b/relational_store/frameworks/native/rdb/src/vdb_store_impl.cpp deleted file mode 100644 index d3f902bf..00000000 --- a/relational_store/frameworks/native/rdb/src/vdb_store_impl.cpp +++ /dev/null @@ -1,427 +0,0 @@ -/* - * Copyright (c) 2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#define LOG_TAG "VdbStoreImpl" -#include "vdb_store_impl.h" - -#include -#include -#include -#include -#include "logger.h" -#include "cache_result_set.h" -#include "rdb_errno.h" -#include "rdb_sql_utils.h" -#include "rdb_store.h" -#include "rdb_store_impl.h" -#include "rdb_trace.h" -#include "rd_result_set.h" -#include "rd_utils.h" -#include "sqlite_global_config.h" -#include "sqlite_sql_builder.h" -#include "sqlite_utils.h" -#include "step_result_set.h" -#include "task_executor.h" -#include "traits.h" - -namespace OHOS::NativeRdb { -using namespace OHOS::Rdb; -using namespace std::chrono; - -VdbStoreImpl::VdbStoreImpl(const RdbStoreConfig &config, int &errCode) : RdbStoreImpl(config), - rdConnectionPool_(nullptr) -{ - rdConnectionPool_ = RdbConnectionPool::Create(config_, errCode); - if (rdConnectionPool_ == nullptr || errCode != E_OK) { - rdConnectionPool_ = nullptr; - LOG_ERROR("InnerOpen failed, err is %{public}d", errCode); - return; - } -} - -VdbStoreImpl::~VdbStoreImpl() -{ - rdConnectionPool_ = nullptr; -} - -std::pair VdbStoreImpl::BeginTrans() -{ - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); - auto time = static_cast(duration_cast(system_clock::now().time_since_epoch()).count()); - int64_t tmpTrxId = 0; - auto connection = rdConnectionPool_->AcquireNewConnection(false, tmpTrxId); - if (connection == nullptr) { - LOG_ERROR("Get null connection, storeName: %{public}s time:%{public}" PRIu64 ".", name_.c_str(), time); - return {E_DATABASE_BUSY, 0}; - } - int ret = connection->ExecuteSql(RdUtils::BEGIN_TRANSACTION_SQL); - if (ret != E_OK) { - LOG_ERROR("transaction id: %{public}" PRIu64 ", storeName: %{public}s, errCode:\ - %{public}d times:%{public}" PRIu64 ".", tmpTrxId, name_.c_str(), ret, time); - return {ret, 0}; - } - connection->SetInTransaction(true); - return {E_OK, tmpTrxId}; -} - -int VdbStoreImpl::Commit(int64_t trxId) -{ - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); - auto time = static_cast(duration_cast(system_clock::now().time_since_epoch()).count()); - auto connection = rdConnectionPool_->AcquireConnection(false, trxId); - if (connection == nullptr) { - LOG_ERROR("Get null connection, storeName: %{public}s time:%{public}" PRIu64 ".", name_.c_str(), time); - return E_INVALID_ARGS; - } - int ret = connection->ExecuteSql(RdUtils::COMMIT_TRANSACTION_SQL); - if (ret != E_OK) { - LOG_ERROR("transaction id: %{public}" PRIu64 ", storeName: %{public}s, errCode:\ - %{public}d times:%{public}" PRIu64 ".", trxId, name_.c_str(), ret, time); - return ret; - } - connection->SetInTransaction(false); - rdConnectionPool_->ReleaseConnection(connection); - return E_OK; -} - -int VdbStoreImpl::RollBack(int64_t trxId) -{ - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); - auto time = static_cast(duration_cast(system_clock::now().time_since_epoch()).count()); - auto connection = rdConnectionPool_->AcquireConnection(false, trxId); - if (connection == nullptr) { - LOG_ERROR("Get null connection, storeName: %{public}s time:%{public}" PRIu64 ".", name_.c_str(), time); - return E_INVALID_ARGS; - } - int ret = connection->ExecuteSql(RdUtils::ROLLBACK_TRANSACTION_SQL); - if (ret != E_OK) { - LOG_ERROR( - "transaction id: %{public}" PRIu64 ", storeName: %{public}s, errCode: %{public}d times:%{public}" PRIu64, - trxId, name_.c_str(), ret, time); - return ret; - } - connection->SetInTransaction(false); - rdConnectionPool_->ReleaseConnection(connection); - return E_OK; -} - -std::pair VdbStoreImpl::Execute(const std::string &sql, - const std::vector &bindArgs, int64_t txId) -{ - ValueObject outValue; - int sqlType = SqliteUtils::GetSqlStatementType(sql); - if (sqlType == SqliteUtils::STATEMENT_SELECT) { - LOG_ERROR("Not support the sql: %{public}s", SqliteUtils::Anonymous(sql).c_str()); - return { E_NOT_SUPPORT_THE_SQL, outValue }; - } - if (sqlType == SqliteUtils::STATEMENT_PRAGMA) { - LOG_ERROR("Not support the sql: %{public}s", SqliteUtils::Anonymous(sql).c_str()); - return { E_NOT_SUPPORT_THE_SQL, outValue }; - } - int32_t ret = E_OK; - txId < 0 ? ret = E_INVALID_ARGS : ret = ExecuteSqlByTrxId(sql, bindArgs, (uint64_t)txId); - return { ret, ValueObject() }; -} - -int VdbStoreImpl::ExecuteSqlByTrxId(const std::string &sql, const std::vector &bindArgs, int64_t trxId) -{ - bool isRead = trxId == 0 ? true : false; - auto connection = rdConnectionPool_->AcquireConnection(isRead, trxId); - if (connection == nullptr) { - LOG_ERROR("Get null connection"); - return E_INVALID_ARGS; - } - int ret = connection->ExecuteSql(sql, bindArgs); - if (ret != E_OK) { - LOG_ERROR("RdbStore unable to execute sql"); - return ret; - } - if (trxId == 0) { - rdConnectionPool_->ReleaseConnection(connection); - } - return E_OK; -} - -std::shared_ptr VdbStoreImpl::QuerySql(const std::string &sql, - const std::vector &bindArgs) -{ - DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); - return std::make_shared(rdConnectionPool_, sql, bindArgs); -} - -int VdbStoreImpl::Insert(int64_t &outRowId, const std::string &table, const ValuesBucket &values) -{ - return E_NOT_SUPPORT; -} - -int VdbStoreImpl::BatchInsert(int64_t& outInsertNum, const std::string& table, const std::vector& values) -{ - return E_NOT_SUPPORT; -} - -int VdbStoreImpl::Replace(int64_t &outRowId, const std::string &table, const ValuesBucket &initialValues) -{ - return E_NOT_SUPPORT; -} - -int VdbStoreImpl::InsertWithConflictResolution(int64_t &outRowId, const std::string &table, const ValuesBucket &values, - ConflictResolution conflictResolution) -{ - return E_NOT_SUPPORT; -} - -int VdbStoreImpl::Update(int &changedRows, const std::string &table, const ValuesBucket &values, - const std::string &whereClause, const std::vector &whereArgs) -{ - return E_NOT_SUPPORT; -} - -int VdbStoreImpl::Update(int &changedRows, const std::string &table, const ValuesBucket &values, - const std::string &whereClause, const std::vector &bindArgs) -{ - return E_NOT_SUPPORT; -} - -int VdbStoreImpl::UpdateWithConflictResolution(int &changedRows, const std::string &table, const ValuesBucket &values, - const std::string &whereClause, const std::vector &whereArgs, - ConflictResolution conflictResolution) -{ - return E_NOT_SUPPORT; -} - -int VdbStoreImpl::UpdateWithConflictResolution(int &changedRows, const std::string &table, const ValuesBucket &values, - const std::string &whereClause, const std::vector &bindArgs, - ConflictResolution conflictResolution) -{ - return E_NOT_SUPPORT; -} - -int VdbStoreImpl::Delete(int &deletedRows, const std::string &table, const std::string &whereClause, - const std::vector &whereArgs) -{ - return E_NOT_SUPPORT; -} - -int VdbStoreImpl::Delete(int &deletedRows, const std::string &table, const std::string &whereClause, - const std::vector &bindArgs) -{ - return E_NOT_SUPPORT; -} - -std::shared_ptr VdbStoreImpl::Query(int &errCode, bool distinct, - const std::string &table, const std::vector &columns, - const std::string &whereClause, const std::vector &bindArgs, const std::string &groupBy, - const std::string &indexName, const std::string &orderBy, const int &limit, const int &offset) -{ - return nullptr; -} - -std::shared_ptr VdbStoreImpl::QuerySql(const std::string &sql, - const std::vector &sqlArgs) -{ - return nullptr; -} - -int VdbStoreImpl::ExecuteSql(const std::string& sql, const std::vector& bindArgs) -{ - return E_NOT_SUPPORT; -} - -int VdbStoreImpl::ExecuteAndGetLong( - int64_t &outValue, const std::string &sql, const std::vector &bindArgs) -{ - return E_NOT_SUPPORT; -} - -int VdbStoreImpl::ExecuteAndGetString(std::string &outValue, const std::string &sql, - const std::vector &bindArgs) -{ - return E_NOT_SUPPORT; -} - -int VdbStoreImpl::ExecuteForLastInsertedRowId(int64_t &outValue, const std::string &sql, - const std::vector &bindArgs) -{ - return E_NOT_SUPPORT; -} - -int VdbStoreImpl::ExecuteForChangedRowCount(int64_t &outValue, const std::string &sql, - const std::vector &bindArgs) -{ - return E_NOT_SUPPORT; -} - -int VdbStoreImpl::Backup(const std::string &databasePath, const std::vector &destEncryptKey) -{ - return E_NOT_SUPPORT; -} - -int VdbStoreImpl::GetVersion(int &version) -{ - return E_NOT_SUPPORT; -} - -int VdbStoreImpl::SetVersion(int version) -{ - return E_NOT_SUPPORT; -} - -int VdbStoreImpl::BeginTransaction() -{ - return E_NOT_SUPPORT; -} - -int VdbStoreImpl::RollBack() -{ - return E_NOT_SUPPORT; -} - -int VdbStoreImpl::Commit() -{ - return E_NOT_SUPPORT; -} - -bool VdbStoreImpl::IsInTransaction() -{ - return false; -} - -int VdbStoreImpl::Restore(const std::string &backupPath, const std::vector &newKey) -{ - return E_NOT_SUPPORT; -} - -std::shared_ptr VdbStoreImpl::QueryByStep(const std::string &sql, const std::vector &sqlArgs) -{ - return nullptr; -} - -std::shared_ptr VdbStoreImpl::QueryByStep(const std::string &sql, const std::vector &args) -{ - return nullptr; -} - -std::shared_ptr VdbStoreImpl::QueryByStep( - const AbsRdbPredicates &predicates, const std::vector &columns) -{ - return nullptr; -} - -std::shared_ptr VdbStoreImpl::Query( - const AbsRdbPredicates &predicates, const std::vector &columns) -{ - return nullptr; -} - -std::pair> VdbStoreImpl::QuerySharingResource( - const AbsRdbPredicates &predicates, const std::vector &columns) -{ - return { E_NOT_SUPPORT, nullptr }; -} - -int VdbStoreImpl::Count(int64_t &outValue, const AbsRdbPredicates &predicates) -{ - return E_NOT_SUPPORT; -} - -int VdbStoreImpl::Update(int &changedRows, const ValuesBucket &values, const AbsRdbPredicates &predicates) -{ - return E_NOT_SUPPORT; -} - -int VdbStoreImpl::Delete(int &deletedRows, const AbsRdbPredicates &predicates) -{ - return E_NOT_SUPPORT; -} - -std::shared_ptr VdbStoreImpl::RemoteQuery(const std::string &device, const AbsRdbPredicates &predicates, - const std::vector &columns, int &errCode) -{ - return nullptr; -} - -int VdbStoreImpl::SetDistributedTables(const std::vector &tables, int32_t type, - const DistributedRdb::DistributedConfig &distributedConfig) -{ - return E_NOT_SUPPORT; -} - -std::string VdbStoreImpl::ObtainDistributedTableName(const std::string& device, const std::string& table, int &errCode) -{ - return ""; -} - -int VdbStoreImpl::Sync(const SyncOption &option, const AbsRdbPredicates &predicate, const AsyncBrief &async) -{ - return E_NOT_SUPPORT; -} - -int VdbStoreImpl::Sync(const SyncOption &option, const std::vector &tables, const AsyncDetail &async) -{ - return E_NOT_SUPPORT; -} - -int VdbStoreImpl::Sync(const SyncOption &option, const AbsRdbPredicates &predicate, const AsyncDetail &async) -{ - return E_NOT_SUPPORT; -} - -int VdbStoreImpl::Subscribe(const SubscribeOption& option, RdbStoreObserver *observer) -{ - return E_NOT_SUPPORT; -} - -int VdbStoreImpl::UnSubscribe(const SubscribeOption& option, RdbStoreObserver *observer) -{ - return E_NOT_SUPPORT; -} - -int VdbStoreImpl::RegisterAutoSyncCallback(std::shared_ptr observer) -{ - return E_NOT_SUPPORT; -} - -int VdbStoreImpl::UnregisterAutoSyncCallback(std::shared_ptr observer) -{ - return E_NOT_SUPPORT; -} - -int VdbStoreImpl::Notify(const std::string &event) -{ - return E_NOT_SUPPORT; -} - -RdbStore::ModifyTime VdbStoreImpl::GetModifyTime(const std::string& table, const std::string& columnName, - std::vector& keys) -{ - return {}; -} - -int VdbStoreImpl::CleanDirtyData(const std::string &table, uint64_t cursor) -{ - return E_NOT_SUPPORT; -} - -std::pair VdbStoreImpl::Attach( - const RdbStoreConfig &config, const std::string &attachName, int32_t waitTime) - { - return { E_NOT_SUPPORT, 0 }; - } - -std::pair VdbStoreImpl::Detach(const std::string &attachName, int32_t waitTime) -{ - return { E_NOT_SUPPORT, 0 }; -} - -} // namespace OHOS::NativeRdb \ No newline at end of file diff --git a/relational_store/interfaces/inner_api/appdatafwk/BUILD.gn b/relational_store/interfaces/inner_api/appdatafwk/BUILD.gn index a461b771..f327747e 100644 --- a/relational_store/interfaces/inner_api/appdatafwk/BUILD.gn +++ b/relational_store/interfaces/inner_api/appdatafwk/BUILD.gn @@ -73,6 +73,8 @@ if (is_android || is_ios) { if (is_ohos) { branch_protector_ret = "pac_ret" sanitize = { + boundary_sanitize = true + ubsan = true cfi = true cfi_cross_dso = true debug = false @@ -107,6 +109,8 @@ if (is_android || is_ios) { ohos_shared_library("native_appdatafwk") { branch_protector_ret = "pac_ret" sanitize = { + boundary_sanitize = true + ubsan = true cfi = true cfi_cross_dso = true debug = false diff --git a/relational_store/interfaces/inner_api/cloud_data/BUILD.gn b/relational_store/interfaces/inner_api/cloud_data/BUILD.gn index f233ac4a..716079d7 100644 --- a/relational_store/interfaces/inner_api/cloud_data/BUILD.gn +++ b/relational_store/interfaces/inner_api/cloud_data/BUILD.gn @@ -24,6 +24,8 @@ config("cloud_public_config") { ohos_static_library("cloud_data_inner") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false diff --git a/relational_store/interfaces/inner_api/cloud_data/include/cloud_service.h b/relational_store/interfaces/inner_api/cloud_data/include/cloud_service.h index e25fb827..d3d65c85 100644 --- a/relational_store/interfaces/inner_api/cloud_data/include/cloud_service.h +++ b/relational_store/interfaces/inner_api/cloud_data/include/cloud_service.h @@ -16,6 +16,7 @@ #ifndef OHOS_DISTRIBUTED_DATA_CLOUD_CLOUD_SERVICE_H #define OHOS_DISTRIBUTED_DATA_CLOUD_CLOUD_SERVICE_H #include +#include #include #include #include @@ -67,9 +68,13 @@ public: SWITCH_OFF }; + enum CloudSyncModule { + CLOUD_SYNC_MODULE_ID = 10, + }; + static const ErrCode CLOUD_ERR_OFFSET = ErrCodeOffset(SUBSYS_DISTRIBUTEDDATAMNG, CLOUD_SYNC_MODULE_ID); enum Status : int32_t { SUCCESS = 0, - ERROR, + ERROR = CLOUD_ERR_OFFSET + 1, INVALID_ARGUMENT, SERVER_UNAVAILABLE, FEATURE_UNAVAILABLE, @@ -79,7 +84,11 @@ public: IPC_ERROR, IPC_PARCEL_ERROR, PERMISSION_DENIED, - CLOUD_CONFIG_PERMISSION_DENIED + CLOUD_CONFIG_PERMISSION_DENIED, + NETWORK_ERROR, + CLOUD_INFO_INVALID, + SCHEMA_INVALID, + STRATEGY_BLOCKING, }; static const int INVALID_USER_ID = -1; diff --git a/relational_store/interfaces/inner_api/dataability/BUILD.gn b/relational_store/interfaces/inner_api/dataability/BUILD.gn index 8634eb04..97d6ef4f 100644 --- a/relational_store/interfaces/inner_api/dataability/BUILD.gn +++ b/relational_store/interfaces/inner_api/dataability/BUILD.gn @@ -38,6 +38,8 @@ config("native_dataability_public_config") { ohos_shared_library("native_dataability") { branch_protector_ret = "pac_ret" sanitize = { + boundary_sanitize = true + ubsan = true cfi = true cfi_cross_dso = true debug = false @@ -55,7 +57,9 @@ ohos_shared_library("native_dataability") { configs = [ ":native_dataability_config" ] - deps = [ "${relational_store_innerapi_path}/rdb:native_rdb" ] + if (!(host_os == "linux" && host_cpu == "arm64")) { + deps = [ "${relational_store_innerapi_path}/rdb:native_rdb" ] + } external_deps = [ "c_utils:utils", diff --git a/relational_store/interfaces/inner_api/rdb/BUILD.gn b/relational_store/interfaces/inner_api/rdb/BUILD.gn index f9c05379..6e582cea 100644 --- a/relational_store/interfaces/inner_api/rdb/BUILD.gn +++ b/relational_store/interfaces/inner_api/rdb/BUILD.gn @@ -25,6 +25,8 @@ base_sources = [ "${relational_store_native_path}/rdb/src/rdb_helper.cpp", "${relational_store_native_path}/rdb/src/rdb_local_db_observer.cpp", "${relational_store_native_path}/rdb/src/rdb_predicates.cpp", + "${relational_store_native_path}/rdb/src/rdb_security_manager.cpp", + "${relational_store_native_path}/rdb/src/rdb_sql_statistic.cpp", "${relational_store_native_path}/rdb/src/rdb_sql_utils.cpp", "${relational_store_native_path}/rdb/src/rdb_store_config.cpp", "${relational_store_native_path}/rdb/src/rdb_store_impl.cpp", @@ -54,12 +56,14 @@ if (is_ohos && !build_ohos_sdk) { "include", "${relational_store_common_path}/include", "${relational_store_native_path}/rdb/include", + "${relational_store_native_path}/dfx/include", "${relational_store_native_path}/rdb_device_manager_adapter/include", ] defines = [ "RELATIONAL_STORE", "SQLITE_HAS_CODEC", + "RDB_TRACE_ON", ] if (relational_store_rdb_support_icu) { @@ -85,6 +89,9 @@ if (is_ohos && !build_ohos_sdk) { include_dirs = [ "include", "${relational_store_native_path}/rdb/include", + "${relational_store_native_path}/dfx/include", + "../cloud_data/include", + "../common_type/include", ] } @@ -96,6 +103,8 @@ if (is_ohos && !build_ohos_sdk) { ohos_shared_library("native_rdb") { branch_protector_ret = "pac_ret" sanitize = { + boundary_sanitize = true + ubsan = true cfi = true cfi_cross_dso = true debug = false @@ -112,20 +121,16 @@ if (is_ohos && !build_ohos_sdk) { ldflags = [ "-Wl,--exclude-libs,ALL" ] cflags_cc = [ "-fvisibility=hidden" ] sources += [ + "${relational_store_native_path}/dfx/src/rdb_radar_reporter.cpp", "${relational_store_native_path}/rdb/src/abs_shared_result_set.cpp", "${relational_store_native_path}/rdb/src/delay_notify.cpp", "${relational_store_native_path}/rdb/src/grd_api_manager.cpp", "${relational_store_native_path}/rdb/src/rd_connection.cpp", - "${relational_store_native_path}/rdb/src/rd_result_set.cpp", "${relational_store_native_path}/rdb/src/rd_statement.cpp", "${relational_store_native_path}/rdb/src/rd_utils.cpp", - "${relational_store_native_path}/rdb/src/rdb_connection.cpp", - "${relational_store_native_path}/rdb/src/rdb_connection_pool.cpp", "${relational_store_native_path}/rdb/src/rdb_manager_impl.cpp", "${relational_store_native_path}/rdb/src/rdb_notifier_stub.cpp", - "${relational_store_native_path}/rdb/src/rdb_security_manager.cpp", "${relational_store_native_path}/rdb/src/rdb_service_proxy.cpp", - "${relational_store_native_path}/rdb/src/rdb_statement.cpp", "${relational_store_native_path}/rdb/src/rdb_types_util.cpp", "${relational_store_native_path}/rdb/src/result_set_proxy.cpp", "${relational_store_native_path}/rdb/src/security_policy.cpp", @@ -133,7 +138,6 @@ if (is_ohos && !build_ohos_sdk) { "${relational_store_native_path}/rdb/src/shared_block_serializer_info.cpp", "${relational_store_native_path}/rdb/src/sqlite_shared_result_set.cpp", "${relational_store_native_path}/rdb/src/task_executor.cpp", - "${relational_store_native_path}/rdb/src/vdb_store_impl.cpp", "${relational_store_native_path}/rdb_device_manager_adapter/src/rdb_device_manager_adapter.cpp", ] @@ -145,9 +149,11 @@ if (is_ohos && !build_ohos_sdk) { external_deps = [ "ability_base:zuri", "ability_runtime:dataobs_manager", + "access_token:libaccesstoken_sdk", "c_utils:utils", "device_manager:devicemanagersdk", "hilog:libhilog", + "hisysevent:libhisysevent", "hitrace:hitrace_meter", "huks:libhukssdk", "ipc:ipc_core", @@ -167,6 +173,8 @@ if (is_ohos && !build_ohos_sdk) { ohos_static_library("native_rdb_static") { branch_protector_ret = "pac_ret" sanitize = { + boundary_sanitize = true + ubsan = true cfi = true cfi_cross_dso = true debug = false @@ -182,20 +190,16 @@ if (is_ohos && !build_ohos_sdk) { ldflags = [ "-Wl,--exclude-libs,ALL" ] sources += [ + "${relational_store_native_path}/dfx/src/rdb_radar_reporter.cpp", "${relational_store_native_path}/rdb/src/abs_shared_result_set.cpp", "${relational_store_native_path}/rdb/src/delay_notify.cpp", "${relational_store_native_path}/rdb/src/grd_api_manager.cpp", "${relational_store_native_path}/rdb/src/rd_connection.cpp", - "${relational_store_native_path}/rdb/src/rd_result_set.cpp", "${relational_store_native_path}/rdb/src/rd_statement.cpp", "${relational_store_native_path}/rdb/src/rd_utils.cpp", - "${relational_store_native_path}/rdb/src/rdb_connection.cpp", - "${relational_store_native_path}/rdb/src/rdb_connection_pool.cpp", "${relational_store_native_path}/rdb/src/rdb_manager_impl.cpp", "${relational_store_native_path}/rdb/src/rdb_notifier_stub.cpp", - "${relational_store_native_path}/rdb/src/rdb_security_manager.cpp", "${relational_store_native_path}/rdb/src/rdb_service_proxy.cpp", - "${relational_store_native_path}/rdb/src/rdb_statement.cpp", "${relational_store_native_path}/rdb/src/rdb_types_util.cpp", "${relational_store_native_path}/rdb/src/result_set_proxy.cpp", "${relational_store_native_path}/rdb/src/security_policy.cpp", @@ -203,7 +207,6 @@ if (is_ohos && !build_ohos_sdk) { "${relational_store_native_path}/rdb/src/shared_block_serializer_info.cpp", "${relational_store_native_path}/rdb/src/sqlite_shared_result_set.cpp", "${relational_store_native_path}/rdb/src/task_executor.cpp", - "${relational_store_native_path}/rdb/src/vdb_store_impl.cpp", "${relational_store_native_path}/rdb_device_manager_adapter/src/rdb_device_manager_adapter.cpp", ] @@ -215,9 +218,11 @@ if (is_ohos && !build_ohos_sdk) { external_deps = [ "ability_base:zuri", "ability_runtime:dataobs_manager", + "access_token:libaccesstoken_sdk", "c_utils:utils", "device_manager:devicemanagersdk", "hilog:libhilog", + "hisysevent:libhisysevent", "hitrace:hitrace_meter", "huks:libhukssdk", "ipc:ipc_core", @@ -244,6 +249,7 @@ if (is_ohos && !build_ohos_sdk) { "include", "//foundation/communication/ipc/interfaces/innerkits/ipc_core/include", "${relational_store_native_path}/rdb/include", + "${relational_store_native_path}/dfx/include", "//third_party/libuv/src/win", ] @@ -277,6 +283,8 @@ if (is_ohos && !build_ohos_sdk) { "mock/include", "include", "//third_party/libuv/src/win", + "../cloud_data/include", + "../common_type/include", ] } @@ -293,8 +301,10 @@ if (is_ohos && !build_ohos_sdk) { deps = base_deps - sources += - [ "${relational_store_native_path}/rdb/mock/src/task_executor.cpp" ] + sources += [ + "${relational_store_native_path}/rdb/mock/src/rdb_radar_reporter.cpp", + "${relational_store_native_path}/rdb/mock/src/task_executor.cpp", + ] deps += [ "${relational_store_innerapi_path}/appdatafwk:relational_common_base", @@ -316,8 +326,10 @@ if (is_ohos && !build_ohos_sdk) { deps = base_deps - sources += - [ "${relational_store_native_path}/rdb/mock/src/task_executor.cpp" ] + sources += [ + "${relational_store_native_path}/rdb/mock/src/rdb_radar_reporter.cpp", + "${relational_store_native_path}/rdb/mock/src/task_executor.cpp", + ] deps += [ "${relational_store_innerapi_path}/appdatafwk:relational_common_base", @@ -344,6 +356,7 @@ if (is_ohos && !build_ohos_sdk) { "include", "//foundation/communication/ipc/interfaces/innerkits/ipc_core/include", "${relational_store_native_path}/rdb/include", + "${relational_store_native_path}/dfx/include", ] cflags = [ "-includemock.h" ] @@ -374,6 +387,8 @@ if (is_ohos && !build_ohos_sdk) { include_dirs = [ "mock/include", "include", + "../cloud_data/include", + "../common_type/include", ] } @@ -390,8 +405,10 @@ if (is_ohos && !build_ohos_sdk) { deps = base_deps - sources += - [ "${relational_store_native_path}/rdb/mock/src/task_executor.cpp" ] + sources += [ + "${relational_store_native_path}/rdb/mock/src/rdb_radar_reporter.cpp", + "${relational_store_native_path}/rdb/mock/src/task_executor.cpp", + ] deps += [ "${relational_store_innerapi_path}/appdatafwk:relational_common_base", "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog_mac", @@ -411,8 +428,10 @@ if (is_ohos && !build_ohos_sdk) { deps = base_deps - sources += - [ "${relational_store_native_path}/rdb/mock/src/task_executor.cpp" ] + sources += [ + "${relational_store_native_path}/rdb/mock/src/rdb_radar_reporter.cpp", + "${relational_store_native_path}/rdb/mock/src/task_executor.cpp", + ] deps += [ "${relational_store_innerapi_path}/appdatafwk:relational_common_base", "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog_mac", @@ -437,6 +456,7 @@ if (is_ohos && !build_ohos_sdk) { "${relational_store_native_path}/rdb/mock/include", "${relational_store_innerapi_path}/rdb/include", "${relational_store_native_path}/rdb/include", + "${relational_store_native_path}/dfx/include", ] cflags = [ "-includemock.h" ] @@ -463,6 +483,10 @@ if (is_ohos && !build_ohos_sdk) { "include", "${relational_store_native_path}/mock/rdb/include", "${relational_store_native_path}/rdb/include", + "${relational_store_native_path}/dfx/include", + "../cloud_data/include", + "../common_type/include", + "//commonlibrary/c_utils/base/include", ] } @@ -480,13 +504,13 @@ if (is_ohos && !build_ohos_sdk) { deps = base_deps sources += [ + "${relational_store_native_path}/rdb/mock/src/rdb_radar_reporter.cpp", "${relational_store_native_path}/rdb/mock/src/task_executor.cpp", "${relational_store_native_path}/rdb/src/security_policy.cpp", ] deps += [ "${relational_store_innerapi_path}/appdatafwk:relational_common_base", "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog_android", - "//commonlibrary/c_utils/base:utils", "//third_party/sqlite:sqlite_static", ] cflags_cc = [ "-std=c++17" ] @@ -506,6 +530,7 @@ if (is_ohos && !build_ohos_sdk) { "${relational_store_native_path}/rdb/mock/include", "${relational_store_innerapi_path}/rdb/include", "${relational_store_native_path}/rdb/include", + "${relational_store_native_path}/dfx/include", ] cflags = [ "-includemock.h" ] @@ -531,6 +556,10 @@ if (is_ohos && !build_ohos_sdk) { "mock/include", "include", "${relational_store_native_path}/rdb/include", + "${relational_store_native_path}/dfx/include", + "../cloud_data/include", + "../common_type/include", + "//commonlibrary/c_utils/base/include", ] } @@ -547,15 +576,18 @@ if (is_ohos && !build_ohos_sdk) { deps = base_deps sources += [ + "${relational_store_native_path}/rdb/mock/src/rdb_radar_reporter.cpp", "${relational_store_native_path}/rdb/mock/src/task_executor.cpp", "${relational_store_native_path}/rdb/src/security_policy.cpp", ] deps += [ "${relational_store_innerapi_path}/appdatafwk:relational_common_base", "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog_ios", - "//commonlibrary/c_utils/base:utilsbase", "//third_party/sqlite:sqlite_static", ] + + external_deps = [ "c_utils:utils" ] + cflags_cc = [ "-std=c++17" ] public_configs = [ ":native_rdb_public_config" ] diff --git a/relational_store/interfaces/inner_api/rdb/include/abs_result_set.h b/relational_store/interfaces/inner_api/rdb/include/abs_result_set.h index 66c9a263..6b24d63a 100644 --- a/relational_store/interfaces/inner_api/rdb/include/abs_result_set.h +++ b/relational_store/interfaces/inner_api/rdb/include/abs_result_set.h @@ -330,9 +330,10 @@ protected: using Mutex = Lock; virtual std::pair> GetColumnNames(); - + std::pair IsEnded(); // The default position of the result set static const int INIT_POS = -1; + static constexpr int NO_COUNT = -1; Mutex globalMtx_; /* @@ -341,6 +342,7 @@ protected: */ int rowPos_ = INIT_POS; bool isClosed_ = false; + int rowCount_ = NO_COUNT; private: int InitColumnNames(); diff --git a/relational_store/interfaces/inner_api/rdb/include/abs_shared_result_set.h b/relational_store/interfaces/inner_api/rdb/include/abs_shared_result_set.h index 40ac2a9e..13064d81 100644 --- a/relational_store/interfaces/inner_api/rdb/include/abs_shared_result_set.h +++ b/relational_store/interfaces/inner_api/rdb/include/abs_shared_result_set.h @@ -142,6 +142,7 @@ protected: static const int INIT_POS = -1; private: int GetCustomerValue(int index, ValueObject &value, AppDataFwk::SharedBlock *block); + int UpdateBlockPos(int position, int rowCnt); static const size_t DEFAULT_BLOCK_SIZE = 2 * 1024 * 1024; friend class ISharedResultSetStub; diff --git a/relational_store/interfaces/inner_api/rdb/include/rdb_common.h b/relational_store/interfaces/inner_api/rdb/include/rdb_common.h index 5ff6909e..3a2a4577 100644 --- a/relational_store/interfaces/inner_api/rdb/include/rdb_common.h +++ b/relational_store/interfaces/inner_api/rdb/include/rdb_common.h @@ -37,6 +37,7 @@ enum class ConflictResolution { enum RebuiltType : uint32_t { NONE, REBUILT, + REPAIRED, }; } // namespace NativeRdb } // namespace OHOS diff --git a/relational_store/interfaces/inner_api/rdb/include/rdb_errno.h b/relational_store/interfaces/inner_api/rdb/include/rdb_errno.h index 5644b1ad..f8c9b786 100644 --- a/relational_store/interfaces/inner_api/rdb/include/rdb_errno.h +++ b/relational_store/interfaces/inner_api/rdb/include/rdb_errno.h @@ -15,10 +15,11 @@ #ifndef NATIVE_RDB_RDB_ERRNO_H #define NATIVE_RDB_RDB_ERRNO_H - +#include namespace OHOS { namespace NativeRdb { +constexpr ErrCode DISTRIBUTEDDATAMGR_RDB_ERR_OFFSET = ErrCodeOffset(SUBSYS_DISTRIBUTEDDATAMNG, 2); /** * @brief The error code in the correct case. */ @@ -27,12 +28,12 @@ constexpr int E_OK = 0; /** * @brief The base code of the exception error code. */ -constexpr int E_BASE = 14800000; +constexpr int E_BASE = DISTRIBUTEDDATAMGR_RDB_ERR_OFFSET; /** * @brief The error when the capability not supported. */ -constexpr int E_NOT_SUPPORTED = 801; +constexpr int E_NOT_SUPPORT = (E_BASE + 801); /** * @brief The error code for common exceptions. @@ -242,7 +243,7 @@ constexpr int E_STORE_SESSION_NO_CURRENT_TRANSACTION = (E_BASE + 40); /** * @brief The error for not supported the current operation. */ -constexpr int E_NOT_SUPPORT = (E_BASE + 41); +constexpr int E_NOT_SUPPORTED = (E_BASE + 41); /** * @brief The error for the current parcel is invalid. @@ -315,7 +316,7 @@ static constexpr int E_ATTACHED_DATABASE_EXIST = (E_BASE + 54); static constexpr int E_SQLITE_ERROR = (E_BASE + 55); /** - * @brief The database disk image is malformed. + * @brief The database disk image is malformed. Used by vector db, too. */ static constexpr int E_SQLITE_CORRUPT = (E_BASE + 56); @@ -388,6 +389,11 @@ static constexpr int E_SQLITE_MISUSE = (E_BASE + 69); * @brief Config changed. */ static constexpr int E_CONFIG_INVALID_CHANGE = (E_BASE + 70); + +/** + * @brief Not get service. + */ +static constexpr int E_SERVICE_NOT_FOUND = (E_BASE + 71); } // namespace NativeRdb } // namespace OHOS diff --git a/relational_store/interfaces/inner_api/rdb/include/rdb_helper.h b/relational_store/interfaces/inner_api/rdb/include/rdb_helper.h index 293e9a38..1061d2ac 100644 --- a/relational_store/interfaces/inner_api/rdb/include/rdb_helper.h +++ b/relational_store/interfaces/inner_api/rdb/include/rdb_helper.h @@ -32,7 +32,8 @@ public: * @brief Obtains an RDB store. * * You can set parameters of the RDB store as required. In general, this method is recommended - * to obtain a rdb store. + * to obtain a rdb store. BundleName is mandatory and must be the same for different RDB stores + * of the same application. * * @param config Indicates the {@link RdbStoreConfig} configuration of the database related to this RDB store. * @param version Indicates the database version for upgrade or downgrade. diff --git a/relational_store/interfaces/inner_api/rdb/include/rdb_store.h b/relational_store/interfaces/inner_api/rdb/include/rdb_store.h index f9fbae5a..ca5e9f27 100644 --- a/relational_store/interfaces/inner_api/rdb/include/rdb_store.h +++ b/relational_store/interfaces/inner_api/rdb/include/rdb_store.h @@ -563,6 +563,11 @@ public: */ virtual int Notify(const std::string &event) = 0; + virtual int32_t GetDbType() const + { + return DB_SQLITE; + } + class ModifyTime { public: ModifyTime() = default; diff --git a/relational_store/interfaces/inner_api/rdb/include/rdb_store_config.h b/relational_store/interfaces/inner_api/rdb/include/rdb_store_config.h index be523473..cc4fc426 100644 --- a/relational_store/interfaces/inner_api/rdb/include/rdb_store_config.h +++ b/relational_store/interfaces/inner_api/rdb/include/rdb_store_config.h @@ -427,6 +427,21 @@ public: */ std::vector GetEncryptKey() const; + /** + * @brief Changes the encrypt key in this {@code StoreConfig} object. + */ + void ChangeEncryptKey() const; + + /** + * @brief Obtains the new encrypt key in this {@code StoreConfig} object. + */ + std::vector GetNewEncryptKey() const; + + /** + * @brief Obtains the encrypted key in this {@code StoreConfig} object. + */ + void Initialize() const; + /** * @brief Sets the scalar function for the object. */ @@ -566,6 +581,8 @@ public: private: void ClearEncryptKey(); + void GenerateEncryptedKey() const; + bool readOnly = false; bool isEncrypt_ = false; bool isCreateNecessary_; @@ -596,9 +613,10 @@ private: std::string encryptAlgo; std::string dataGroupId_; std::string customDir_; - std::vector encryptKey_{}; + mutable std::vector encryptKey_{}; + mutable std::vector newEncryptKey_{}; std::map customScalarFunctions; - + static constexpr int MAX_TIMEOUT = 300; // seconds static constexpr int MIN_TIMEOUT = 1; // seconds bool allowRebuilt_ = false; diff --git a/relational_store/interfaces/inner_api/rdb/include/rdb_types.h b/relational_store/interfaces/inner_api/rdb/include/rdb_types.h index 5736b571..4432c4d2 100644 --- a/relational_store/interfaces/inner_api/rdb/include/rdb_types.h +++ b/relational_store/interfaces/inner_api/rdb/include/rdb_types.h @@ -22,6 +22,7 @@ #include #include #include +#include namespace OHOS::DistributedRdb { enum RdbStatus { @@ -276,5 +277,18 @@ struct RdbChangeProperties { struct RdbChangedData { std::map tableData; }; + +class SqlObserver { +public: + struct SqlExecutionInfo { + std::vector sql_; + int64_t totalTime_; + int64_t waitTime_; + int64_t prepareTime_; + int64_t executeTime_; + }; + virtual ~SqlObserver() = default; + virtual void OnStatistic(const SqlExecutionInfo &info) = 0; +}; } // namespace OHOS::DistributedRdb #endif diff --git a/relational_store/interfaces/inner_api/rdb/mock/include/abs_result_set.h b/relational_store/interfaces/inner_api/rdb/mock/include/abs_result_set.h index e996a8a3..52dfe66b 100644 --- a/relational_store/interfaces/inner_api/rdb/mock/include/abs_result_set.h +++ b/relational_store/interfaces/inner_api/rdb/mock/include/abs_result_set.h @@ -95,9 +95,11 @@ protected: using Mutex = Lock; virtual std::pair> GetColumnNames() = 0; + std::pair IsEnded(); // The default position of the result set static const int INIT_POS = -1; + static constexpr int NO_COUNT = -1; Mutex globalMtx_; /* @@ -106,6 +108,7 @@ protected: */ int rowPos_ = INIT_POS; bool isClosed_ = false; + int rowCount_; private: int InitColumnNames(); diff --git a/relational_store/interfaces/inner_api/rdb/mock/include/rdb_common.h b/relational_store/interfaces/inner_api/rdb/mock/include/rdb_common.h index 9f00faf7..2a564788 100644 --- a/relational_store/interfaces/inner_api/rdb/mock/include/rdb_common.h +++ b/relational_store/interfaces/inner_api/rdb/mock/include/rdb_common.h @@ -30,6 +30,7 @@ enum class ConflictResolution { enum RebuiltType : uint32_t { NONE, REBUILT, + REPAIRED, }; } } diff --git a/relational_store/interfaces/inner_api/rdb/mock/include/rdb_store.h b/relational_store/interfaces/inner_api/rdb/mock/include/rdb_store.h index 71ba9088..e89d3e2c 100644 --- a/relational_store/interfaces/inner_api/rdb/mock/include/rdb_store.h +++ b/relational_store/interfaces/inner_api/rdb/mock/include/rdb_store.h @@ -60,6 +60,8 @@ public: virtual std::shared_ptr QueryByStep(const std::string &sql, const std::vector &sqlArgs) = 0; virtual std::shared_ptr QueryByStep(const std::string &sql, const std::vector &args) = 0; + virtual std::shared_ptr QueryByStep( + const AbsRdbPredicates &predicates, const std::vector &columns) = 0; virtual int ExecuteSql(const std::string &sql, const std::vector &bindArgs = {}) = 0; virtual std::pair Execute(const std::string &sql, const std::vector &bindArgs = {}, int64_t txId = 0) = 0; diff --git a/relational_store/interfaces/inner_api/rdb/mock/include/rdb_store_config.h b/relational_store/interfaces/inner_api/rdb/mock/include/rdb_store_config.h index f32f8f04..6a6b65f4 100644 --- a/relational_store/interfaces/inner_api/rdb/mock/include/rdb_store_config.h +++ b/relational_store/interfaces/inner_api/rdb/mock/include/rdb_store_config.h @@ -97,6 +97,10 @@ public: std::string GetJournalMode() const; std::string GetSyncMode() const; std::vector GetEncryptKey() const; + std::vector GetNewEncryptKey() const; + void Initialize() const; + void ChangeEncryptKey() const; + bool IsReadOnly() const; bool IsMemoryRdb() const; std::string GetDatabaseFileType() const; @@ -198,6 +202,8 @@ public: } private: + void GenerateEncryptedKey() const; + bool readOnly = false; bool isEncrypt_ = false; bool isCreateNecessary_; @@ -227,9 +233,10 @@ private: std::string encryptAlgo; std::string dataGroupId_; std::string customDir_; - std::vector encryptKey_{}; + mutable std::vector encryptKey_{}; + mutable std::vector newEncryptKey_{}; std::map customScalarFunctions; - + static constexpr int MAX_TIMEOUT = 300; // seconds static constexpr int MIN_TIMEOUT = 1; // seconds bool allowRebuilt_ = false; diff --git a/relational_store/interfaces/inner_api/rdb_data_ability_adapter/BUILD.gn b/relational_store/interfaces/inner_api/rdb_data_ability_adapter/BUILD.gn index f08981ee..8fdebcc4 100644 --- a/relational_store/interfaces/inner_api/rdb_data_ability_adapter/BUILD.gn +++ b/relational_store/interfaces/inner_api/rdb_data_ability_adapter/BUILD.gn @@ -35,6 +35,8 @@ config("rdb_data_ability_adapter_public_config") { ohos_shared_library("rdb_data_ability_adapter") { branch_protector_ret = "pac_ret" sanitize = { + boundary_sanitize = true + ubsan = true cfi = true cfi_cross_dso = true debug = false diff --git a/relational_store/interfaces/inner_api/rdb_data_share_adapter/BUILD.gn b/relational_store/interfaces/inner_api/rdb_data_share_adapter/BUILD.gn index 34574878..403da4e0 100644 --- a/relational_store/interfaces/inner_api/rdb_data_share_adapter/BUILD.gn +++ b/relational_store/interfaces/inner_api/rdb_data_share_adapter/BUILD.gn @@ -40,6 +40,8 @@ config("rdb_data_share_adapter_public_config") { ohos_shared_library("rdb_data_share_adapter") { branch_protector_ret = "pac_ret" sanitize = { + boundary_sanitize = true + ubsan = true cfi = true cfi_cross_dso = true debug = false diff --git a/relational_store/interfaces/ndk/include/data_asset.h b/relational_store/interfaces/ndk/include/data_asset.h index 5502df38..6259d3cb 100644 --- a/relational_store/interfaces/ndk/include/data_asset.h +++ b/relational_store/interfaces/ndk/include/data_asset.h @@ -96,6 +96,8 @@ typedef struct Data_Asset Data_Asset; * @param asset Represents a pointer to an {@link Data_Asset} instance. * @param name Indicates the name to set. * @return Returns a specific error code. + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. * @see Data_Asset * @since 11 @@ -108,6 +110,8 @@ int OH_Data_Asset_SetName(Data_Asset *asset, const char *name); * @param asset Represents a pointer to an {@link Data_Asset} instance. * @param uri Indicates the uri to set. * @return Returns a specific error code. + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. * @see Data_Asset * @since 11 @@ -120,6 +124,8 @@ int OH_Data_Asset_SetUri(Data_Asset *asset, const char *uri); * @param asset Represents a pointer to an {@link Data_Asset} instance. * @param path Indicates the path to set. * @return Returns a specific error code. + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. * @see Data_Asset * @since 11 @@ -132,6 +138,8 @@ int OH_Data_Asset_SetPath(Data_Asset *asset, const char *path); * @param asset Represents a pointer to an {@link Data_Asset} instance. * @param createTime Indicates the create time to set. * @return Returns a specific error code. + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. * @see Data_Asset * @since 11 @@ -144,6 +152,8 @@ int OH_Data_Asset_SetCreateTime(Data_Asset *asset, int64_t createTime); * @param asset Represents a pointer to an {@link Data_Asset} instance. * @param modifyTime Indicates the create time to set. * @return Returns a specific error code. + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. * @see Data_Asset * @since 11 @@ -156,6 +166,8 @@ int OH_Data_Asset_SetModifyTime(Data_Asset *asset, int64_t modifyTime); * @param asset Represents a pointer to an {@link Data_Asset} instance. * @param size Indicates the size to set. * @return Returns a specific error code. + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. * @see Data_Asset * @since 11 @@ -168,6 +180,8 @@ int OH_Data_Asset_SetSize(Data_Asset *asset, size_t size); * @param asset Represents a pointer to an {@link Data_Asset} instance. * @param status Indicates the status to set. Specific status can be referenced {@link Data_AssetStatus}. * @return Returns a specific error code. + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. * @see Data_Asset, Data_AssetStatus * @since 11 @@ -182,6 +196,9 @@ int OH_Data_Asset_SetStatus(Data_Asset *asset, Data_AssetStatus status); * and the name of the asset as a char * is written to this variable. * @param length Indicates the length of the name. * @return Returns a specific error code. + * {@link RDB_ERR} - Indicates that the function execution exception. + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. * @see Data_Asset * @since 11 @@ -196,6 +213,9 @@ int OH_Data_Asset_GetName(Data_Asset *asset, char *name, size_t *length); * and the uri of the asset as a char * is written to this variable. * @param length Indicates the length of the uri. * @return Returns a specific error code. + * {@link RDB_ERR} - Indicates that the function execution exception. + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. * @see Data_Asset * @since 11 @@ -210,6 +230,9 @@ int OH_Data_Asset_GetUri(Data_Asset *asset, char *uri, size_t *length); * and the path of the asset as a char * is written to this variable. * @param length Indicates the length of the path. * @return Returns a specific error code. + * {@link RDB_ERR} - Indicates that the function execution exception. + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. * @see Data_Asset * @since 11 @@ -223,6 +246,9 @@ int OH_Data_Asset_GetPath(Data_Asset *asset, char *path, size_t *length); * @param createTime This parameter is the output parameter, * and the create time of the asset as a int64_t is written to this variable. * @return Returns a specific error code. + * {@link RDB_ERR} - Indicates that the function execution exception. + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. * @see Data_Asset * @since 11 @@ -236,6 +262,9 @@ int OH_Data_Asset_GetCreateTime(Data_Asset *asset, int64_t *createTime); * @param modifyTime This parameter is the output parameter, * and the create time of the asset as a int64_t is written to this variable. * @return Returns a specific error code. + * {@link RDB_ERR} - Indicates that the function execution exception. + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. * @see Data_Asset * @since 11 @@ -249,6 +278,9 @@ int OH_Data_Asset_GetModifyTime(Data_Asset *asset, int64_t *modifyTime); * @param size This parameter is the output parameter, * and the size of the asset as a size_t is written to this variable. * @return Returns a specific error code. + * {@link RDB_ERR} - Indicates that the function execution exception. + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. * @see Data_Asset * @since 11 @@ -262,6 +294,8 @@ int OH_Data_Asset_GetSize(Data_Asset *asset, size_t *size); * @param status This parameter is the output parameter, * and the size of the status as a {@link Data_AssetStatus} is written to this variable. * @return Returns a specific error code. + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. * @see Data_Asset Data_AssetStatus. * @since 11 @@ -293,8 +327,8 @@ int OH_Data_Asset_DestroyOne(Data_Asset *asset); * @brief Creates {@link Data_Asset} instances of given number. * * @param count Represents the count of {@link Data_Asset} to create. - * @return If the creation is successful, a pointer to the instance of the @link Data_Asset} structure is returned, - * otherwise NULL is returned. + * @return If the creation is successful, a pointer to the instance of the {@link Data_Asset} structure is returned. + * If the creation is unsuccessful, nullptr is returned. * @see Data_Asset. * @since 11 */ diff --git a/relational_store/interfaces/ndk/include/oh_values_bucket.h b/relational_store/interfaces/ndk/include/oh_values_bucket.h index 66a923e2..dba9feee 100644 --- a/relational_store/interfaces/ndk/include/oh_values_bucket.h +++ b/relational_store/interfaces/ndk/include/oh_values_bucket.h @@ -147,6 +147,8 @@ typedef struct OH_VBucket { * @param field Indicates the name of the column. * @param value Indicates the const {@link Data_Asset} * value. * @return Returns the status code of the execution. + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * @see OH_VBucket. * @since 11 */ @@ -160,6 +162,8 @@ int OH_VBucket_PutAsset(OH_VBucket *bucket, const char *field, Data_Asset *value * @param value Indicates the {@link Data_Asset} value of given count. * @param count Indicates the count of value. * @return Returns the status code of the execution. + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * @see OH_VBucket. * @since 11 */ diff --git a/relational_store/interfaces/ndk/include/relational_store.h b/relational_store/interfaces/ndk/include/relational_store.h index d3e7245a..3dc9be36 100644 --- a/relational_store/interfaces/ndk/include/relational_store.h +++ b/relational_store/interfaces/ndk/include/relational_store.h @@ -174,8 +174,8 @@ OH_VBucket *OH_Rdb_CreateValuesBucket(); * @brief Creates an {@link OH_Predicates} instance. * * @param table Indicates the table name. - * @return If the creation is successful, a pointer to the instance of the @link OH_Predicates} structure is returned, - * otherwise NULL is returned. + * @return If the creation is successful, a pointer to the instance of the @link OH_Predicates} structure is returned. + * If the table name is nullptr, nullptr is returned. * @see OH_Predicates. * @since 10 */ @@ -191,8 +191,9 @@ OH_Predicates *OH_Rdb_CreatePredicates(const char *table); * Indicates the configuration of the database related to this RDB store. * @param errCode This parameter is the output parameter, * and the execution status of a function is written to this variable. - * @return If the creation is successful, a pointer to the instance of the @link OH_Rdb_Store} structure is returned, - * otherwise NULL is returned. + * @return If the creation is successful, a pointer to the instance of the @link OH_Rdb_Store} structure is returned. + * If the Config is empty, config.size does not match, or errCode is empty. + * Get database path failed.Get RDB Store fail. Nullptr is returned. * @see OH_Rdb_Config, OH_Rdb_Store. * @since 10 */ @@ -203,6 +204,8 @@ OH_Rdb_Store *OH_Rdb_GetOrOpen(const OH_Rdb_Config *config, int *errCode); * * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. * @return Returns the status code of the execution. Successful execution returns RDB_OK, + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * while failure returns a specific error code. Specific error codes can be referenced {@link OH_Rdb_ErrCode}. * @see OH_Rdb_Store, OH_Rdb_ErrCode. * @since 10 @@ -215,6 +218,8 @@ int OH_Rdb_CloseStore(OH_Rdb_Store *store); * @param config Represents a pointer to an {@link OH_Rdb_Config} instance. * Indicates the configuration of the database related to this RDB store. * @return Returns the status code of the execution. Successful execution returns RDB_OK, + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * while failure returns a specific error code. Specific error codes can be referenced {@link OH_Rdb_ErrCode}. * @see OH_Rdb_ErrCode. * @since 10 @@ -228,6 +233,8 @@ int OH_Rdb_DeleteStore(const OH_Rdb_Config *config); * @param table Indicates the target table. * @param valuesBucket Indicates the row of data {@link OH_VBucket} to be inserted into the table. * @return Returns the rowId if success, returns a specific error code. + * {@link RDB_ERR} - Indicates that the function execution exception. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. * @see OH_Rdb_Store, OH_VBucket, OH_Rdb_ErrCode. * @since 10 @@ -242,6 +249,8 @@ int OH_Rdb_Insert(OH_Rdb_Store *store, const char *table, OH_VBucket *valuesBuck * @param predicates Represents a pointer to an {@link OH_Predicates} instance. * Indicates the specified update condition. * @return Returns the number of rows changed if success, otherwise, returns a specific error code. + * {@link RDB_ERR} - Indicates that the function execution exception. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. * @see OH_Rdb_Store, OH_Bucket, OH_Predicates, OH_Rdb_ErrCode. * @since 10 @@ -255,6 +264,8 @@ int OH_Rdb_Update(OH_Rdb_Store *store, OH_VBucket *valuesBucket, OH_Predicates * * @param predicates Represents a pointer to an {@link OH_Predicates} instance. * Indicates the specified delete condition. * @return Returns the number of rows changed if success, otherwise, returns a specific error code. + * {@link RDB_ERR} - Indicates that the function execution exception. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. * @see OH_Rdb_Store, OH_Predicates, OH_Rdb_ErrCode. * @since 10 @@ -269,8 +280,8 @@ int OH_Rdb_Delete(OH_Rdb_Store *store, OH_Predicates *predicates); * Indicates the specified query condition. * @param columnNames Indicates the columns to query. If the value is empty array, the query applies to all columns. * @param length Indicates the length of columnNames. - * @return If the query is successful, a pointer to the instance of the @link OH_Cursor} structure is returned, - * otherwise NULL is returned. + * @return If the query is successful, a pointer to the instance of the @link OH_Cursor} structure is returned. + * If Get store failed or resultSet is nullptr, nullptr is returned. * @see OH_Rdb_Store, OH_Predicates, OH_Cursor. * @since 10 */ @@ -282,6 +293,8 @@ OH_Cursor *OH_Rdb_Query(OH_Rdb_Store *store, OH_Predicates *predicates, const ch * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. * @param sql Indicates the SQL statement to execute. * @return Returns the status code of the execution. + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * @see OH_Rdb_Store. * @since 10 */ @@ -292,8 +305,8 @@ int OH_Rdb_Execute(OH_Rdb_Store *store, const char *sql); * * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. * @param sql Indicates the SQL statement to execute. - * @return If the query is successful, a pointer to the instance of the @link OH_Cursor} structure is returned, - * otherwise NULL is returned. + * @return If the query is successful, a pointer to the instance of the @link OH_Cursor} structure is returned. + * If Get store failed,sql is nullptr or resultSet is nullptr, nullptr is returned. * @see OH_Rdb_Store. * @since 10 */ @@ -304,6 +317,8 @@ OH_Cursor *OH_Rdb_ExecuteQuery(OH_Rdb_Store *store, const char *sql); * * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. * @return Returns the status code of the execution. + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * @see OH_Rdb_Store. * @since 10 */ @@ -314,6 +329,8 @@ int OH_Rdb_BeginTransaction(OH_Rdb_Store *store); * * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. * @return Returns the status code of the execution. + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * @see OH_Rdb_Store. * @since 10 */ @@ -324,6 +341,8 @@ int OH_Rdb_RollBack(OH_Rdb_Store *store); * * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. * @return Returns the status code of the execution. + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * @see OH_Rdb_Store. * @since 10 */ @@ -335,6 +354,8 @@ int OH_Rdb_Commit(OH_Rdb_Store *store); * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. * @param databasePath Indicates the database file path. * @return Returns the status code of the execution. + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * @see OH_Rdb_Store. * @since 10 */ @@ -346,6 +367,8 @@ int OH_Rdb_Backup(OH_Rdb_Store *store, const char *databasePath); * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. * @param databasePath Indicates the database file path. * @return Returns the status code of the execution. + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * @see OH_Rdb_Store. * @since 10 */ @@ -357,6 +380,8 @@ int OH_Rdb_Restore(OH_Rdb_Store *store, const char *databasePath); * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. * @param version Indicates the version number. * @return Returns the status code of the execution. + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * @see OH_Rdb_Store. * @since 10 */ @@ -368,6 +393,8 @@ int OH_Rdb_GetVersion(OH_Rdb_Store *store, int *version); * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. * @param version Indicates the version number. * @return Returns the status code of the execution. + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * @see OH_Rdb_Store. * @since 10 */ @@ -416,6 +443,8 @@ typedef struct Rdb_DistributedConfig { * @param type Indicates the distributed type {@link Rdb_DistributedType}. * @param config Indicates the distributed config of the tables. For details, see {@link Rdb_DistributedConfig}. * @return Returns the status code of the execution. See {@link OH_Rdb_ErrCode}. + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * @see OH_Rdb_Store. * @see Rdb_DistributedConfig. * @since 11 @@ -433,6 +462,7 @@ int OH_Rdb_SetDistributedTables(OH_Rdb_Store *store, const char *tables[], uint3 * @param values Indicates the primary keys of the rows to check. * If the table has no primary key , please pass in the row-ids of the rows to check. * @return If the operation is successful, a pointer to the instance of the @link OH_Cursor} structure is returned. + * If Get store failed, nullptr is returned. * There are two columns, "data_key" and "timestamp". Otherwise NULL is returned. * @see OH_Rdb_Store. * @see OH_VObject. @@ -554,6 +584,12 @@ typedef enum Rdb_SubscribeType { * @brief Subscription to cloud data change details. */ RDB_SUBSCRIBE_TYPE_CLOUD_DETAILS, + + /** + * @brief Subscription to local data change details. + * @since 12 + */ + RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS, } Rdb_SubscribeType; /** @@ -620,6 +656,8 @@ typedef struct Rdb_DataObserver { * @param type Indicates the subscription type, which is defined in {@link Rdb_SubscribeType}. * @param observer The {@link Rdb_DataObserver} of change events in the database. * @return Returns the status code of the execution. See {@link OH_Rdb_ErrCode}. + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * @see OH_Rdb_Store. * @see Rdb_DataObserver. * @since 11 @@ -634,6 +672,8 @@ int OH_Rdb_Subscribe(OH_Rdb_Store *store, Rdb_SubscribeType type, const Rdb_Data * @param observer The {@link Rdb_DataObserver} of change events in the database. * If this is nullptr, remove all observers of the type. * @return Returns the status code of the execution. See {@link OH_Rdb_ErrCode}. + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * @see OH_Rdb_Store. * @see Rdb_DataObserver. * @since 11 @@ -814,7 +854,7 @@ typedef struct Rdb_ProgressDetails { * @param progress Represents a pointer to an {@link Rdb_ProgressDetails} instance. * @param version Indicates the version of current {@link Rdb_ProgressDetails}. * @return If the operation is successful, a pointer to the instance of the {@link Rdb_TableDetails} - * structure is returned. Otherwise NULL is returned. + * structure is returned.If get details is failed, nullptr is returned. * @see Rdb_ProgressDetails * @see Rdb_TableDetails * @since 11 @@ -865,6 +905,8 @@ typedef struct Rdb_ProgressObserver { * @param count The count of tables to sync. If value equals 0, sync all tables of the store. * @param observer The {@link Rdb_ProgressObserver} of cloud sync progress. * @return Returns the status code of the execution. See {@link OH_Rdb_ErrCode}. + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * @see OH_Rdb_Store. * @see Rdb_ProgressObserver. * @since 11 @@ -880,6 +922,8 @@ int OH_Rdb_CloudSync(OH_Rdb_Store *store, Rdb_SyncMode mode, const char *tables[ * @param observer The {@link Rdb_SyncObserver} for the automatic synchornizaiton progress * Indicates the callback invoked to return the automatic synchronization progress. * @return Returns the status code of the execution. See {@link OH_Rdb_ErrCode}. +* {@link RDB_OK} - success. +* {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * @see OH_Rdb_Store. * @see Rdb_ProgressObserver. * @since 11 @@ -893,6 +937,8 @@ int OH_Rdb_SubscribeAutoSyncProgress(OH_Rdb_Store *store, const Rdb_ProgressObse * @param observer Indicates the {@link Rdb_SyncObserver} callback for the automatic synchronization progress. * If it is a null pointer, all callbacks for the automatic synchronization progress will be unregistered. * @return Returns the status code of the execution. See {@link OH_Rdb_ErrCode}. +* {@link RDB_OK} - success. +* {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * @see OH_Rdb_Store. * @see Rdb_ProgressObserver. * @since 11 @@ -906,6 +952,8 @@ int OH_Rdb_UnsubscribeAutoSyncProgress(OH_Rdb_Store *store, const Rdb_ProgressOb * @param predicates Represents a pointer to an {@link OH_Predicates} instance. * Indicates the specified lock condition. * @return Returns the status code of the execution. See {@link OH_Rdb_ErrCode}. + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * @see OH_Rdb_Store, OH_Predicates, OH_Rdb_ErrCode. * @since 12 */ @@ -918,6 +966,8 @@ int OH_Rdb_LockRow(OH_Rdb_Store *store, OH_Predicates *predicates); * @param predicates Represents a pointer to an {@link OH_Predicates} instance. * Indicates the specified unlock condition. * @return Returns the status code of the execution. See {@link OH_Rdb_ErrCode}. + * {@link RDB_OK} - success. + * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * @see OH_Rdb_Store, OH_Predicates, OH_Rdb_ErrCode. * @since 12 */ @@ -931,8 +981,8 @@ int OH_Rdb_UnlockRow(OH_Rdb_Store *store, OH_Predicates *predicates); * Indicates the specified query condition. * @param columnNames Indicates the columns to query. If the value is empty array, the query applies to all columns. * @param length Indicates the length of columnNames. - * @return If the query is successful, a pointer to the instance of the @link OH_Cursor} structure is returned, - * otherwise NULL is returned. + * @return If the query is successful, a pointer to the instance of the @link OH_Cursor} structure is returned. + * If Get store failed or resultSet is nullptr, nullptr is returned. * @see OH_Rdb_Store, OH_Predicates, OH_Cursor. * @since 12 */ diff --git a/relational_store/interfaces/ndk/src/BUILD.gn b/relational_store/interfaces/ndk/src/BUILD.gn index 332a7ae9..cd526623 100644 --- a/relational_store/interfaces/ndk/src/BUILD.gn +++ b/relational_store/interfaces/ndk/src/BUILD.gn @@ -17,6 +17,8 @@ import("//foundation/distributeddatamgr/relational_store/relational_store.gni") ohos_shared_library("native_rdb_ndk") { branch_protector_ret = "pac_ret" sanitize = { + boundary_sanitize = true + ubsan = true cfi = true cfi_cross_dso = true debug = false @@ -29,6 +31,7 @@ ohos_shared_library("native_rdb_ndk") { "${relational_store_native_path}/rdb/include", ] sources = [ + "convertor_error_code.cpp", "modify_time_cursor.cpp", "relational_asset.cpp", "relational_cursor.cpp", diff --git a/relational_store/interfaces/ndk/src/convertor_error_code.cpp b/relational_store/interfaces/ndk/src/convertor_error_code.cpp new file mode 100644 index 00000000..ba45201c --- /dev/null +++ b/relational_store/interfaces/ndk/src/convertor_error_code.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "convertor_error_code.h" +#include +#include "relational_store_error_code.h" +#include "rdb_errno.h" + +namespace OHOS::RdbNdk { + +struct NdkErrorCode { + int nativeCode; + int ndkCode; +}; + +static constexpr NdkErrorCode ERROR_CODE_MAP[] = { + { OHOS::NativeRdb::E_OK, RDB_OK }, + { OHOS::NativeRdb::E_ERROR, RDB_E_ERROR }, + { OHOS::NativeRdb::E_INVALID_ARGS, RDB_E_INVALID_ARGS }, + { OHOS::NativeRdb::E_CANNOT_UPDATE_READONLY, RDB_E_CANNOT_UPDATE_READONLY }, + { OHOS::NativeRdb::E_REMOVE_FILE, RDB_E_REMOVE_FILE }, + { OHOS::NativeRdb::E_EMPTY_TABLE_NAME, RDB_E_EMPTY_TABLE_NAME }, + { OHOS::NativeRdb::E_EMPTY_VALUES_BUCKET, RDB_E_EMPTY_VALUES_BUCKET }, + { OHOS::NativeRdb::E_NOT_SELECT, RDB_E_EXECUTE_IN_STEP_QUERY }, + { OHOS::NativeRdb::E_COLUMN_OUT_RANGE, RDB_E_INVALID_COLUMN_INDEX }, + { OHOS::NativeRdb::E_INVALID_COLUMN_TYPE, RDB_E_INVALID_COLUMN_TYPE }, + { OHOS::NativeRdb::E_EMPTY_FILE_NAME, RDB_E_EMPTY_FILE_NAME }, + { OHOS::NativeRdb::E_INVALID_FILE_PATH, RDB_E_INVALID_FILE_PATH }, + { OHOS::NativeRdb::E_TRANSACTION_IN_EXECUTE, RDB_E_TRANSACTION_IN_EXECUTE }, + { OHOS::NativeRdb::E_ROW_OUT_RANGE, RDB_E_STEP_RESULT_IS_AFTER_LAST }, + { OHOS::NativeRdb::E_EXECUTE_WRITE_IN_READ_CONNECTION, RDB_E_EXECUTE_WRITE_IN_READ_CONNECTION }, + { OHOS::NativeRdb::E_BEGIN_TRANSACTION_IN_READ_CONNECTION, RDB_E_BEGIN_TRANSACTION_IN_READ_CONNECTION }, + { OHOS::NativeRdb::E_NO_TRANSACTION_IN_SESSION, RDB_E_NO_TRANSACTION_IN_SESSION }, + { OHOS::NativeRdb::E_MORE_STEP_QUERY_IN_ONE_SESSION, RDB_E_MORE_STEP_QUERY_IN_ONE_SESSION }, + { OHOS::NativeRdb::E_NO_ROW_IN_QUERY, RDB_E_NO_ROW_IN_QUERY }, + { OHOS::NativeRdb::E_INVALID_BIND_ARGS_COUNT, RDB_E_INVALID_BIND_ARGS_COUNT }, + { OHOS::NativeRdb::E_INVALID_OBJECT_TYPE, RDB_E_INVALID_OBJECT_TYPE }, + { OHOS::NativeRdb::E_INVALID_CONFLICT_FLAG, RDB_E_INVALID_CONFLICT_FLAG }, + { OHOS::NativeRdb::E_HAVING_CLAUSE_NOT_IN_GROUP_BY, RDB_E_HAVING_CLAUSE_NOT_IN_GROUP_BY }, + { OHOS::NativeRdb::E_NOT_SUPPORTED_BY_STEP_RESULT_SET, RDB_E_NOT_SUPPORTED }, + { OHOS::NativeRdb::E_STEP_RESULT_SET_CROSS_THREADS, RDB_E_STEP_RESULT_SET_CROSS_THREADS }, + { OHOS::NativeRdb::E_NO_MORE_ROWS, RDB_E_STEP_RESULT_IS_AFTER_LAST }, + { OHOS::NativeRdb::E_STEP_RESULT_QUERY_EXCEEDED, RDB_E_STEP_RESULT_QUERY_EXCEEDED }, + { OHOS::NativeRdb::E_STATEMENT_NOT_PREPARED, RDB_E_STATEMENT_NOT_PREPARED }, + { OHOS::NativeRdb::E_EXECUTE_RESULT_INCORRECT, RDB_E_EXECUTE_RESULT_INCORRECT }, + { OHOS::NativeRdb::E_ALREADY_CLOSED, RDB_E_STEP_RESULT_CLOSED }, + { OHOS::NativeRdb::E_RELATIVE_PATH, RDB_E_RELATIVE_PATH }, + { OHOS::NativeRdb::E_EMPTY_NEW_ENCRYPT_KEY, RDB_E_EMPTY_NEW_ENCRYPT_KEY }, + { OHOS::NativeRdb::E_CHANGE_UNENCRYPTED_TO_ENCRYPTED, RDB_E_CHANGE_UNENCRYPTED_TO_ENCRYPTED }, + { OHOS::NativeRdb::E_DATABASE_BUSY, RDB_E_CON_OVER_LIMIT }, + { OHOS::NativeRdb::E_STORE_CLOSED, RDB_E_STEP_RESULT_CLOSED }, + { OHOS::NativeRdb::E_NOT_SUPPORTED_ATTACH_IN_WAL_MODE, RDB_E_NOT_SUPPORTED_ATTACH_IN_WAL_MODE }, + { OHOS::NativeRdb::E_CREATE_FOLDER_FAIL, RDB_E_CREATE_FOLDER_FAIL }, + { OHOS::NativeRdb::E_SQLITE_SQL_BUILDER_NORMALIZE_FAIL, RDB_E_SQLITE_SQL_BUILDER_NORMALIZE_FAIL }, + { OHOS::NativeRdb::E_STORE_SESSION_NOT_GIVE_CONNECTION_TEMPORARILY, + RDB_E_STORE_SESSION_NOT_GIVE_CONNECTION_TEMPORARILY }, + { OHOS::NativeRdb::E_STORE_SESSION_NO_CURRENT_TRANSACTION, RDB_E_STORE_SESSION_NO_CURRENT_TRANSACTION }, + { OHOS::NativeRdb::E_NOT_SUPPORT, RDB_E_NOT_SUPPORTED }, + { OHOS::NativeRdb::E_INVALID_PARCEL, RDB_E_INVALID_PARCEL }, + { OHOS::NativeRdb::E_QUERY_IN_EXECUTE, RDB_E_QUERY_IN_EXECUTE }, + { OHOS::NativeRdb::E_SET_PERSIST_WAL, RDB_E_SET_PERSIST_WAL }, + { OHOS::NativeRdb::E_DB_NOT_EXIST, RDB_E_DB_NOT_EXIST }, + { OHOS::NativeRdb::E_ARGS_READ_CON_OVERLOAD, RDB_E_ARGS_READ_CON_OVERLOAD }, + { OHOS::NativeRdb::E_WAL_SIZE_OVER_LIMIT, RDB_E_WAL_SIZE_OVER_LIMIT }, + { OHOS::NativeRdb::E_CON_OVER_LIMIT, RDB_E_CON_OVER_LIMIT }, + { OHOS::NativeRdb::E_NOT_SUPPORT, RDB_E_NOT_SUPPORTED }, +}; + +int ConvertorErrorCode::NativeToNdk(int nativeErrCode) +{ + auto errorCode = NdkErrorCode{ nativeErrCode, -1 }; + auto iter = std::lower_bound(ERROR_CODE_MAP, + ERROR_CODE_MAP + sizeof(ERROR_CODE_MAP) / sizeof(ERROR_CODE_MAP[0]), + errorCode, [](const NdkErrorCode &errorCode1, const NdkErrorCode &errorCode2) { + return errorCode1.nativeCode < errorCode2.nativeCode; + }); + if (iter < ERROR_CODE_MAP + sizeof(ERROR_CODE_MAP) / sizeof(ERROR_CODE_MAP[0]) && + iter->nativeCode == nativeErrCode) { + return iter->ndkCode; + } + return RDB_E_ERROR; +} +} \ No newline at end of file diff --git a/relational_store/interfaces/ndk/src/convertor_error_code.h b/relational_store/interfaces/ndk/src/convertor_error_code.h new file mode 100644 index 00000000..a8c992a7 --- /dev/null +++ b/relational_store/interfaces/ndk/src/convertor_error_code.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef CONVERATOR_ERROR_CODE_H +#define CONVERATOR_ERROR_CODE_H +namespace OHOS::RdbNdk { +class ConvertorErrorCode final { +private: + ConvertorErrorCode() = default; + ~ConvertorErrorCode() = default; + +public: + static int NativeToNdk(int nativeErrCode); +}; +} // namespace OHOS::RdbNdk +#endif // CONVERATOR_ERROR_CODE_H \ No newline at end of file diff --git a/relational_store/interfaces/ndk/src/relational_cursor.cpp b/relational_store/interfaces/ndk/src/relational_cursor.cpp index 8fe42a9e..b0e6baff 100644 --- a/relational_store/interfaces/ndk/src/relational_cursor.cpp +++ b/relational_store/interfaces/ndk/src/relational_cursor.cpp @@ -23,6 +23,7 @@ #include "relational_asset.h" #include "relational_store_error_code.h" #include "securec.h" +#include "convertor_error_code.h" namespace OHOS { namespace RdbNdk { @@ -213,7 +214,7 @@ int RelationalCursor::GetColumnCount(int *count) if (count == nullptr || resultSet_ == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - return resultSet_->GetColumnCount(*count); + return ConvertorErrorCode::NativeToNdk(resultSet_->GetColumnCount(*count)); } int RelationalCursor::GetColumnType(int32_t columnIndex, OH_ColumnType *columnType) @@ -224,7 +225,7 @@ int RelationalCursor::GetColumnType(int32_t columnIndex, OH_ColumnType *columnTy NativeRdb::ColumnType type; int result = resultSet_->GetColumnType(columnIndex, type); *columnType = static_cast(static_cast(type)); - return result; + return ConvertorErrorCode::NativeToNdk(result); } int RelationalCursor::GetColumnIndex(const char *name, int *columnIndex) @@ -232,7 +233,7 @@ int RelationalCursor::GetColumnIndex(const char *name, int *columnIndex) if (name == nullptr || columnIndex == nullptr || resultSet_ == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - return resultSet_->GetColumnIndex(name, *columnIndex); + return ConvertorErrorCode::NativeToNdk(resultSet_->GetColumnIndex(name, *columnIndex)); } int RelationalCursor::GetColumnName(int32_t columnIndex, char *name, int length) @@ -243,7 +244,7 @@ int RelationalCursor::GetColumnName(int32_t columnIndex, char *name, int length) std::string str; int errCode = resultSet_->GetColumnName(columnIndex, str); if (errCode != NativeRdb::E_OK) { - return errCode; + return ConvertorErrorCode::NativeToNdk(errCode); } errno_t result = strcpy_s(name, length, str.c_str()); if (result != EOK) { @@ -258,7 +259,7 @@ int RelationalCursor::GetRowCount(int *count) if (count == nullptr || resultSet_ == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - return resultSet_->GetRowCount(*count); + return ConvertorErrorCode::NativeToNdk(resultSet_->GetRowCount(*count)); } int RelationalCursor::GoToNextRow() @@ -266,7 +267,7 @@ int RelationalCursor::GoToNextRow() if (resultSet_ == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - return resultSet_->GoToNextRow(); + return ConvertorErrorCode::NativeToNdk(resultSet_->GoToNextRow()); } int RelationalCursor::GetSize(int32_t columnIndex, size_t *size) @@ -274,7 +275,7 @@ int RelationalCursor::GetSize(int32_t columnIndex, size_t *size) if (size == nullptr || resultSet_ == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - return resultSet_->GetSize(columnIndex, *size); + return ConvertorErrorCode::NativeToNdk(resultSet_->GetSize(columnIndex, *size)); } int RelationalCursor::GetText(int32_t columnIndex, char *value, int length) @@ -285,7 +286,7 @@ int RelationalCursor::GetText(int32_t columnIndex, char *value, int length) std::string str; int errCode = resultSet_->GetString(columnIndex, str); if (errCode != NativeRdb::E_OK) { - return errCode; + return ConvertorErrorCode::NativeToNdk(errCode); } errno_t result = strcpy_s(value, length, str.c_str()); if (result != EOK) { @@ -300,7 +301,7 @@ int RelationalCursor::GetInt64(int32_t columnIndex, int64_t *value) if (value == nullptr || resultSet_ == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - return resultSet_->GetLong(columnIndex, *value); + return ConvertorErrorCode::NativeToNdk(resultSet_->GetLong(columnIndex, *value)); } int RelationalCursor::GetReal(int32_t columnIndex, double *value) @@ -308,7 +309,7 @@ int RelationalCursor::GetReal(int32_t columnIndex, double *value) if (value == nullptr || resultSet_ == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - return resultSet_->GetDouble(columnIndex, *value); + return ConvertorErrorCode::NativeToNdk(resultSet_->GetDouble(columnIndex, *value)); } int RelationalCursor::GetBlob(int32_t columnIndex, unsigned char *value, int length) @@ -319,7 +320,7 @@ int RelationalCursor::GetBlob(int32_t columnIndex, unsigned char *value, int len std::vector vec; int errCode = resultSet_->GetBlob(columnIndex, vec); if (errCode != NativeRdb::E_OK) { - return errCode; + return ConvertorErrorCode::NativeToNdk(errCode); } errno_t result = memcpy_s(value, length, vec.data(), vec.size()); if (result != EOK) { @@ -337,11 +338,11 @@ int RelationalCursor::GetAsset(int32_t columnIndex, Data_Asset *value) NativeRdb::AssetValue asset; auto errCode = resultSet_->GetAsset(columnIndex, asset); if (errCode != NativeRdb::E_OK) { - return errCode; + return ConvertorErrorCode::NativeToNdk(errCode); } value->cid = DATA_ASSET_V0; value->asset_ = asset; - return errCode; + return ConvertorErrorCode::NativeToNdk(errCode); } int RelationalCursor::GetAssets(int32_t columnIndex, Data_Asset **value, uint32_t *length) @@ -353,7 +354,7 @@ int RelationalCursor::GetAssets(int32_t columnIndex, Data_Asset **value, uint32_ std::vector assets; auto errCode = resultSet_->GetAssets(columnIndex, assets); if (errCode != NativeRdb::E_OK) { - return errCode; + return ConvertorErrorCode::NativeToNdk(errCode); } uint32_t inputLength = *length; *length = assets.size(); @@ -370,7 +371,7 @@ int RelationalCursor::GetAssets(int32_t columnIndex, Data_Asset **value, uint32_ value[i]->cid = DATA_ASSET_V0; value[i]->asset_ = assets[i]; } - return errCode; + return ConvertorErrorCode::NativeToNdk(errCode); } int RelationalCursor::IsNull(int32_t columnIndex, bool *isNull) @@ -378,7 +379,7 @@ int RelationalCursor::IsNull(int32_t columnIndex, bool *isNull) if (isNull == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - return resultSet_->IsColumnNull(columnIndex, *isNull); + return ConvertorErrorCode::NativeToNdk(resultSet_->IsColumnNull(columnIndex, *isNull)); } int RelationalCursor::Destroy() @@ -386,7 +387,7 @@ int RelationalCursor::Destroy() if (resultSet_ == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - return resultSet_->Close(); + return ConvertorErrorCode::NativeToNdk(resultSet_->Close()); } int RelationalCursor::GetAssetsCount(int32_t columnIndex, uint32_t *count) @@ -397,7 +398,7 @@ int RelationalCursor::GetAssetsCount(int32_t columnIndex, uint32_t *count) std::vector assets; auto errCode = resultSet_->GetAssets(columnIndex, assets); if (errCode != NativeRdb::E_OK) { - return errCode; + return ConvertorErrorCode::NativeToNdk(errCode); } *count = assets.size(); return OH_Rdb_ErrCode::RDB_OK; diff --git a/relational_store/interfaces/ndk/src/relational_store.cpp b/relational_store/interfaces/ndk/src/relational_store.cpp index e2fafaf7..ed1e7d94 100644 --- a/relational_store/interfaces/ndk/src/relational_store.cpp +++ b/relational_store/interfaces/ndk/src/relational_store.cpp @@ -31,6 +31,7 @@ #include "relational_values_bucket.h" #include "securec.h" #include "sqlite_global_config.h" +#include "convertor_error_code.h" using namespace OHOS::RdbNdk; using namespace OHOS::DistributedRdb; @@ -74,10 +75,10 @@ int RelationalStore::SubscribeAutoSyncProgress(const Rdb_ProgressObserver *callb int errCode = store_->RegisterAutoSyncCallback(obs); if (errCode == NativeRdb::E_OK) { LOG_ERROR("subscribe failed"); - return errCode; + return ConvertorErrorCode::NativeToNdk(errCode); } callbacks_.push_back(std::move(obs)); - return NativeRdb::E_OK; + return OH_Rdb_ErrCode::RDB_OK; } int RelationalStore::UnsubscribeAutoSyncProgress(const Rdb_ProgressObserver *callback) @@ -92,12 +93,12 @@ int RelationalStore::UnsubscribeAutoSyncProgress(const Rdb_ProgressObserver *cal int errCode = store_->UnregisterAutoSyncCallback(*it); if (errCode != NativeRdb::E_OK) { LOG_ERROR("unsubscribe failed"); - return errCode; + return ConvertorErrorCode::NativeToNdk(errCode); } it = callbacks_.erase(it); LOG_DEBUG("progress unsubscribe success"); } - return NativeRdb::E_OK; + return OH_Rdb_ErrCode::RDB_OK; } RelationalStore::~RelationalStore() @@ -131,6 +132,8 @@ OHOS::DistributedRdb::SubscribeMode NDKUtils::GetSubscribeType(Rdb_SubscribeType return SubscribeMode::CLOUD; case Rdb_SubscribeType::RDB_SUBSCRIBE_TYPE_CLOUD_DETAILS: return SubscribeMode::CLOUD_DETAIL; + case Rdb_SubscribeType::RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS: + return SubscribeMode::LOCAL_DETAIL; default: return SubscribeMode::SUBSCRIBE_MODE_MAX; } @@ -144,12 +147,12 @@ public: int MainOpenCallback::OnCreate(OHOS::NativeRdb::RdbStore &rdbStore) { - return OHOS::NativeRdb::E_OK; + return OH_Rdb_ErrCode::RDB_OK; } int MainOpenCallback::OnUpgrade(OHOS::NativeRdb::RdbStore &rdbStore, int oldVersion, int newVersion) { - return OHOS::NativeRdb::E_OK; + return OH_Rdb_ErrCode::RDB_OK; } RelationalStore *GetRelationalStore(OH_Rdb_Store *store) @@ -173,6 +176,7 @@ OH_Rdb_Store *OH_Rdb_GetOrOpen(const OH_Rdb_Config *config, int *errCode) std::string realPath = OHOS::NativeRdb::RdbSqlUtils::GetDefaultDatabasePath(config->dataBaseDir, config->storeName, *errCode); if (*errCode != 0) { + *errCode = ConvertorErrorCode::NativeToNdk(*errCode); LOG_ERROR("Get database path failed, ret %{public}d ", *errCode); return nullptr; } @@ -190,6 +194,7 @@ OH_Rdb_Store *OH_Rdb_GetOrOpen(const OH_Rdb_Config *config, int *errCode) MainOpenCallback callback; std::shared_ptr store = OHOS::NativeRdb::RdbHelper::GetRdbStore(rdbStoreConfig, -1, callback, *errCode); + *errCode = ConvertorErrorCode::NativeToNdk(*errCode); if (store == nullptr) { LOG_ERROR("Get RDB Store fail %{public}s", realPath.c_str()); return nullptr; @@ -217,9 +222,9 @@ int OH_Rdb_DeleteStore(const OH_Rdb_Config *config) std::string realPath = OHOS::NativeRdb::RdbSqlUtils::GetDefaultDatabasePath(config->dataBaseDir, config->storeName, errCode); if (errCode != OHOS::NativeRdb::E_OK) { - return errCode; + return ConvertorErrorCode::NativeToNdk(errCode); } - return OHOS::NativeRdb::RdbHelper::DeleteRdbStore(realPath); + return ConvertorErrorCode::NativeToNdk(OHOS::NativeRdb::RdbHelper::DeleteRdbStore(realPath)); } int OH_Rdb_Insert(OH_Rdb_Store *store, const char *table, OH_VBucket *valuesBucket) @@ -302,7 +307,8 @@ int OH_Rdb_Execute(OH_Rdb_Store *store, const char *sql) if (rdbStore == nullptr || sql == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - return rdbStore->GetStore()->ExecuteSql(sql, std::vector{}); + return ConvertorErrorCode::NativeToNdk( + rdbStore->GetStore()->ExecuteSql(sql, std::vector{})); } int OH_Rdb_BeginTransaction(OH_Rdb_Store *store) @@ -311,7 +317,7 @@ int OH_Rdb_BeginTransaction(OH_Rdb_Store *store) if (rdbStore == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - return rdbStore->GetStore()->BeginTransaction(); + return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->BeginTransaction()); } int OH_Rdb_RollBack(OH_Rdb_Store *store) @@ -320,7 +326,7 @@ int OH_Rdb_RollBack(OH_Rdb_Store *store) if (rdbStore == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - return rdbStore->GetStore()->RollBack(); + return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->RollBack()); } int OH_Rdb_Commit(OH_Rdb_Store *store) @@ -329,7 +335,7 @@ int OH_Rdb_Commit(OH_Rdb_Store *store) if (rdbStore == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - return rdbStore->GetStore()->Commit(); + return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->Commit()); } int OH_Rdb_Backup(OH_Rdb_Store *store, const char *databasePath) @@ -338,7 +344,7 @@ int OH_Rdb_Backup(OH_Rdb_Store *store, const char *databasePath) if (rdbStore == nullptr || databasePath == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - return rdbStore->GetStore()->Backup(databasePath); + return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->Backup(databasePath)); } int OH_Rdb_Restore(OH_Rdb_Store *store, const char *databasePath) @@ -347,7 +353,7 @@ int OH_Rdb_Restore(OH_Rdb_Store *store, const char *databasePath) if (rdbStore == nullptr || databasePath == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - return rdbStore->GetStore()->Restore(databasePath); + return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->Restore(databasePath)); } int OH_Rdb_GetVersion(OH_Rdb_Store *store, int *version) @@ -356,7 +362,7 @@ int OH_Rdb_GetVersion(OH_Rdb_Store *store, int *version) if (rdbStore == nullptr || version == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - return rdbStore->GetStore()->GetVersion(*version); + return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->GetVersion(*version)); } int OH_Rdb_SetVersion(OH_Rdb_Store *store, int version) @@ -365,7 +371,7 @@ int OH_Rdb_SetVersion(OH_Rdb_Store *store, int version) if (rdbStore == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - return rdbStore->GetStore()->SetVersion(version); + return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->SetVersion(version)); } static std::pair Convert(const Rdb_DistributedConfig *config) @@ -406,8 +412,8 @@ int OH_Rdb_SetDistributedTables(OH_Rdb_Store *store, const char *tables[], uint3 } tableNames.emplace_back(tables[i]); } - return rdbStore->GetStore()->SetDistributedTables(tableNames, DistributedTableType::DISTRIBUTED_CLOUD, - { cfg.isAutoSync }); + return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->SetDistributedTables(tableNames, + DistributedTableType::DISTRIBUTED_CLOUD, { cfg.isAutoSync })); } OH_Cursor *OH_Rdb_FindModifyTime(OH_Rdb_Store *store, const char *tableName, const char *columnName, OH_VObject *values) @@ -435,7 +441,7 @@ int OH_Rdb_Subscribe(OH_Rdb_Store *store, Rdb_SubscribeType type, const Rdb_Data if (rdbStore == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - return (OH_Rdb_ErrCode)rdbStore->DoSubScribe(type, observer); + return rdbStore->DoSubScribe(type, observer); } int OH_Rdb_Unsubscribe(OH_Rdb_Store *store, Rdb_SubscribeType type, const Rdb_DataObserver *observer) @@ -444,15 +450,17 @@ int OH_Rdb_Unsubscribe(OH_Rdb_Store *store, Rdb_SubscribeType type, const Rdb_Da if (rdbStore == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - return (OH_Rdb_ErrCode)rdbStore->DoUnsubScribe(type, observer); + return rdbStore->DoUnsubScribe(type, observer); } int RelationalStore::DoSubScribe(Rdb_SubscribeType type, const Rdb_DataObserver *observer) { - if (store_ == nullptr || type < RDB_SUBSCRIBE_TYPE_CLOUD || type > RDB_SUBSCRIBE_TYPE_CLOUD_DETAILS || - observer->callback.briefObserver == nullptr || observer->callback.detailsObserver == nullptr) { + if (store_ == nullptr || type < RDB_SUBSCRIBE_TYPE_CLOUD || type > RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS || + observer == nullptr || observer->callback.briefObserver == nullptr || + observer->callback.detailsObserver == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } + std::lock_guard lock(mutex_); auto result = std::any_of(dataObservers_[type].begin(), dataObservers_[type].end(), [observer](const std::shared_ptr &item) { @@ -464,18 +472,19 @@ int RelationalStore::DoSubScribe(Rdb_SubscribeType type, const Rdb_DataObserver } auto subscribeOption = SubscribeOption{ .mode = NDKUtils::GetSubscribeType(type), .event = "data_change" }; auto ndkObserver = std::make_shared(observer, type); - auto subscribeResult = store_->Subscribe(subscribeOption, ndkObserver.get()); + int subscribeResult = (type == RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS) ? + store_->SubscribeObserver(subscribeOption, ndkObserver) : store_->Subscribe(subscribeOption, ndkObserver.get()); if (subscribeResult != OHOS::NativeRdb::E_OK) { LOG_ERROR("subscribe failed"); } else { dataObservers_[type].emplace_back(std::move(ndkObserver)); } - return (OH_Rdb_ErrCode)subscribeResult; + return ConvertorErrorCode::NativeToNdk(subscribeResult); } int RelationalStore::DoUnsubScribe(Rdb_SubscribeType type, const Rdb_DataObserver *observer) { - if (store_ == nullptr || type < RDB_SUBSCRIBE_TYPE_CLOUD || type > RDB_SUBSCRIBE_TYPE_CLOUD_DETAILS) { + if (store_ == nullptr || type < RDB_SUBSCRIBE_TYPE_CLOUD || type > RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } std::lock_guard lock(mutex_); @@ -485,15 +494,16 @@ int RelationalStore::DoUnsubScribe(Rdb_SubscribeType type, const Rdb_DataObserve continue; } auto subscribeOption = SubscribeOption{ .mode = NDKUtils::GetSubscribeType(type), .event = "data_change" }; - int errCode = store_->UnSubscribe(subscribeOption, it->get()); + int errCode = (type == RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS) ? + store_->UnsubscribeObserver(subscribeOption, *it) : store_->UnSubscribe(subscribeOption, it->get()); if (errCode != NativeRdb::E_OK) { LOG_ERROR("unsubscribe failed"); - return errCode; + return ConvertorErrorCode::NativeToNdk(errCode); } it = dataObservers_[type].erase(it); LOG_DEBUG("data observer unsubscribe success"); } - return NativeRdb::E_OK; + return OH_Rdb_ErrCode::RDB_OK; } namespace { @@ -629,7 +639,7 @@ int OH_Rdb_CloudSync(OH_Rdb_Store *store, Rdb_SyncMode mode, const char *tables[ break; } }; - return rdbStore->GetStore()->Sync(syncOption, tableNames, progressCallback); + return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->Sync(syncOption, tableNames, progressCallback)); } int OH_Rdb_SubscribeAutoSyncProgress(OH_Rdb_Store *store, const Rdb_ProgressObserver *callback) @@ -638,7 +648,7 @@ int OH_Rdb_SubscribeAutoSyncProgress(OH_Rdb_Store *store, const Rdb_ProgressObse if (rdbStore == nullptr || callback == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - return rdbStore->SubscribeAutoSyncProgress(callback); + return ConvertorErrorCode::NativeToNdk(rdbStore->SubscribeAutoSyncProgress(callback)); } int OH_Rdb_UnsubscribeAutoSyncProgress(OH_Rdb_Store *store, const Rdb_ProgressObserver *callback) @@ -647,7 +657,7 @@ int OH_Rdb_UnsubscribeAutoSyncProgress(OH_Rdb_Store *store, const Rdb_ProgressOb if (rdbStore == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - return rdbStore->UnsubscribeAutoSyncProgress(callback); + return ConvertorErrorCode::NativeToNdk(rdbStore->UnsubscribeAutoSyncProgress(callback)); } int OH_Rdb_LockRow(OH_Rdb_Store *store, OH_Predicates *predicates) @@ -657,7 +667,7 @@ int OH_Rdb_LockRow(OH_Rdb_Store *store, OH_Predicates *predicates) if (rdbStore == nullptr || predicate == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - return rdbStore->GetStore()->ModifyLockStatus(predicate->Get(), true); + return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->ModifyLockStatus(predicate->Get(), true)); } int OH_Rdb_UnlockRow(OH_Rdb_Store *store, OH_Predicates *predicates) @@ -667,7 +677,7 @@ int OH_Rdb_UnlockRow(OH_Rdb_Store *store, OH_Predicates *predicates) if (rdbStore == nullptr || predicate == nullptr) { return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS; } - return rdbStore->GetStore()->ModifyLockStatus(predicate->Get(), false); + return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->ModifyLockStatus(predicate->Get(), false)); } OH_Cursor *OH_Rdb_QueryLockedRow( @@ -733,9 +743,78 @@ void NDKStoreObserver::OnChange(const std::vector &devices) } } +size_t NDKStoreObserver::GetKeyInfoSize(RdbStoreObserver::ChangeInfo &&changeInfo) +{ + size_t size = 0; + for (auto it = changeInfo.begin(); it != changeInfo.end(); ++it) { + size += it->second[RdbStoreObserver::CHG_TYPE_INSERT].size() * sizeof(Rdb_KeyInfo::Rdb_KeyData); + size += it->second[RdbStoreObserver::CHG_TYPE_UPDATE].size() * sizeof(Rdb_KeyInfo::Rdb_KeyData); + size += it->second[RdbStoreObserver::CHG_TYPE_DELETE].size() * sizeof(Rdb_KeyInfo::Rdb_KeyData); + } + return size; +} + +int32_t NDKStoreObserver::GetKeyDataType(std::vector &primaryKey) +{ + if (primaryKey.size() == 0) { + return OH_ColumnType::TYPE_NULL; + } + if (std::holds_alternative(primaryKey[0]) || std::holds_alternative(primaryKey[0])) { + return OH_ColumnType::TYPE_INT64; + } + if (std::holds_alternative(primaryKey[0])) { + return OH_ColumnType::TYPE_TEXT; + } + return OH_ColumnType::TYPE_NULL; +} + void NDKStoreObserver::OnChange(const Origin &origin, const RdbStoreObserver::PrimaryFields &fields, RdbStoreObserver::ChangeInfo &&changeInfo) { + uint32_t count = changeInfo.size(); + if (count == 0) { + LOG_ERROR("No any infos"); + return; + } + + if (mode_ == Rdb_SubscribeType::RDB_SUBSCRIBE_TYPE_CLOUD_DETAILS || + mode_ == Rdb_SubscribeType::RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS) { + size_t size = count * (sizeof(Rdb_ChangeInfo *) + sizeof(Rdb_ChangeInfo)) + + GetKeyInfoSize(std::forward(changeInfo)); + std::unique_ptr buffer = std::make_unique(size); + Rdb_ChangeInfo **infos = (Rdb_ChangeInfo **)(buffer.get()); + if (infos == nullptr) { + LOG_ERROR("Failed to allocate memory for Rdb_ChangeInfo"); + return; + } + + Rdb_ChangeInfo *details = (Rdb_ChangeInfo *)(infos + count); + Rdb_KeyInfo::Rdb_KeyData *data = (Rdb_KeyInfo::Rdb_KeyData *)(details + count); + + int index = 0; + for (auto it = changeInfo.begin(); it != changeInfo.end(); ++it) { + infos[index] = &details[index]; + infos[index]->version = DISTRIBUTED_CHANGE_INFO_VERSION; + infos[index]->tableName = it->first.c_str(); + infos[index]->ChangeType = origin.dataType; + infos[index]->inserted.count = static_cast(it->second[RdbStoreObserver::CHG_TYPE_INSERT].size()); + infos[index]->inserted.type = GetKeyDataType(it->second[RdbStoreObserver::CHG_TYPE_INSERT]); + infos[index]->updated.count = static_cast(it->second[RdbStoreObserver::CHG_TYPE_UPDATE].size()); + infos[index]->updated.type = GetKeyDataType(it->second[RdbStoreObserver::CHG_TYPE_UPDATE]); + infos[index]->deleted.count = static_cast(it->second[RdbStoreObserver::CHG_TYPE_DELETE].size()); + infos[index]->deleted.type = GetKeyDataType(it->second[RdbStoreObserver::CHG_TYPE_DELETE]); + ConvertKeyInfoData(data, it->second[RdbStoreObserver::CHG_TYPE_INSERT]); + infos[index]->inserted.data = data; + ConvertKeyInfoData(data+infos[index]->inserted.count, it->second[RdbStoreObserver::CHG_TYPE_UPDATE]); + infos[index]->updated.data = data+infos[index]->inserted.count; + ConvertKeyInfoData(data+infos[index]->inserted.count+infos[index]->updated.count, + it->second[RdbStoreObserver::CHG_TYPE_DELETE]); + infos[index]->deleted.data = data+infos[index]->inserted.count+infos[index]->updated.count; + index++; + } + + (*observer_->callback.detailsObserver)(observer_->context, const_cast(infos), count); + } } void NDKStoreObserver::OnChange() @@ -743,8 +822,27 @@ void NDKStoreObserver::OnChange() RdbStoreObserver::OnChange(); } -void NDKStoreObserver::ConvertKeyInfo(Rdb_KeyInfo &keyInfo, std::vector &primaryKey) +void NDKStoreObserver::ConvertKeyInfoData(Rdb_KeyInfo::Rdb_KeyData *keyInfoData, + std::vector &primaryKey) { + if (keyInfoData == nullptr || primaryKey.empty()) { + LOG_WARN("no data, keyInfoData is nullptr:%{public}d", keyInfoData == nullptr); + return; + } + + for (size_t i = 0; i < primaryKey.size(); ++i) { + const auto &key = primaryKey[i]; + if (auto val = std::get_if(&key)) { + keyInfoData[i].real = *val; + } else if (auto val = std::get_if(&key)) { + keyInfoData[i].integer = *val; + } else if (auto val = std::get_if(&key)) { + keyInfoData[i].text = val->c_str(); + } else { + LOG_ERROR("Not support the data type"); + return; + } + } } bool NDKStoreObserver::operator==(const Rdb_DataObserver *other) diff --git a/relational_store/interfaces/ndk/src/relational_store_impl.h b/relational_store/interfaces/ndk/src/relational_store_impl.h index efba6554..46e106d9 100644 --- a/relational_store/interfaces/ndk/src/relational_store_impl.h +++ b/relational_store/interfaces/ndk/src/relational_store_impl.h @@ -52,7 +52,10 @@ public: bool operator==(const Rdb_DataObserver *other); private: - void ConvertKeyInfo(Rdb_KeyInfo &keyInfo, std::vector &primaryKey); + void ConvertKeyInfoData(Rdb_KeyInfo::Rdb_KeyData *keyInfoData, + std::vector &primaryKey); + size_t GetKeyInfoSize(RdbStoreObserver::ChangeInfo &&changeInfo); + int32_t GetKeyDataType(std::vector &primaryKey); int mode_ = Rdb_SubscribeType::RDB_SUBSCRIBE_TYPE_CLOUD; const Rdb_DataObserver *observer_; }; diff --git a/relational_store/rdbmock/frameworks/native/rdb/file_ex.h b/relational_store/rdbmock/frameworks/native/rdb/file_ex.h new file mode 100644 index 00000000..59e5112e --- /dev/null +++ b/relational_store/rdbmock/frameworks/native/rdb/file_ex.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MOCK_UTILS_BASE_FILE_EX_H +#define MOCK_UTILS_BASE_FILE_EX_H + +#include +#include + +static bool SaveBufferToFile(const std::string& filePath, const std::vector& content, bool truncated = true) +{ + return true; +} + +static bool LoadBufferFromFile(const std::string& filePath, std::vector& content) +{ + return true; +} + +#endif /* MOCK_UTILS_BASE_FILE_EX_H */ + diff --git a/relational_store/rdbmock/frameworks/native/rdb/hks_api.h b/relational_store/rdbmock/frameworks/native/rdb/hks_api.h new file mode 100644 index 00000000..ebaefaa3 --- /dev/null +++ b/relational_store/rdbmock/frameworks/native/rdb/hks_api.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MOCK_STORE_HKS_API_H +#define MOCK_STORE_HKS_API_H + +#include "hks_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Init operation + * @param keyAlias key alias + * @param paramSet required parameter set + * @param handle operation handle + * @param token token + * @return error code, see hks_type.h + */ +static int32_t HksInit(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet, + struct HksBlob *handle, struct HksBlob *token) +{ + return HKS_SUCCESS; +} + +/** + * @brief Update operation + * @param handle operation handle + * @param paramSet required parameter set + * @param inData the data to update + * @param outData output data + * @return error code, see hks_type.h + */ +static int32_t HksUpdate(const struct HksBlob *handle, const struct HksParamSet *paramSet, + const struct HksBlob *inData, struct HksBlob *outData) +{ + return HKS_SUCCESS; +} + +/** + * @brief Finish operation + * @param handle operation handle + * @param paramSet required parameter set + * @param inData the data to update + * @param outData output data + * @return error code, see hks_type.h + */ +static int32_t HksFinish(const struct HksBlob *handle, const struct HksParamSet *paramSet, + const struct HksBlob *inData, struct HksBlob *outData) +{ + return HKS_SUCCESS; +} + +/** + * @brief Generate key + * @param keyAlias key alias + * @param paramSetIn required parameter set + * @param paramSetOut output parameter set + * @return error code, see hks_type.h + */ +static int32_t HksGenerateKey(const struct HksBlob *keyAlias, + const struct HksParamSet *paramSetIn, struct HksParamSet *paramSetOut) +{ + return HKS_SUCCESS; +} + +/** + * @brief Check whether the key exists + * @param keyAlias key alias + * @param paramSetIn required parameter set + * @param paramSetOut output parameter set + * @return error code, see hks_type.h + */ +static int32_t HksKeyExist(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet) +{ + return HKS_SUCCESS; +} + +#ifdef __cplusplus +} +#endif + +#endif /* MOCK_STORE_HKS_API_H */ diff --git a/relational_store/rdbmock/frameworks/native/rdb/hks_param.h b/relational_store/rdbmock/frameworks/native/rdb/hks_param.h new file mode 100644 index 00000000..ed3034bd --- /dev/null +++ b/relational_store/rdbmock/frameworks/native/rdb/hks_param.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MOCK_HKS_PARAM_H +#define MOCK_HKS_PARAM_H + +#include "hks_type.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Init parameter set + * @param paramSet required parameter set + * @return error code, see hks_type.h + */ +static int32_t HksInitParamSet(struct HksParamSet **paramSet) +{ + return HKS_SUCCESS; +} + +/** + * @brief Add parameter set + * @param paramSet required parameter set + * @param params params need to add + * + * @param paramCnt numbers of params + * @return error code, see hks_type.h + */ +static int32_t HksAddParams(struct HksParamSet *paramSet, + const struct HksParam *params, uint32_t paramCnt) +{ + return HKS_SUCCESS; +} + +/** + * @brief Build parameter set + * @param paramSet required parameter set + * @return error code, see hks_type.h + */ +static int32_t HksBuildParamSet(struct HksParamSet **paramSet) +{ + return HKS_SUCCESS; +} + +/** + * @brief Free parameter set + * @param paramSet required parameter set + * @return error code, see hks_type.h + */ +static void HksFreeParamSet(struct HksParamSet **paramSet) +{ + return ; +} + +#ifdef __cplusplus +} +#endif + +#endif /* MOCK_HKS_PARAM_H */ diff --git a/relational_store/rdbmock/frameworks/native/rdb/hks_type.h b/relational_store/rdbmock/frameworks/native/rdb/hks_type.h new file mode 100644 index 00000000..d0bf9383 --- /dev/null +++ b/relational_store/rdbmock/frameworks/native/rdb/hks_type.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MOCK_HKS_TYPE_H +#define MOCK_HKS_TYPE_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +enum HksTagType { + HKS_TAG_TYPE_UINT = 2 << 28, + HKS_TAG_TYPE_BYTES = 5 << 28, +}; + +enum HksErrorCode { + HKS_SUCCESS = 0, + HKS_FAILURE = -1, + HKS_ERROR_INVALID_ARGUMENT = -3, + + HKS_ERROR_NOT_EXIST = -13, +}; + +enum HksKeyAlg { + HKS_ALG_AES = 20, +}; + +enum HksKeyPurpose { + HKS_KEY_PURPOSE_ENCRYPT = 1, + HKS_KEY_PURPOSE_DECRYPT = 2, +}; + +enum HksKeyPadding { + HKS_PADDING_NONE = 0, +}; + +enum HksCipherMode { + HKS_MODE_GCM = 32, +}; + +enum HksAuthStorageLevel { + HKS_AUTH_STORAGE_LEVEL_DE = 0, +}; + +enum HksKeySize { + HKS_AES_KEY_SIZE_256 = 256, +}; + +struct HksBlob { + uint32_t size; + uint8_t *data; +}; + +struct HksParam { + uint32_t tag; + union { + bool boolParam; + int32_t int32Param; + uint32_t uint32Param; + uint64_t uint64Param; + struct HksBlob blob; + }; +}; + +enum HksTag { + HKS_TAG_ALGORITHM = HKS_TAG_TYPE_UINT | 1, + HKS_TAG_PURPOSE = HKS_TAG_TYPE_UINT | 2, + HKS_TAG_KEY_SIZE = HKS_TAG_TYPE_UINT | 3, + HKS_TAG_DIGEST = HKS_TAG_TYPE_UINT | 4, + HKS_TAG_PADDING = HKS_TAG_TYPE_UINT | 5, + HKS_TAG_BLOCK_MODE = HKS_TAG_TYPE_UINT | 6, + HKS_TAG_ASSOCIATED_DATA = HKS_TAG_TYPE_BYTES | 8, + HKS_TAG_NONCE = HKS_TAG_TYPE_BYTES | 9, + + HKS_TAG_AUTH_STORAGE_LEVEL = HKS_TAG_TYPE_UINT | 316, + + HKS_TAG_AE_TAG = HKS_TAG_TYPE_BYTES | 10009, +}; + +struct HksParamSet; + + +#ifdef __cplusplus +} +#endif + +#endif /* MOCK_HKS_TYPE_H */ diff --git a/relational_store/rdbmock/frameworks/native/rdb/lru_bucket.h b/relational_store/rdbmock/frameworks/native/rdb/lru_bucket.h new file mode 100644 index 00000000..fb899813 --- /dev/null +++ b/relational_store/rdbmock/frameworks/native/rdb/lru_bucket.h @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_DATA_FRAMEWORKS_COMMON_LRU_BUCKET_H +#define OHOS_DISTRIBUTED_DATA_FRAMEWORKS_COMMON_LRU_BUCKET_H + +#include +#include +#include + +namespace OHOS { +template +class LRUBucket { +public: + LRUBucket(size_t capacity) + : size_(0), capacity_(capacity) {} + + LRUBucket(LRUBucket &&bucket) noexcept = delete; + LRUBucket(const LRUBucket &bucket) = delete; + LRUBucket &operator=(LRUBucket &&bucket) noexcept = delete; + LRUBucket &operator=(const LRUBucket &bucket) = delete; + + ~LRUBucket() + { + std::lock_guard lock(mutex_); + while (size_ > 0) { + PopBack(); + } + } + + size_t Size() const + { + return size_; + } + + size_t Capacity() const + { + return capacity_; + } + + bool ResetCapacity(size_t capacity) + { + std::lock_guard lock(mutex_); + capacity_ = capacity; + while (capacity_ < size_) { + PopBack(); + } + return capacity_ == capacity; + } + + /** + * The time complexity is O(log(index size)) + **/ + bool Get(const _Key &key, _Tp &value, bool isLRU = true) + { + std::lock_guard lock(mutex_); + auto it = indexes_.find(key); + if (it != indexes_.end()) { + if (isLRU) { + // move node from the list; + Remove(it->second); + // insert node to the head + Insert(&head_, it->second); + } + value = it->second->value_; + return true; + } + return false; + } + + /** + * The time complexity is O(log(index size)) + **/ + bool Set(const _Key &key, const _Tp &value) + { + std::lock_guard lock(mutex_); + if (capacity_ == 0) { + return false; + } + + auto it = indexes_.find(key); + if (it != indexes_.end()) { + Update(it->second, value); + Remove(it->second); + Insert(&head_, it->second); + return true; + } + + while (capacity_ <= size_) { + PopBack(); + } + + auto *node = new(std::nothrow) Node(value); + if (node == nullptr) { + return false; + } + + Insert(&head_, node); + auto pair = indexes_.emplace(key, node); + node->iterator_ = pair.first; + return true; + } + + /** + * Just update the values, not change the lru + **/ + bool Update(const _Key &key, const _Tp &value) + { + std::lock_guard lock(mutex_); + auto it = indexes_.find(key); + if (it != indexes_.end()) { + Update(it->second, value); + return true; + } + return false; + } + + /** + * The time complexity is O(min(indexes, values)) + * Just update the values, not change the lru chain + */ + bool Update(const std::map<_Key, _Tp> &values) + { + std::lock_guard lock(mutex_); + auto idx = indexes_.begin(); + auto val = values.begin(); + bool updated = false; + auto comp = indexes_.key_comp(); + while (idx != indexes_.end() && val != values.end()) { + if (comp(idx->first, val->first)) { + ++idx; + continue; + } + if (comp(val->first, idx->first)) { + ++val; + continue; + } + updated = true; + Update(idx->second, val->second); + ++idx; + ++val; + } + return updated; + } + + /** + * The time complexity is O(log(index size)) + * */ + bool Delete(const _Key &key) + { + std::lock_guard lock(mutex_); + auto it = indexes_.find(key); + if (it != indexes_.end()) { + Remove(it->second); + Delete(it->second); + return true; + } + return false; + } + +private: + struct Node final { + using iterator = typename std::map<_Key, Node *>::iterator; + Node(const _Tp &value) : value_(value) {} + Node() : value_() {} + ~Node() = default; + _Tp value_; + iterator iterator_; + Node *prev_ = this; + Node *next_ = this; + }; + + void PopBack() + { + auto *node = head_.prev_; + Remove(node); + Delete(node); + } + + void Update(Node *node, const _Tp &value) + { + node->value_ = value; + } + + void Remove(Node *node) + { + node->prev_->next_ = node->next_; + node->next_->prev_ = node->prev_; + size_--; + } + + void Insert(Node *prev, Node *node) + { + prev->next_->prev_ = node; + node->next_ = prev->next_; + prev->next_ = node; + node->prev_ = prev; + size_++; + } + + void Delete(Node *node) + { + indexes_.erase(node->iterator_); + delete node; + } + + mutable std::recursive_mutex mutex_; + std::map<_Key, Node *> indexes_; + Node head_; + size_t size_; + size_t capacity_; +}; +} // namespace OHOS +#endif // OHOS_DISTRIBUTED_DATA_FRAMEWORKS_COMMON_LRU_BUCKET_H diff --git a/relational_store/rdbmock/frameworks/native/rdb/relational_store_client.h b/relational_store/rdbmock/frameworks/native/rdb/relational_store_client.h index b9a5aff5..161abcb4 100644 --- a/relational_store/rdbmock/frameworks/native/rdb/relational_store_client.h +++ b/relational_store/rdbmock/frameworks/native/rdb/relational_store_client.h @@ -28,6 +28,10 @@ enum DBStatus { NOT_FOUND = 2, WAIT_COMPENSATED_SYNC = 57, }; +class RelationalStoreManager { +public: + static std::string GetDistributedLogTableName(const std::string &tableName); +}; } DistributedDB::DBStatus UnRegisterClientObserver(sqlite3 *db); @@ -47,4 +51,5 @@ DistributedDB::DBStatus UnLock( const std::string &tableName, const std::vector> &hashKey, sqlite3 *db); DistributedDB::DBStatus DropLogicDeletedData(sqlite3* db, const std::string& tableName, uint64_t cursor); + #endif //RELATIONAL_STORE_RELATIONAL_STORE_CLIENT_H diff --git a/relational_store/test/js/rdb/unittest/src/RdbstoreInsertJsunit.test.js b/relational_store/test/js/rdb/unittest/src/RdbstoreInsertJsunit.test.js index 6355158c..18244142 100644 --- a/relational_store/test/js/rdb/unittest/src/RdbstoreInsertJsunit.test.js +++ b/relational_store/test/js/rdb/unittest/src/RdbstoreInsertJsunit.test.js @@ -280,6 +280,39 @@ describe('rdbStoreInsertTest', function () { console.log(TAG + "************* testRdbStoreInsert0006 end *************"); }) + /** + * @tc.name rdb getString test + * @tc.number SUB_DDM_AppDataFWK_JSRDB_GetString_0001 + * @tc.desc rdb getString test of the null value + */ + it('testRdbStoreGetString0001', 0, async function (done) { + console.log(TAG + "************* testRdbStoreGetString0001 start *************"); + var u8 = new Uint8Array([1, 2, 3]) + const valueBucket = { + "name": "", + "age": 21, + "salary": 100.5, + "blobType": u8, + } + await rdbStore.insert("test", valueBucket) + let predicates = new dataRdb.RdbPredicates("test"); + predicates.equalTo("name", "") + let resultSet = await rdbStore.query(predicates) + try { + console.log(TAG + "resultSet query done"); + expect(true).assertEqual(resultSet.goToFirstRow()) + const name = resultSet.getString(resultSet.getColumnIndex("name")) + expect("").assertEqual(name) + } catch (e) { + console.log("insert error " + e); + expect().assertFail(); + } + resultSet.close() + resultSet = null + done() + console.log(TAG + "************* testRdbStoreGetString0001 end *************"); + }) + /** * @tc.name: rdb batchInsert test * @tc.number: SUB_DDM_AppDataFWK_JSRDB_batchInsert_0001 diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbStoreCorruptJsunit.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbStoreCorruptJsunit.test.js index 690bc315..106c8683 100644 --- a/relational_store/test/js/relationalstore/unittest/src/RdbStoreCorruptJsunit.test.js +++ b/relational_store/test/js/relationalstore/unittest/src/RdbStoreCorruptJsunit.test.js @@ -61,7 +61,7 @@ describe('RdbStoreCorruptTest', function () { let dir = await context.getFilesDir(); console.log(TAG, `filepath is${dir},databaseDir is${context.databaseDir},dbpath is${dbPath}`) rdbStore = await data_relationalStore.getRdbStore(context, STORE_CONFIG); - rdbStore.executeSql(CREATE_TABLE_TEST, null); + await rdbStore.executeSql(CREATE_TABLE_TEST, null); await createTest(); let u8 = new Uint8Array([1, 2, 3]); const valueBucket = { @@ -175,7 +175,7 @@ describe('RdbStoreCorruptTest', function () { /** * @tc.name the insert function - * @tc.number SUB_DDM_AppDataFWK_JSRDB_RdbStore_insert_002 + * @tc.number SUB_DDM_AppDataFWK_JSRDB_RdbStore_insert_001 * @tc.desc insert while corrupt */ it('insertTest0001', 0, async function (done) { diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbStoreDistributedJsunit.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbStoreDistributedJsunit.test.js index f5c7003b..6eea12af 100644 --- a/relational_store/test/js/relationalstore/unittest/src/RdbStoreDistributedJsunit.test.js +++ b/relational_store/test/js/relationalstore/unittest/src/RdbStoreDistributedJsunit.test.js @@ -19,7 +19,7 @@ import ability_featureAbility from '@ohos.ability.featureAbility' const TAG = "[RELATIONAL_STORE_JSKITS_TEST]" const STORE_NAME = "distributed_rdb.db" -const E_NOT_SUPPORTED = 801; +const E_NOT_SUPPORT = 801; var rdbStore = undefined; var context = ability_featureAbility.getContext() @@ -96,7 +96,7 @@ describe('rdbStoreDistributedTest', function () { expect(rdbStore).assertEqual(rdbStore) } catch (err) { console.log(TAG + `set none to be distributed table failed, err is ${err.code}.`); - expect(E_NOT_SUPPORTED).assertEqual(err.code); + expect(E_NOT_SUPPORT).assertEqual(err.code); } done() console.log(TAG + "************* testRdbStoreDistributed002 end *************"); @@ -115,7 +115,7 @@ describe('rdbStoreDistributedTest', function () { expect(rdbStore).assertEqual(rdbStore) } catch (err) { console.log(TAG + `set employee to be distributed table failed, err is ${err.code}.`); - expect(E_NOT_SUPPORTED).assertEqual(err.code); + expect(E_NOT_SUPPORT).assertEqual(err.code); } done() console.log(TAG + "************* testRdbStoreDistributed003 end *************"); @@ -134,7 +134,7 @@ describe('rdbStoreDistributedTest', function () { expect(rdbStore).assertEqual(rdbStore) } catch (err) { console.log(TAG + `set employee and product to be distributed table failed, err is ${err.code}.`); - expect(E_NOT_SUPPORTED).assertEqual(err.code); + expect(E_NOT_SUPPORT).assertEqual(err.code); } done() console.log(TAG + "************* testRdbStoreDistributed004 end *************"); diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbStoreQueryByStep.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbStoreQueryByStep.test.js index 20595ce2..66c9eff4 100644 --- a/relational_store/test/js/relationalstore/unittest/src/RdbStoreQueryByStep.test.js +++ b/relational_store/test/js/relationalstore/unittest/src/RdbStoreQueryByStep.test.js @@ -307,5 +307,84 @@ describe('rdbStoreQueryByStepTest', function () { done(); }) + /** + * @tc.number testRdbStoreQueryByStep0009 + * @tc.name Normal test case of queryByStep, PRAGMA user_version + * @tc.desc 1.Set user_version + * 2.Get user_version + */ + it('testRdbStoreQueryByStep0009', 0, async function () { + console.log(TAG + "************* testRdbStoreQueryByStep0009 start *************"); + // 2 is used to set the store version + await rdbStore.executeSql("PRAGMA user_version = 2") + let resultSet = await rdbStore.queryByStep("PRAGMA user_version"); + resultSet.goToFirstRow(); + expect(2).assertEqual(resultSet.getLong(0)) + resultSet.close(); + console.log(TAG + "************* testRdbStoreQueryByStep0009 end *************"); + }) + + /** + * @tc.number testRdbStoreQueryByStep0010 + * @tc.name Normal test case of queryByStep, PRAGMA table_info + * @tc.desc 1.Get table_info + * 2.Check table_info + */ + it('testRdbStoreQueryByStep0010', 0, async function () { + console.log(TAG + "************* testRdbStoreQueryByStep0010 start *************"); + let resultSet = await rdbStore.queryByStep("PRAGMA table_info(test)"); + resultSet.goToFirstRow(); + expect("id").assertEqual(resultSet.getString(1)) + expect("INTEGER").assertEqual(resultSet.getString(2)) + resultSet.goToNextRow(); + expect("name").assertEqual(resultSet.getString(1)) + expect("TEXT").assertEqual(resultSet.getString(2)) + expect(0).assertEqual(resultSet.getLong(3)) + resultSet.goToNextRow(); + expect("age").assertEqual(resultSet.getString(1)) + expect("INTEGER").assertEqual(resultSet.getString(2)) + resultSet.goToNextRow(); + expect("salary").assertEqual(resultSet.getString(1)) + expect("REAL").assertEqual(resultSet.getString(2)) + resultSet.goToNextRow(); + expect("blobType").assertEqual(resultSet.getString(1)) + expect("BLOB").assertEqual(resultSet.getString(2)) + resultSet.close(); + console.log(TAG + "************* testRdbStoreQueryByStep0010 end *************"); + }) + + /** + * @tc.number testRdbStoreQueryByStep0009 + * @tc.name Normal test case of queryByStep, query all data + * @tc.desc 1. Execute queryByStep, sql is 'select * from test' + * @tc.size MediumTest + * @tc.type Function + * @tc.level Level 2 + */ + it('testRdbStoreQueryByStep0011', 0, async function (done) { + console.log(TAG + "************* testRdbStoreQueryByStep0011 start *************"); + var u8 = new Uint8Array([1, 2, 3]) + let valuesBucket4 = { + "name": "", + "age": 21, + "salary": 100.5, + "blobType": u8, + } + await rdbStore.insert("test", valuesBucket4); + let resultSet = await rdbStore.queryByStep('select * from test where name = ""'); + try { + console.log(TAG + "resultSet queryByStep done"); + expect(true).assertEqual(resultSet.goToFirstRow()) + const name = resultSet.getString(resultSet.getColumnIndex("name")) + expect("").assertEqual(name) + } catch (err) { + expect().assertFail(); + } + resultSet.close() + resultSet = null + done() + console.log(TAG + "************* testRdbStoreQueryByStep0011 end *************"); + }) + console.info(TAG + "*************Unit Test End*************"); }) diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbStoreReadOnlyJsunit.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbStoreReadOnlyJsunit.test.js new file mode 100644 index 00000000..71debfd8 --- /dev/null +++ b/relational_store/test/js/relationalstore/unittest/src/RdbStoreReadOnlyJsunit.test.js @@ -0,0 +1,302 @@ +/* + * Copyright (C) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from '@ohos/hypium'; +import relationalStore from '@ohos.data.relationalStore'; +import featureAbility from '@ohos.ability.featureAbility' + +let context = featureAbility.getContext(); +let store = undefined; + +const TAG = "[RELATIONAL_STORE_JS_READ_ONLY_TEST]"; + +let STORE_CONFIG = { + name: "store.db", + securityLevel: relationalStore.SecurityLevel.S1, +} +let STORE_CONFIG1 = { + name: "test.db", + securityLevel: relationalStore.SecurityLevel.S1, + isReadOnly: true, +} + +let STORE_CONFIG2 = { + name: "readOnly.db", + securityLevel: relationalStore.SecurityLevel.S1, + isReadOnly: true, +} + +const valueBucket = { + 'name': 'zhangsan', + 'age': 18, + 'salary': 25000, + 'blobType': new Uint8Array([1, 2, 3]), +}; + +describe('rdbStoreReadOnlyTest', function () { + beforeAll(async function () { + console.log(TAG + 'beforeAll'); + try { + await relationalStore.deleteRdbStore(context, STORE_CONFIG); + let rdbStore = await relationalStore.getRdbStore(context, STORE_CONFIG); + expect(rdbStore === null).assertFalse(); + + const CREATE_TABLE_SQL = "CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY AUTOINCREMENT, " + + "name TEXT, age INTEGER, salary REAL, blobType BLOB)"; + await rdbStore.executeSql(CREATE_TABLE_SQL); + + await rdbStore.insert('test', valueBucket); + await rdbStore.insert('test', valueBucket); + + rdbStore.backup(STORE_CONFIG2.name) + await relationalStore.deleteRdbStore(context, STORE_CONFIG); + + } catch (err) { + console.error(TAG, `init database failed, errCode:${err.code}, message:${err.message}`); + expect().assertFail(); + } + }) + + beforeEach(async function () { + store = await relationalStore.getRdbStore(context, STORE_CONFIG2); + expect(store === null).assertFalse(); + console.info(TAG + 'beforeEach'); + }) + + afterEach(async function () { + console.info(TAG + 'afterEach') + }) + + afterAll(async function () { + console.info(TAG + 'afterAll'); + await relationalStore.deleteRdbStore(context, STORE_CONFIG); + await relationalStore.deleteRdbStore(context, STORE_CONFIG1); + await relationalStore.deleteRdbStore(context, STORE_CONFIG2); + }) + + console.info(TAG + "*************JS Test Begin*************"); + + /** + * @tc.name open read-only database if the database is not exist + * @tc.number readOnlyTest0001 + * @tc.desc 1. set isReadOnly as true + * 2. open read-only database + * @tc.size MediumTest + * @tc.type Function + * @tc.level Level 2 + */ + it('readOnlyTest0001', 0, async function () { + console.info(TAG + "************* readOnlyTest0001 start *************"); + try { + await relationalStore.getRdbStore(context, STORE_CONFIG1); + expect().assertFail(); + } catch (err) { + console.error(TAG, `open read-only database failed, errCode:${err.code}, message:${err.message}`); + expect(err.code == 14800030).assertTrue(); + } + console.log(TAG + "************* readOnlyTest0001 end *************"); + }) + + /** + * @tc.name insert data into read-only database + * @tc.number readOnlyTest0002 + * @tc.desc insert data + * @tc.size MediumTest + * @tc.type Function + * @tc.level Level 2 + */ + it('readOnlyTest0002', 0, async function () { + console.info(TAG + "************* readOnlyTest0002 start *************"); + try { + await store.insert('test', valueBucket); + expect().assertFail(); + } catch (err) { + console.error(TAG, `insert failed, errCode:${err.code}, message:${err.message}`); + expect(err.code == 801).assertTrue(); + } + console.info(TAG + "************* readOnlyTest0002 end *************"); + }) + + /** + * @tc.name update data in read-only database + * @tc.number readOnlyTest0003 + * @tc.desc update data + * @tc.size MediumTest + * @tc.type Function + * @tc.level Level 2 + */ + it('readOnlyTest0003', 0, async function () { + console.info(TAG + "************* readOnlyTest0003 start *************"); + try { + let predicates = new relationalStore.RdbPredicates('test') + predicates.equalTo('id', 1) + await store.update(valueBucket, predicates); + expect().assertFail(); + } catch (err) { + console.error(TAG, `update failed, errCode:${err.code}, message:${err.message}`); + expect(err.code == 801).assertTrue(); + } + console.info(TAG + "************* readOnlyTest0003 end *************"); + }) + + /** + * @tc.name delete data from read-only database + * @tc.number readOnlyTest0004 + * @tc.desc delete data + * @tc.size MediumTest + * @tc.type Function + * @tc.level Level 2 + */ + it('readOnlyTest0004', 0, async function () { + console.info(TAG + "************* readOnlyTest0004 start *************"); + try { + let predicates = new relationalStore.RdbPredicates('test') + await store.delete(predicates); + expect().assertFail(); + } catch (err) { + console.error(TAG, `delete failed, errCode:${err.code}, message:${err.message}`); + expect(err.code == 801).assertTrue(); + } + console.info(TAG + "************* readOnlyTest0004 end *************"); + }) + + /** + * @tc.name execute transaction for read-only database + * @tc.number readOnlyTest0005 + * @tc.desc begin transaction + * @tc.size MediumTest + * @tc.type Function + * @tc.level Level 2 + */ + it('readOnlyTest0005', 0, async function () { + console.info(TAG + "************* readOnlyTest0005 start *************"); + try { + store.beginTransaction(); + expect().assertFail(); + } catch (err) { + console.error(TAG, `begin transaction failed, errCode:${err.code}, message:${err.message}`); + expect(err.code == 801).assertTrue(); + } + console.info(TAG + "************* readOnlyTest0005 end *************"); + }) + + /** + * @tc.name get user_version from read-only database + * @tc.number readOnlyTest0006 + * @tc.desc get user_version + * @tc.size MediumTest + * @tc.type Function + * @tc.level Level 2 + */ + it('readOnlyTest0006', 0, async function () { + console.info(TAG + "************* readOnlyTest0006 start *************"); + try { + expect(store.version === 0).assertTrue(); + let resultSet = await store.querySql('PRAGMA user_version'); + resultSet.goToFirstRow(); + expect(resultSet.getValue(0) === 0).assertTrue(); + } catch (err) { + console.error(TAG, `restore failed, errCode:${err.code}, message:${err.message}`); + expect().assertFail(); + } + console.info(TAG + "************* readOnlyTest0006 end *************"); + }) + + /** + * @tc.name query data from read-only database + * @tc.number readOnlyTest0007 + * @tc.desc query data + * @tc.size MediumTest + * @tc.type Function + * @tc.level Level 2 + */ + it('readOnlyTest0007', 0, async function () { + console.info(TAG + "************* readOnlyTest0007 start *************"); + try { + let predicates = await new relationalStore.RdbPredicates('test') + let resultSet = await store.query(predicates); + expect(resultSet.rowCount == 2).assertTrue(); + } catch (err) { + console.error(TAG, `query failed, errCode:${err.code}, message:${err.message}`); + expect().assertFail(); + } + console.info(TAG + "************* readOnlyTest0007 end *************"); + }) + + /** + * @tc.name set user_version to read-only database + * @tc.number readOnlyTest0008 + * @tc.desc test execute + * @tc.size MediumTest + * @tc.type Function + * @tc.level Level 2 + */ + it('readOnlyTest0008', 0, async function () { + console.info(TAG + "************* readOnlyTest0008 start *************"); + try { + expect(store.version === 0).assertTrue(); + await store.execute('PRAGMA user_version=5'); + expect().assertFail(); + } catch (err) { + console.error(TAG, `get user_version failed, errCode:${err.code}, message:${err.message}`); + expect(err.code == 801).assertTrue(); + } + console.info(TAG + "************* readOnlyTest0008 end *************"); + }) + + /** + * @tc.name set user_version to read-only database + * @tc.number readOnlyTest009 + * @tc.desc test executeSql + * @tc.size MediumTest + * @tc.type Function + * @tc.level Level 2 + */ + it('readOnlyTest009', 0, async function () { + console.info(TAG + "************* readOnlyTest009 start *************"); + try { + expect(store.version === 0).assertTrue(); + await store.executeSql('PRAGMA user_version'); + expect().assertFail(); + } catch (err) { + console.error(TAG, `set user_version failed, errCode:${err.code}, message:${err.message}`); + expect(err.code == 801).assertTrue(); + } + console.info(TAG + "************* readOnlyTest009 end *************"); + }) + + /** + * @tc.name set user_version to read-only database + * @tc.number readOnlyTest0010 + * @tc.desc set user_version by store + * @tc.size MediumTest + * @tc.type Function + * @tc.level Level 2 + */ + it('readOnlyTest010', 0, async function () { + console.info(TAG + "************* readOnlyTest0010 start *************"); + try { + store.version = 5; + expect().assertFail(); + } catch (err) { + console.error(TAG, `set user_version failed, errCode:${err.code}, message:${err.message}`); + expect(err.code == 801).assertTrue(); + } + console.info(TAG + "************* readOnlyTest0010 end *************"); + }) + + console.info(TAG + "*************Unit Test End*************"); +}) + diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbStoreResultSetSyncJsunit.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbStoreResultSetSyncJsunit.test.js index 81c88c2d..92cd069a 100644 --- a/relational_store/test/js/relationalstore/unittest/src/RdbStoreResultSetSyncJsunit.test.js +++ b/relational_store/test/js/relationalstore/unittest/src/RdbStoreResultSetSyncJsunit.test.js @@ -1936,12 +1936,12 @@ describe('rdbResultSetSyncTest', function () { expect(0).assertEqual(count); resultSet.goToFirstRow(); - expect(true).assertEqual(resultSet.isStarted); + expect(false).assertEqual(resultSet.isStarted); console.log(TAG + "************* testSyncBigData0004 after goto first row *************"); let rows = [1, 2, 0, -1, -2]; for (const i of rows) { resultSet.goToRow(i); - expect(true).assertEqual(resultSet.isStarted); + expect(false).assertEqual(resultSet.isStarted); } resultSet.close() diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbStoreStatisticsJsunit.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbStoreStatisticsJsunit.test.js new file mode 100644 index 00000000..6b42a032 --- /dev/null +++ b/relational_store/test/js/relationalstore/unittest/src/RdbStoreStatisticsJsunit.test.js @@ -0,0 +1,581 @@ +/* + * Copyright (C) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from "deccjsunit/index" +import relationalStore from '@ohos.data.relationalStore'; +import ability_featureAbility from '@ohos.ability.featureAbility' + +const TAG = "[RELATIONAL_STORE_JSKITS_TEST]" +const STORE_NAME = "statistics.db" +let rdbStore = undefined; +let context = ability_featureAbility.getContext() +describe('RdbStoreStatisticsTest', function () { + beforeAll(async function () { + console.info(TAG + 'beforeAll') + const config = { + 'name': STORE_NAME, + securityLevel: relationalStore.SecurityLevel.S1, + } + try { + rdbStore = await relationalStore.getRdbStore(context, config); + } catch (err) { + console.error(TAG + `failed, code:${err.code}, message: ${err.message}`) + expect().assertFail() + } + }) + + beforeEach(async function () { + console.info(TAG + 'beforeEach') + try { + const CREATE_TABLE_SQL = "CREATE TABLE IF NOT EXISTS test (" + + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + + "name TEXT NOT NULL, " + "age INTEGER, " + "salary REAL, " + "blobType BLOB)"; + await rdbStore.executeSql(CREATE_TABLE_SQL); + + const valueBucket1 = { + 'name': 'zhangsan', + 'age': 18, + 'salary': 25000, + 'blobType': new Uint8Array([1, 2, 3]), + }; + let rowId = await rdbStore.insert('test', valueBucket1); + expect(1).assertEqual(rowId); + } catch (err) { + console.error(TAG + `failed2, code:${err.code}, message: ${err.message}`) + expect().assertFail() + } + }) + + afterEach(async function () { + console.info(TAG + 'afterEach') + try { + rdbStore.off('statistics') + } catch (err) { + console.error(TAG + `unRegister fail3, code:${err.code}, message: ${err.message}`); + expect().assertFail(); + } + await rdbStore.executeSql("drop table test"); + }) + + afterAll(async function () { + console.info(TAG + 'afterAll') + rdbStore = null + await relationalStore.deleteRdbStore(context, STORE_NAME); + }) + + console.info(TAG + "*************Unit Test Begin*************"); + + /** + * @tc.name Normal case for Statistics insert data execution time + * @tc.number testRdbStoreStatistics0001 + * @tc.desc 1. Register callback for statistics + * 2. Insert data + * 3. UnRegister callback + */ + it('testRdbStoreStatistics0001', 0, async function (done) { + console.info(TAG + "************* testRdbStoreStatistics0001 start *************"); + try { + rdbStore.on('statistics', (SqlExeInfo) => { + expect('INSERT INTO test(age,blobType,name,salary) VALUES (?,?,?,?)').assertEqual(SqlExeInfo.sql[0]); + done() + }) + } catch (err) { + console.error(TAG + `on statistics fail, code:${err.code}, message: ${err.message}`); + expect().assertFail(); + done() + } + + try { + const valueBucket1 = { + 'name': 'zhangsan', + 'age': 18, + 'salary': 25000, + 'blobType': new Uint8Array([1, 2, 3]), + }; + let rowId = await rdbStore.insert('test', valueBucket1); + expect(2).assertEqual(rowId); + } catch (error) { + console.error(TAG + `insert2 fail, code:${error.code}, message: ${error.message}`); + expect().assertFail(); + done(); + } + console.info(TAG + "************* testRdbStoreStatistics0001 end *************"); + }) + + /** + * @tc.name Normal case for Statistics update data execution time + * @tc.number testRdbStoreStatistics0002 + * @tc.desc 1. Register callback for statistics + * 2. Update data + * 3. UnRegister callback + */ + it('testRdbStoreStatistics0002', 0, async function (done) { + console.info(TAG + "************* testRdbStoreStatistics0002 start *************"); + try { + rdbStore.on('statistics', (SqlExeInfo) => { + expect('UPDATE test SET age=?,blobType=?,name=?,salary=? WHERE id = ? ').assertEqual(SqlExeInfo.sql[0]); + done() + }) + } catch (err) { + console.error(TAG + `register fail, code:${err.code}, message: ${err.message}`); + expect().assertFail(); + done() + } + + try { + const valueBucket = { + 'name': 'lisi', + 'age': 18, + 'salary': 30000, + 'blobType': new Uint8Array([1, 2, 3]), + }; + let predicates = new relationalStore.RdbPredicates('test'); + predicates.equalTo('id', 1); + let rowId = await rdbStore.update(valueBucket, predicates); + expect(1).assertEqual(rowId); + } catch (error) { + console.error(TAG + `update fail, code:${error.code}, message: ${error.message}`); + expect().assertFail(); + done() + } + console.info(TAG + "************* testRdbStoreStatistics0002 end *************"); + }) + + /** + * @tc.name Normal case for Statistics delete data execution time + * @tc.number testRdbStoreStatistics0003 + * @tc.desc 1. Register callback for statistics + * 2. Delete data + * 3. UnRegister callback + */ + it('testRdbStoreStatistics0003', 0, async function (done) { + console.info(TAG + "************* testRdbStoreStatistics0003 start *************"); + try { + rdbStore.on('statistics', (SqlExeInfo) => { + expect('DELETE FROM test').assertEqual(SqlExeInfo.sql[0]); + done() + }) + } catch (err) { + console.error(TAG + `register fail, code:${err.code}, message: ${err.message}`); + expect().assertFail(); + done() + } + + try { + let predicates = new relationalStore.RdbPredicates('test'); + let rowId = await rdbStore.delete(predicates); + expect(1).assertEqual(rowId); + } catch (error) { + console.error(TAG + `delete fail, code:${error.code}, message: ${error.message}`); + expect().assertFail(); + done() + } + console.info(TAG + "************* testRdbStoreStatistics0003 end *************"); + }) + + /** + * @tc.name Normal case for Statistics batchInsert data execution time + * @tc.number testRdbStoreStatistics0004 + * @tc.desc 1. Register callback for statistics + * 2. batchInsert data + * 3. UnRegister callback + */ + it('testRdbStoreStatistics0004', 0, async function (done) { + console.info(TAG + "************* testRdbStoreStatistics0004 start *************"); + try { + rdbStore.on('statistics', (SqlExeInfo) => { + expect(SqlExeInfo.sql.length).assertEqual(1); + done() + }) + } catch (err) { + console.error(TAG + `register fail, code:${err.code}, message: ${err.message}`); + expect().assertFail(); + done() + } + + try { + let u8 = new Uint8Array([1, 2, 3]) + const valueBucket = { + "name": "zhangsan", + "age": 18, + "salary": 100.5, + "blobType": u8, + } + let valueBucketArray = new Array(); + for (let i = 0; i < 1000; i++) { + valueBucketArray.push(valueBucket); + } + let rowId = await rdbStore.batchInsert("test", valueBucketArray); + expect(1000).assertEqual(rowId); + } catch (error) { + console.error(TAG + `insert fail, code:${error.code}, message: ${error.message}`); + expect().assertFail(); + done(); + } + console.info(TAG + "************* testRdbStoreStatistics0004 end *************"); + }) + + /** + * @tc.name Normal case for Statistics insert data execution time to new table + * @tc.number testRdbStoreStatistics0005 + * @tc.desc 1. Register callback for statistics + * 2. Create table test1 + * 3. Insert data into table test1 + * 4. UnRegister callback + */ + it('testRdbStoreStatistics0005', 0, async function (done) { + console.info(TAG + "************* testRdbStoreStatistics0005 start *************"); + const CREATE_TABLE_SQL = "CREATE TABLE IF NOT EXISTS test1 (" + + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + + "name TEXT NOT NULL, " + "age INTEGER, " + "salary REAL, " + "blobType BLOB)"; + try { + rdbStore.on('statistics', (SqlExeInfo) => { + expect(CREATE_TABLE_SQL).assertEqual(SqlExeInfo.sql[0]); + done() + }) + } catch (err) { + console.error(TAG + `register fail, code:${err.code}, message: ${err.message}`); + expect().assertFail(); + done(); + } + try { + await rdbStore.executeSql(CREATE_TABLE_SQL); + const valueBucket = { + "name": "zhangsan", + "age": 18, + "salary": 100.5, + "blobType": new Uint8Array([1, 2, 3]), + } + let rowId = await rdbStore.insert("test1", valueBucket); + expect(1).assertEqual(rowId); + await rdbStore.executeSql("drop table test1"); + } catch (error) { + console.error(TAG + `insert fail, code:${error.code}, message: ${error.message}`); + expect().assertFail(); + done(); + } + console.info(TAG + "************* testRdbStoreStatistics0005 end *************"); + }) + + /** + * @tc.name AbNormal case for failed to insert + * @tc.number testRdbStoreStatistics0006 + * @tc.desc 1. Register callback for statistics + * 2. Failed to insert data into table test + * 3. UnRegister callback + */ + it('testRdbStoreStatistics0006', 0, async function (done) { + console.info(TAG + "************* testRdbStoreStatistics0006 start *************"); + try { + rdbStore.on('statistics', (SqlExeInfo) => { + expect().assertFail(); + done(); + }) + } catch (err) { + console.error(TAG + `register fail, code:${err.code}, message: ${err.message}`); + expect().assertFail(); + done(); + } + + try { + const valueBucket = { + "age": 18, + "salary": 100.5, + "blobType": new Uint8Array([1, 2, 3]), + } + await rdbStore.insert("test", valueBucket); + expect().assertFail(); + } catch (error) { + expect(14800032).assertEqual(error.code); + console.error(TAG + `insert fail, code:${error.code}, message: ${error.message}`); + done(); + } + console.info(TAG + "************* testRdbStoreStatistics0006 end *************"); + }) + + /** + * @tc.name AbNormal case for function on, if args is invalid + * @tc.number testRdbStoreStatistics0007 + * @tc.desc 1.Register callback for statistics, event is invalid + */ + it('testRdbStoreStatistics0007', 0, async function (done) { + console.info(TAG + "************* testRdbStoreStatistics0007 start *************"); + try { + rdbStore.on('', (SqlExeInfo) => { + }) + expect().assertFail(); + } catch (err) { + console.error(TAG + `register fail, code:${err.code}, message: ${err.message}`); + expect('401').assertEqual(err.code); + done(); + } + console.info(TAG + "************* testRdbStoreStatistics0007 end *************"); + }) + + /** + * @tc.name AbNormal case for function off, if args is invalid + * @tc.number testRdbStoreStatistics0008 + * @tc.desc 1.Register callback statistics, event is invalid + */ + it('testRdbStoreStatistics0008', 0, async function (done) { + console.info(TAG + "************* testRdbStoreStatistics0008 start *************"); + try { + rdbStore.off('', (SqlExeInfo) => { + }) + expect().assertFail(); + } catch (err) { + console.error(TAG + `register fail, code:${err.code}, message: ${err.message}`); + expect('401').assertEqual(err.code); + done(); + } + console.info(TAG + "************* testRdbStoreStatistics0008 end *************"); + }) + + /** + * @tc.name Normal case for multi observer + * @tc.number testRdbStoreStatistics0009 + * @tc.desc 1. Register observer1 and observer2 for local database + * 2. Insert data into table test + * 3. UnRegister observer1 and observer2 + */ + it('testRdbStoreStatistics0009', 0, async function (done) { + console.info(TAG + "************* testRdbStoreStatistics0009 start *************"); + function observer1(SqlExeInfo) { + console.info(TAG + "observer1"); + expect().assertFail(); + }; + function observer2(SqlExeInfo) { + console.info(TAG + "observer2"); + expect('INSERT INTO test(age,blobType,name,salary) VALUES (?,?,?,?)').assertEqual(SqlExeInfo.sql[SqlExeInfo.sql.length - 1]); + done(); + }; + try { + rdbStore.on('statistics', observer1); + rdbStore.on('statistics', observer2); + } catch (err) { + console.error(TAG + `register fail, code:${err.code}, message: ${err.message}`); + expect().assertFail(); + done(); + } + try { + rdbStore.off('statistics', observer1); + } catch (err) { + expect().assertFail(); + console.error(TAG + `register fail, code:${err.code}, message: ${err.message}`); + done(); + } + try { + const valueBucket = { + 'name': 'liSi', + "age": 18, + "salary": 100.5, + "blobType": new Uint8Array([1, 2, 3]), + } + let rowId = await rdbStore.insert("test", valueBucket); + expect(2).assertEqual(rowId); + } catch (error) { + expect().assertFail(); + console.error(TAG + `insert fail, code:${error.code}, message: ${error.message}`); + done(); + } + console.info(TAG + "************* testRdbStoreStatistics0009 end *************"); + }) + + /** + * @tc.name Normal case for multi observer + * @tc.number testRdbStoreStatistics0010 + * @tc.desc 1. Register observer1 and observer2 for local database + * 2. Insert data into table test + * 3. UnRegister observer1 and observer2 + */ + it('testRdbStoreStatistics0010', 0, async function (done) { + console.info(TAG + "************* testRdbStoreStatistics0010 start *************"); + function observer1(SqlExeInfo) { + console.info(TAG + "observer1"); + expect('INSERT INTO test(age,blobType,name,salary) VALUES (?,?,?,?)').assertEqual(SqlExeInfo.sql[SqlExeInfo.sql.length - 1]); + }; + function observer2(SqlExeInfo) { + console.info(TAG + "observer2"); + expect('INSERT INTO test(age,blobType,name,salary) VALUES (?,?,?,?)').assertEqual(SqlExeInfo.sql[SqlExeInfo.sql.length - 1]); + done(); + }; + try { + rdbStore.on('statistics', observer1); + rdbStore.on('statistics', observer2); + } catch (err) { + console.error(TAG + `register fail, code:${err.code}, message: ${err.message}`); + expect().assertFail(); + done(); + } + try { + const valueBucket = { + 'name': 'liSi', + "age": 18, + "salary": 100.5, + "blobType": new Uint8Array([1, 2, 3]), + } + let rowId = await rdbStore.insert("test", valueBucket); + expect(2).assertEqual(rowId); + } catch (error) { + expect().assertFail(); + console.error(TAG + `insert fail, code:${error.code}, message: ${error.message}`); + done(); + } + console.info(TAG + "************* testRdbStoreStatistics0010 end *************"); + }) + + /** + * @tc.name Normal case for multi observer + * @tc.number testRdbStoreStatistics0012 + * @tc.desc 1. Register observer1 local database + * 2. query data into table test + * + */ + it('testRdbStoreStatistics0011', 0, async function (done) { + console.info(TAG + "************* testRdbStoreStatistics0011 start *************"); + try { + rdbStore.on('statistics', (SqlExeInfo) => { + expect('select * from test').assertEqual(SqlExeInfo.sql[0]); + done(); + }) + } catch (err) { + console.error(TAG + `on statistics fail, code:${err.code}, message: ${err.message}`); + expect().assertFail(); + done(); + } + await rdbStore.queryByStep("select * from test"); + console.info(TAG + "************* testRdbStoreStatistics0011 end *************"); + }) + + /** + * @tc.name Normal case for multi observer + * @tc.number testRdbStoreStatistics0012 + * @tc.desc 1. Register observer1 local database + * 2. query data into table test + * + */ + it('testRdbStoreStatistics0012', 0, async function (done) { + console.info(TAG + "************* testRdbStoreStatistics0012 start *************"); + try { + rdbStore.on('statistics', (SqlExeInfo) => { + expect('SELECT * FROM test').assertEqual(SqlExeInfo.sql[0]); + done(); + }) + } catch (err) { + console.error(TAG + `on statistics fail, code:${err.code}, message: ${err.message}`); + expect().assertFail(); + done(); + } + let predicates = new relationalStore.RdbPredicates('test'); + await rdbStore.query(predicates); + console.info(TAG + "************* testRdbStoreStatistics0012 end *************"); + }) + + /** + * @tc.name Normal case for multi observer + * @tc.number testRdbStoreStatistics0012 + * @tc.desc 1. Register observer1 local database + * 2. query data into table test + * + */ + it('testRdbStoreStatistics0013', 0, async function (done) { + console.info(TAG + "************* testRdbStoreStatistics0013 start *************"); + try { + rdbStore.on('statistics', (SqlExeInfo) => { + expect('select * from test').assertEqual(SqlExeInfo.sql[0]); + done(); + }) + } catch (err) { + console.error(TAG + `on statistics fail, code:${err.code}, message: ${err.message}`); + expect().assertFail(); + done(); + } + + await rdbStore.querySql("select * from test"); + console.info(TAG + "************* testRdbStoreStatistics0013 end *************"); + }) + + /** + * @tc.name Normal case for multi observer + * @tc.number testRdbStoreStatistics0012 + * @tc.desc 1. Register observer1 local database + * 2. query data into table test + * + */ + it('testRdbStoreStatistics0014', 0, async function (done) { + console.info(TAG + "************* testRdbStoreStatistics0014 start *************"); + try { + rdbStore.on('statistics', (SqlExeInfo) => { + expect('PRAGMA quick_check').assertEqual(SqlExeInfo.sql[0]); + done(); + }) + } catch (err) { + console.error(TAG + `on statistics fail, code:${err.code}, message: ${err.message}`); + expect().assertFail(); + done(); + } + let ret = await rdbStore.execute("PRAGMA quick_check"); + console.info(TAG + "************* testRdbStoreStatistics0014 end *************"); + }) + + /** + * @tc.name Normal case for Statistics query data execution time + * @tc.number testRdbStoreStatistics0016 + * @tc.desc 1. Register callback for statistics + * 2. query data into table test + * + */ + it('testRdbStoreStatistics0015', 0, async function (done) { + console.info(TAG + "************* testRdbStoreStatistics0016 start *************"); + try { + rdbStore.on('statistics', (SqlExeInfo) => { + expect('with test1 as (select * from test) select * from test').assertEqual(SqlExeInfo.sql[0]); + done(); + }) + } catch (err) { + console.error(TAG + `on statistics fail, code:${err.code}, message: ${err.message}`); + expect().assertFail(); + done(); + } + let ret = await rdbStore.executeSql("with test1 as (select * from test) select * from test"); + console.info(TAG + "************* testRdbStoreStatistics0015 end *************"); + }) + + /** + * @tc.name AbNormal case for Statistics when store is closed + * @tc.number testRdbStoreStatistics0016 + * @tc.desc 1. close store + * 2. Register callback for statistics + * + */ + it('testRdbStoreStatistics0016', 0, async function () { + console.info(TAG + "************* testRdbStoreStatistics0016 start *************"); + await rdbStore.close().then(() => { + console.info(`close succeeded`); + }).catch((err) => { + console.error(`close failed, code is ${err.code},message is ${err.message}`); + }) + + try { + rdbStore.on('statistics', (SqlExeInfo) => { + }) + } catch (err) { + console.error(TAG + `on statistics fail, code:${err.code}, message: ${err.message}`); + expect('14800014').assertEqual(err.code); + } + console.info(TAG + "************* testRdbStoreStatistics0016 end *************"); + }) + console.info(TAG + "*************Unit Test End*************"); +}) \ No newline at end of file diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbstoreEncryptionJsunit.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbstoreEncryptionJsunit.test.js index 11520bd4..fea83dfa 100644 --- a/relational_store/test/js/relationalstore/unittest/src/RdbstoreEncryptionJsunit.test.js +++ b/relational_store/test/js/relationalstore/unittest/src/RdbstoreEncryptionJsunit.test.js @@ -193,7 +193,7 @@ describe('rdbEncryptTest', function () { rdbStore = await CreatRdbStore(context, STORE_CONFIG_WRONG) expect(false).assertTrue() } catch (err) { - expect(err.code).assertEqual(14800017); + expect(err.code).assertEqual(14800011); } await console.log(TAG + "************* RdbEncryptTest_0040 end *************") diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbstoreInsertJsunit.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbstoreInsertJsunit.test.js index 6c129982..91d8ac00 100644 --- a/relational_store/test/js/relationalstore/unittest/src/RdbstoreInsertJsunit.test.js +++ b/relational_store/test/js/relationalstore/unittest/src/RdbstoreInsertJsunit.test.js @@ -27,6 +27,7 @@ const STORE_CONFIG = { } var rdbStore = undefined +var rdbStore1 = undefined var context = ability_featureAbility.getContext() describe('rdbStoreInsertTest', function () { @@ -451,6 +452,42 @@ describe('rdbStoreInsertTest', function () { console.log(TAG + "************* testRdbStoreInsert0009 end *************"); }) + /** + * @tc.number SUB_DDM_AppDataFWK_JSRDB_Insert_0010 + * @tc.name Abnormal test case of insert, if store is closed + * @tc.desc 1.close store + * 2.Execute insert + */ + it('testRdbStoreInsert0010', 0, async function () { + console.log(TAG + "************* testRdbStoreInsert0010 start *************"); + const STORE_CONFIG1 = { + name: "InsertTest1.db", + securityLevel: data_relationalStore.SecurityLevel.S1, + }; + rdbStore1 = await data_relationalStore.getRdbStore(context, STORE_CONFIG1); + await rdbStore1.executeSql(CREATE_TABLE_TEST, null); + await rdbStore1.close().then(() => { + console.info(`close succeeded`); + }).catch((err) => { + console.error(`close failed, code is ${err.code},message is ${err.message}`); + }) + + var u8 = new Uint8Array([1, 2, 3]) + const valueBucket = { + "name": "zhangsan", + "age": new Date(), + "salary": 100.5, + "blobType": u8, + } + try { + await rdbStore1.insert("test", valueBucket) + } catch (err) { + console.log("catch err: failed, err: code=" + err.code + " message=" + err.message) + expect("14800014").assertEqual(err.code) + } + await data_relationalStore.deleteRdbStore(context, "InsertTest1.db"); + console.log(TAG + "************* testRdbStoreInsert0010 end *************"); + }) /** * @tc.number SUB_DDM_AppDataFWK_JSRDB_InsertWithConflictResolution_0001 diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbstoreInsertSyncJsUnit.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbstoreInsertSyncJsUnit.test.js index dde37e1a..0df64ff1 100644 --- a/relational_store/test/js/relationalstore/unittest/src/RdbstoreInsertSyncJsUnit.test.js +++ b/relational_store/test/js/relationalstore/unittest/src/RdbstoreInsertSyncJsUnit.test.js @@ -27,6 +27,7 @@ const STORE_CONFIG = { } var rdbStore = undefined +var rdbStore1 = undefined var context = ability_featureAbility.getContext() describe('rdbStoreInsertSyncTest', function () { @@ -438,6 +439,42 @@ describe('rdbStoreInsertSyncTest', function () { console.log(TAG + "************* testSyncRdbStoreInsert0009 end *************"); }) + /** + * @tc.number SUB_DDM_AppDataFWK_JSRDB_Insert_0010 + * @tc.name Abnormal test case of insert, if store is closed + * @tc.desc 1.close store + * 2.Execute insert + */ + it('testSyncRdbStoreInsert0010', 0, async function (done) { + console.log(TAG + "************* testSyncRdbStoreInsert0010 start *************"); + const STORE_CONFIG1 = { + name: "InsertTest1.db", + securityLevel: data_relationalStore.SecurityLevel.S1, + }; + rdbStore1 = await data_relationalStore.getRdbStore(context, STORE_CONFIG1); + await rdbStore1.executeSql(CREATE_TABLE_TEST, null); + await rdbStore1.close().then(() => { + console.info(`close succeeded`); + }).catch((err) => { + console.error(`close failed, code is ${err.code},message is ${err.message}`); + }) + var u8 = new Uint8Array([1, 2, 3]) + const valueBucket = { + "name": "zhangsan", + "age": new Date(), + "salary": 100.5, + "blobType": u8, + } + try { + rdbStore1.insertSync("test", valueBucket) + } catch (err) { + console.log("catch err: failed, err: code=" + err.code + " message=" + err.message) + expect("14800014").assertEqual(err.code) + done(); + } + await data_relationalStore.deleteRdbStore(context, "InsertTest1.db"); + console.log(TAG + "************* testSyncRdbStoreInsert0010 end *************"); + }) /** * @tc.number SUB_DDM_AppDataFWK_JSRDB_InsertWithConflictResolutionSync_0001 diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbstoreLockRowJsunit.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbstoreLockRowJsunit.test.js index bfe39045..223a5817 100644 --- a/relational_store/test/js/relationalstore/unittest/src/RdbstoreLockRowJsunit.test.js +++ b/relational_store/test/js/relationalstore/unittest/src/RdbstoreLockRowJsunit.test.js @@ -230,7 +230,7 @@ describe('rdbStoreLockRowTest', function () { expect().assertFail() } catch (err) { console.log(TAG + `wrongTable failed, err: ${JSON.stringify(err)}`) - expect(14800000).assertEqual(err.code) + expect(14800018).assertEqual(err.code) } try { let predicates = new data_relationalStore.RdbPredicates(TABLE) @@ -239,7 +239,7 @@ describe('rdbStoreLockRowTest', function () { expect().assertFail() } catch (err) { console.log(TAG + `aaa failed, err: ${JSON.stringify(err)}`) - expect(14800000).assertEqual(err.code) + expect(14800018).assertEqual(err.code) } try { let predicates = new data_relationalStore.RdbPredicates(TABLE) @@ -278,7 +278,7 @@ describe('rdbStoreLockRowTest', function () { expect().assertFail() } catch (err) { console.log(TAG + `wrongTable failed, err: ${JSON.stringify(err)}`) - expect(14800000).assertEqual(err.code) + expect(14800018).assertEqual(err.code) } try { let predicates = new data_relationalStore.RdbPredicates(TABLE) @@ -287,7 +287,7 @@ describe('rdbStoreLockRowTest', function () { expect().assertFail() } catch (err) { console.log(TAG + `aaa failed, err: ${JSON.stringify(err)}`) - expect(14800000).assertEqual(err.code) + expect(14800018).assertEqual(err.code) } try { let predicates = new data_relationalStore.RdbPredicates(TABLE) diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbstorePredicatesJsunit.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbstorePredicatesJsunit.test.js index 3357ec3c..f56825a8 100644 --- a/relational_store/test/js/relationalstore/unittest/src/RdbstorePredicatesJsunit.test.js +++ b/relational_store/test/js/relationalstore/unittest/src/RdbstorePredicatesJsunit.test.js @@ -34,6 +34,55 @@ const STORE_CONFIG = { var rdbStore = undefined var context = ability_featureAbility.getContext() var DOUBLE_MAX = 9223372036854775807; +var u8 = new Uint8Array([1, 2, 3]) +const valueBucket1 = { + "integerValue": 2147483647, + "doubleValue": DOUBLE_MAX, + "booleanValue": true, + "floatValue": -0.123, + "longValue": 9223372036854775807, + "shortValue": 32767, + "characterValue": ' ', + "stringValue": "ABCDEFGHIJKLMN", + "blobValue": u8, + "byteValue": 127, +} +const valueBucket2 = { + "integerValue": 1, + "doubleValue": 1.0, + "booleanValue": false, + "floatValue": 1.0, + "longValue": 1, + "shortValue": 1, + "characterValue": '中', + "stringValue": "ABCDEFGHIJKLMN", + "blobValue": u8, + "byteValue": 1, +} +const valueBucket3 = { + "integerValue": -2147483648, + "doubleValue": Number.MIN_VALUE, + "booleanValue": false, + "floatValue": 0.1234567, + "longValue": -9223372036854775808, + "shortValue": -32768, + "characterValue": '#', + "stringValue": "ABCDEFGHIJKLMN", + "blobValue": u8, + "byteValue": -128, +} +const valueBucket4 = { + "integerValue": -2147483648, + "doubleValue": Number.MIN_VALUE, + "booleanValue": false, + "floatValue": 0.1234567, + "longValue": -9223372036854775808, + "shortValue": -32768, + "characterValue": '#', + "stringValue": "OPQRST", + "blobValue": u8, + "byteValue": -128, +} describe('rdbPredicatesTest', function () { beforeAll(async function () { console.info(TAG + 'beforeAll') @@ -60,62 +109,17 @@ describe('rdbPredicatesTest', function () { async function buildAllDataType1() { console.log(TAG + "buildAllDataType1 start"); - { - var u8 = new Uint8Array([1, 2, 3]) - const valueBucket = { - "integerValue": 2147483647, - "doubleValue": DOUBLE_MAX, - "booleanValue": true, - "floatValue": -0.123, - "longValue": 9223372036854775807, - "shortValue": 32767, - "characterValue": ' ', - "stringValue": "ABCDEFGHIJKLMN", - "blobValue": u8, - "byteValue": 127, - } - await rdbStore.insert("AllDataType", valueBucket) - } + await rdbStore.insert("AllDataType", valueBucket1) } async function buildAllDataType2() { console.log(TAG + "buildAllDataType2 start"); - { - var u8 = new Uint8Array([1, 2, 3]) - const valueBucket = { - "integerValue": 1, - "doubleValue": 1.0, - "booleanValue": false, - "floatValue": 1.0, - "longValue": 1, - "shortValue": 1, - "characterValue": '中', - "stringValue": "ABCDEFGHIJKLMN", - "blobValue": u8, - "byteValue": 1, - } - await rdbStore.insert("AllDataType", valueBucket) - } + await rdbStore.insert("AllDataType", valueBucket2) } async function buildAllDataType3() { console.log(TAG + "buildAllDataType3 start"); - { - var u8 = new Uint8Array([1, 2, 3]) - const valueBucket = { - "integerValue": -2147483648, - "doubleValue": Number.MIN_VALUE, - "booleanValue": false, - "floatValue": 0.1234567, - "longValue": -9223372036854775808, - "shortValue": -32768, - "characterValue": '#', - "stringValue": "ABCDEFGHIJKLMN", - "blobValue": u8, - "byteValue": -128, - } - await rdbStore.insert("AllDataType", valueBucket) - } + await rdbStore.insert("AllDataType", valueBucket3) } console.log(TAG + "*************Unit Test Begin*************"); @@ -2933,20 +2937,7 @@ describe('rdbPredicatesTest', function () { expect(2).assertEqual(result.rowCount); result.close() result = null - var u8 = new Uint8Array([1, 2, 3]) - const valueBucket = { - "integerValue": -2147483648, - "doubleValue": Number.MIN_VALUE, - "booleanValue": false, - "floatValue": 0.1234567, - "longValue": -9223372036854775808, - "shortValue": -32768, - "characterValue": '#', - "stringValue": "OPQRST", - "blobValue": u8, - "byteValue": -128, - } - await rdbStore.insert("AllDataType", valueBucket) + await rdbStore.insert("AllDataType", valueBucket4) let predicatesInsert = new data_relationalStore.RdbPredicates("AllDataType"); predicatesInsert.notLike("characterValue", "#"); result = await rdbStore.query(predicatesInsert); @@ -2978,42 +2969,17 @@ describe('rdbPredicatesTest', function () { expect(2).assertEqual(result.rowCount); result.close() result = null - var u8 = new Uint8Array([1, 2, 3]) - const valueBucket = { - "integerValue": -2147483648, - "doubleValue": Number.MIN_VALUE, - "booleanValue": false, - "floatValue": 0.1234567, - "longValue": -9223372036854775808, - "shortValue": -32768, - "characterValue": '#', - "stringValue": "OPQRST", - "blobValue": u8, - "byteValue": -128, - } predicates.equalTo("characterValue", "中"); - await rdbStore.update(valueBucket, predicates); + await rdbStore.update(valueBucket4, predicates); let predicatesUpdate = new data_relationalStore.RdbPredicates("AllDataType"); predicatesUpdate.notLike("characterValue", "#"); result = await rdbStore.query(predicatesUpdate); expect(1).assertEqual(result.rowCount); - const valueBucketBefore = { - "integerValue": 1, - "doubleValue": 1.0, - "booleanValue": false, - "floatValue": 1.0, - "longValue": 1, - "shortValue": 1, - "characterValue": '中', - "stringValue": "ABCDEFGHIJKLMN", - "blobValue": u8, - "byteValue": 1, - } result.close(); result = null; let predicatesBefore = new data_relationalStore.RdbPredicates("AllDataType"); predicatesBefore.equalTo("stringValue", "OPQRST"); - await rdbStore.update(valueBucketBefore, predicatesBefore); + await rdbStore.update(valueBucket2, predicatesBefore); done(); console.log(TAG + "************* testNotLike0007 end *************"); }) @@ -3044,20 +3010,7 @@ describe('rdbPredicatesTest', function () { expect(1).assertEqual(result.rowCount); result.close(); result = null; - var u8 = new Uint8Array([1, 2, 3]); - const valueBucketBefore = { - "integerValue": 1, - "doubleValue": 1.0, - "booleanValue": false, - "floatValue": 1.0, - "longValue": 1, - "shortValue": 1, - "characterValue": '中', - "stringValue": "ABCDEFGHIJKLMN", - "blobValue": u8, - "byteValue": 1, - } - await rdbStore.insert("AllDataType", valueBucketBefore); + await rdbStore.insert("AllDataType", valueBucket2); done(); console.log(TAG + "************* testNotLike0008 end *************"); }) @@ -3185,20 +3138,7 @@ describe('rdbPredicatesTest', function () { expect(2).assertEqual(result.rowCount); result.close() result = null - var u8 = new Uint8Array([1, 2, 3]) - const valueBucket = { - "integerValue": -2147483648, - "doubleValue": Number.MIN_VALUE, - "booleanValue": false, - "floatValue": 0.1234567, - "longValue": -9223372036854775808, - "shortValue": -32768, - "characterValue": '#', - "stringValue": "OPQRST", - "blobValue": u8, - "byteValue": -128, - } - await rdbStore.insert("AllDataType", valueBucket) + await rdbStore.insert("AllDataType", valueBucket4) let predicatesInsert = new data_relationalStore.RdbPredicates("AllDataType"); predicatesInsert.notContains("characterValue", "#"); result = await rdbStore.query(predicatesInsert); @@ -3230,42 +3170,17 @@ describe('rdbPredicatesTest', function () { expect(2).assertEqual(result.rowCount); result.close(); result = null; - var u8 = new Uint8Array([1, 2, 3]) - const valueBucket = { - "integerValue": -2147483648, - "doubleValue": Number.MIN_VALUE, - "booleanValue": false, - "floatValue": 0.1234567, - "longValue": -9223372036854775808, - "shortValue": -32768, - "characterValue": '#', - "stringValue": "OPQRST", - "blobValue": u8, - "byteValue": -128, - } predicates.equalTo("characterValue", "中") - await rdbStore.update(valueBucket, predicates) + await rdbStore.update(valueBucket4, predicates) let predicatesUpdate = new data_relationalStore.RdbPredicates("AllDataType"); predicatesUpdate.notContains("characterValue", "#"); result = await rdbStore.query(predicatesUpdate); expect(1).assertEqual(result.rowCount); result.close(); result = null; - const valueBucketBefore = { - "integerValue": 1, - "doubleValue": 1.0, - "booleanValue": false, - "floatValue": 1.0, - "longValue": 1, - "shortValue": 1, - "characterValue": '中', - "stringValue": "ABCDEFGHIJKLMN", - "blobValue": u8, - "byteValue": 1, - } let predicatesBefore = new data_relationalStore.RdbPredicates("AllDataType"); predicatesBefore.equalTo("stringValue", "OPQRST"); - await rdbStore.update(valueBucketBefore, predicatesBefore); + await rdbStore.update(valueBucket2, predicatesBefore); done(); console.log(TAG + "************* testNotContains0007 end *************"); }) @@ -3296,20 +3211,7 @@ describe('rdbPredicatesTest', function () { expect(1).assertEqual(result.rowCount); result.close(); result = null; - var u8 = new Uint8Array([1, 2, 3]); - const valueBucketBefore = { - "integerValue": 1, - "doubleValue": 1.0, - "booleanValue": false, - "floatValue": 1.0, - "longValue": 1, - "shortValue": 1, - "characterValue": '中', - "stringValue": "ABCDEFGHIJKLMN", - "blobValue": u8, - "byteValue": 1, - } - await rdbStore.insert("AllDataType", valueBucketBefore); + await rdbStore.insert("AllDataType", valueBucket2); done(); console.log(TAG + "************* testNotContains0008 end *************"); }) diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbstoreStoreExcuteSqlJsunit.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbstoreStoreExcuteSqlJsunit.test.js index 0e643abc..ec28f390 100644 --- a/relational_store/test/js/relationalstore/unittest/src/RdbstoreStoreExcuteSqlJsunit.test.js +++ b/relational_store/test/js/relationalstore/unittest/src/RdbstoreStoreExcuteSqlJsunit.test.js @@ -287,5 +287,56 @@ describe('rdbStoreExcuteSqlTest', function () { console.log(TAG + "************* ExcuteSqlTest0004 end *************"); }) + /** + * @tc.number SUB_DDM_AppDataFWK_JSRDB_ExcuteSql_0050 + * @tc.name Normal test case of excuteSql and querySql, PRAGMA user_version + * @tc.desc 1.Set user_version + * 2.Get user_version + */ + it('ExcuteSqlTest0005', 0, async function () { + console.log(TAG + "************* ExcuteSqlTest0005 start *************"); + // 2 is used to set the store version + await rdbStore.executeSql("PRAGMA user_version = 2") + let resultSet = await rdbStore.querySql("PRAGMA user_version"); + resultSet.goToFirstRow(); + expect(2).assertEqual(resultSet.getLong(0)) + resultSet.close(); + console.log(TAG + "************* ExcuteSqlTest0005 end *************"); + }) + + /** + * @tc.number SUB_DDM_AppDataFWK_JSRDB_ExcuteSql_0060 + * @tc.name Normal test case of excuteSql and querySql, PRAGMA table_info + * @tc.desc 1.Get table_info + * 2.Check table_info + */ + it('ExcuteSqlTest0006', 0, async function () { + console.log(TAG + "************* ExcuteSqlTest0006 start *************"); + let resultSet = await rdbStore.querySql("PRAGMA table_info(test)"); + resultSet.goToFirstRow(); + expect(0).assertEqual(resultSet.getLong(0)) + expect("id").assertEqual(resultSet.getString(1)) + expect("INTEGER").assertEqual(resultSet.getString(2)) + resultSet.goToNextRow(); + expect(1).assertEqual(resultSet.getLong(0)) + expect("name").assertEqual(resultSet.getString(1)) + expect("TEXT").assertEqual(resultSet.getString(2)) + expect(1).assertEqual(resultSet.getLong(3)) + resultSet.goToNextRow(); + expect(2).assertEqual(resultSet.getLong(0)) + expect("age").assertEqual(resultSet.getString(1)) + expect("INTEGER").assertEqual(resultSet.getString(2)) + resultSet.goToNextRow(); + expect(3).assertEqual(resultSet.getLong(0)) + expect("salary").assertEqual(resultSet.getString(1)) + expect("REAL").assertEqual(resultSet.getString(2)) + resultSet.goToNextRow(); + expect(4).assertEqual(resultSet.getLong(0)) + expect("blobType").assertEqual(resultSet.getString(1)) + expect("BLOB").assertEqual(resultSet.getString(2)) + resultSet.close(); + console.log(TAG + "************* ExcuteSqlTest0006 end *************"); + }) + console.log(TAG + "*************Unit Test End*************"); }) \ No newline at end of file diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbstoreStoreExcuteSyncJsunit.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbstoreStoreExcuteSyncJsunit.test.js index d6f5a969..1c136bc0 100644 --- a/relational_store/test/js/relationalstore/unittest/src/RdbstoreStoreExcuteSyncJsunit.test.js +++ b/relational_store/test/js/relationalstore/unittest/src/RdbstoreStoreExcuteSyncJsunit.test.js @@ -42,13 +42,13 @@ describe('rdbStoreExcuteTest', function () { }) beforeEach(async function () { - rdbStore.executeSql(CREATE_TABLE_TEST); + await rdbStore.executeSql(CREATE_TABLE_TEST); console.info(TAG + 'beforeEach') }) afterEach(async function () { console.info(TAG + 'afterEach') - rdbStore.executeSql("DROP TABLE IF EXISTS test") + await rdbStore.executeSql("DROP TABLE IF EXISTS test") }) afterAll(async function () { diff --git a/relational_store/test/native/appdatafwk/BUILD.gn b/relational_store/test/native/appdatafwk/BUILD.gn new file mode 100644 index 00000000..46046cf6 --- /dev/null +++ b/relational_store/test/native/appdatafwk/BUILD.gn @@ -0,0 +1,56 @@ +# Copyright (c) 2024 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import("//build/test.gni") +import("//foundation/distributeddatamgr/relational_store/relational_store.gni") + +module_output_path = "relational_store/native_appdatafwk" + +############################################################################### +config("module_private_config") { + visibility = [ ":*" ] + + include_dirs = [ + "${relational_store_native_path}/appdatafwk/include", + "${relational_store_innerapi_path}/appdatafwk/include", + "${relational_store_innerapi_path}/rdb/include", + "${relational_store_innerapi_path}/rdb/src", + ] +} + +ohos_unittest("NativeAppDataFwkTest") { + module_out_path = module_output_path + + sources = [ "unittest/serializable_test.cpp" ] + + configs = [ ":module_private_config" ] + + external_deps = [ + "hilog:libhilog", + "relational_store:native_appdatafwk", + ] + + deps = [ + "${relational_store_innerapi_path}/appdatafwk:native_appdatafwk", + "${relational_store_innerapi_path}/appdatafwk:relational_common_base", + "${relational_store_innerapi_path}/rdb:native_rdb", + "//third_party/googletest:gtest_main", + ] +} + +############################################################################### +group("unittest") { + testonly = true + + deps = [ ":NativeAppDataFwkTest" ] +} +############################################################################### diff --git a/relational_store/test/native/appdatafwk/unittest/serializable_test.cpp b/relational_store/test/native/appdatafwk/unittest/serializable_test.cpp new file mode 100644 index 00000000..958350f7 --- /dev/null +++ b/relational_store/test/native/appdatafwk/unittest/serializable_test.cpp @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define LOG_TAG "SerializableTest" +#include +#include "logger.h" +#include "serializable.h" +#include "gtest/gtest.h" + +using namespace testing::ext; +namespace OHOS::Test { +class SerializableTest : public testing::Test { +public: + struct Normal final : public Serializable { + public: + std::string name = "Test"; + int32_t count = 0; + uint32_t status = 1; + int64_t value = 2; + bool isClear = false; + std::vector cols{ "123", "345", "789" }; + std::vector> colRow{ { 123, 345, 789 }, { 123, 345, 789 } }; + + bool Marshal(json &node) const override + { + SetValue(node[GET_NAME(name)], name); + SetValue(node[GET_NAME(count)], count); + SetValue(node[GET_NAME(status)], status); + SetValue(node[GET_NAME(value)], value); + SetValue(node[GET_NAME(isClear)], isClear); + SetValue(node[GET_NAME(cols)], cols); + SetValue(node[GET_NAME(colRow)], colRow); + return true; + } + bool Unmarshal(const json &node) override + { + GetValue(node, GET_NAME(name), name); + GetValue(node, GET_NAME(count), count); + GetValue(node, GET_NAME(status), status); + GetValue(node, GET_NAME(value), value); + GetValue(node, GET_NAME(isClear), isClear); + GetValue(node, GET_NAME(cols), cols); + GetValue(node, GET_NAME(colRow), colRow); + return true; + } + bool operator == (const Normal &ref) const + { + return name == ref.name && count == ref.count && status == ref.status && value == ref.value + && isClear == ref.isClear && cols == ref.cols; + } + }; + + struct NormalEx final : public Serializable { + public: + std::vector normals {Normal(), Normal()}; + Normal normal; + int32_t count = 123; + std::string name = "wdt"; + bool Marshal(json &node) const override + { + SetValue(node[GET_NAME(normals)], normals); + SetValue(node[GET_NAME(normal)], normal); + SetValue(node[GET_NAME(count)], count); + SetValue(node[GET_NAME(name)], name); + return true; + } + bool Unmarshal(const json &node) override + { + GetValue(node, GET_NAME(normals), normals); + GetValue(node, GET_NAME(normal), normal); + GetValue(node, GET_NAME(count), count); + GetValue(node, GET_NAME(name), name); + return true; + } + bool operator==(const NormalEx &normalEx) const + { + return normals == normalEx.normals && count == normalEx.count && name == normalEx.name; + } + }; + static void SetUpTestCase(void) + { + } + static void TearDownTestCase(void) + { + } + void SetUp() + { + Test::SetUp(); + } + void TearDown() + { + Test::TearDown(); + } + + template + static inline bool EqualPtr(const T *src, const T *target) + { + return (((src) == (target)) || ((src) != nullptr && (target) != nullptr && *(src) == *(target))); + } +}; + +/** +* @tc.name: SerializableSuiteGetVal +* @tc.desc: Get Value. +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SerializableTest, GetNormalVal, TestSize.Level2) +{ + Normal normal; + normal.name = "normal"; + normal.count = -1; + normal.status = 12; + normal.value = -56; + normal.isClear = true; + normal.cols = {"adfasdfas"}; + auto jstr = to_string(normal.Marshall()); + Normal normal1; + normal1.Unmarshall(jstr); + ASSERT_TRUE(normal == normal1) << normal1.name; +} + +/** +* @tc.name: Delete Serializable +* @tc.desc: can delete child class, but not delete parent class point. +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SerializableTest, DeleteSerializable, TestSize.Level2) +{ + ASSERT_FALSE(std::is_destructible::value); + ASSERT_TRUE(std::is_destructible::value); +} + +/** +* @tc.name: SerializableSuiteGetMutilVal +* @tc.desc: mutil value case. +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(SerializableTest, GetMutilVal, TestSize.Level2) +{ + NormalEx normalEx; + normalEx.normals = {Normal()}; + normalEx.name = "normalEx"; + auto jstr = to_string(normalEx.Marshall()); + NormalEx normal1; + normal1.Unmarshall(jstr); + ASSERT_TRUE(normalEx == normal1) << normal1.name; +} + +/** +* @tc.name: IsJson +* @tc.desc: is json. +* @tc.type: FUNC +*/ +HWTEST_F(SerializableTest, IsJson, TestSize.Level1) +{ + std::string str = "test"; + std::string jsonStr = "\"test\""; + ASSERT_FALSE(Serializable::IsJson(str)); + ASSERT_TRUE(Serializable::IsJson(jsonStr)); +} +} // namespace OHOS::Test \ No newline at end of file diff --git a/relational_store/test/native/clouddata/BUILD.gn b/relational_store/test/native/clouddata/BUILD.gn new file mode 100644 index 00000000..b1d17d72 --- /dev/null +++ b/relational_store/test/native/clouddata/BUILD.gn @@ -0,0 +1,75 @@ +# Copyright (c) 2024 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import("//build/test.gni") +import("//foundation/distributeddatamgr/relational_store/relational_store.gni") + +module_output_path = "relational_store/native_clouddata" + +############################################################################### +config("module_private_config") { + visibility = [ ":*" ] + + include_dirs = [ + "${cloud_data_native_path}/include", + "${relational_store_common_path}/include", + "${relational_store_innerapi_path}/cloud_data/include", + "${relational_store_innerapi_path}/common_type/include", + "${relational_store_innerapi_path}/rdb/include", + ] +} + +ohos_unittest("NativeCloudDataTest") { + module_out_path = module_output_path + + sources = [ + "${cloud_data_native_path}/src/cloud_manager.cpp", + "${cloud_data_native_path}/src/cloud_service_proxy.cpp", + "${cloud_data_native_path}/src/cloud_types_util.cpp", + "unittest/cloud_data_test.cpp", + ] + + configs = [ ":module_private_config" ] + + branch_protector_ret = "pac_ret" + sanitize = { + ubsan = true + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + } + + external_deps = [ + "access_token:libaccesstoken_sdk", + "access_token:libtoken_setproc", + "access_token:libtokenid_sdk", + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_core", + "kv_store:distributeddata_mgr", + "samgr:samgr_proxy", + ] + + deps = [ + "${relational_store_innerapi_path}/rdb:native_rdb", + "//third_party/googletest:gtest_main", + ] +} + +############################################################################### +group("unittest") { + testonly = true + + deps = [ ":NativeCloudDataTest" ] +} +############################################################################### diff --git a/relational_store/test/native/clouddata/unittest/cloud_data_test.cpp b/relational_store/test/native/clouddata/unittest/cloud_data_test.cpp new file mode 100644 index 00000000..fce7a1b3 --- /dev/null +++ b/relational_store/test/native/clouddata/unittest/cloud_data_test.cpp @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "accesstoken_kit.h" +#include "cloud_manager.h" +#include "logger.h" +#include "token_setproc.h" + +namespace OHOS::CloudData { +using namespace testing::ext; +using namespace OHOS::Security::AccessToken; +using namespace OHOS::Rdb; +uint64_t g_selfTokenID = 0; +static constexpr const char *TEST_BUNDLE_NAME = "bundleName"; +static constexpr const char *TEST_ACCOUNT_ID = "testId"; +static constexpr const char *TEST_STORE_ID = "storeId"; +void AllocSystemHapToken(const HapPolicyParams &policy) +{ + HapInfoParams info = { + .userID = 100, + .bundleName = "ohos.clouddatatest.demo", + .instIndex = 0, + .appIDDesc = "ohos.clouddatatest.demo", + .isSystemApp = true + }; + auto token = AccessTokenKit::AllocHapToken(info, policy); + SetSelfTokenID(token.tokenIDEx); +} + +void AllocNormalHapToken(const HapPolicyParams &policy) +{ + HapInfoParams info = { + .userID = 100, + .bundleName = "ohos.clouddatatest.demo", + .instIndex = 0, + .appIDDesc = "ohos.clouddatatest.demo", + .isSystemApp = false + }; + auto token = AccessTokenKit::AllocHapToken(info, policy); + SetSelfTokenID(token.tokenIDEx); +} + +HapPolicyParams g_normalPolicy = { + .apl = APL_NORMAL, + .domain = "test.domain", + .permList = { + { + .permissionName = "ohos.permission.CLOUDDATA_CONFIG", + .bundleName = "ohos.clouddatatest.demo", + .grantMode = 1, + .availableLevel = APL_NORMAL, + .label = "label", + .labelId = 1, + .description = "ohos.clouddatatest.demo", + .descriptionId = 1 + } + }, + .permStateList = { + { + .permissionName = "ohos.permission.CLOUDDATA_CONFIG", + .isGeneral = true, + .resDeviceID = { "local" }, + .grantStatus = { PermissionState::PERMISSION_GRANTED }, + .grantFlags = { 1 } + } + } +}; + +HapPolicyParams g_systemPolicy = { + .apl = APL_SYSTEM_BASIC, + .domain = "test.domain", + .permList = { + { + .permissionName = "ohos.permission.CLOUDDATA_CONFIG", + .bundleName = "ohos.clouddatatest.demo", + .grantMode = 1, + .availableLevel = APL_SYSTEM_BASIC, + .label = "label", + .labelId = 1, + .description = "ohos.clouddatatest.demo", + .descriptionId = 1 + } + }, + .permStateList = { + { + .permissionName = "ohos.permission.CLOUDDATA_CONFIG", + .isGeneral = true, + .resDeviceID = { "local" }, + .grantStatus = { PermissionState::PERMISSION_GRANTED }, + .grantFlags = { 1 } + } + } +}; + +HapPolicyParams g_notPermissonPolicy = { + .apl = APL_SYSTEM_BASIC, + .domain = "test.domain", + .permList = { + { + .permissionName = "ohos.permission.TEST", + .bundleName = "ohos.clouddatatest.demo", + .grantMode = 1, + .availableLevel = APL_SYSTEM_BASIC, + .label = "label", + .labelId = 1, + .description = "ohos.clouddatatest.demo", + .descriptionId = 1 + } + }, + .permStateList = { + { + .permissionName = "ohos.permission.TEST", + .isGeneral = true, + .resDeviceID = { "local" }, + .grantStatus = { PermissionState::PERMISSION_GRANTED }, + .grantFlags = { 1 } + } + } +}; + +class CloudDataTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp() + { + } + void TearDown() + { + SetSelfTokenID(g_selfTokenID); + } +}; + +void CloudDataTest::SetUpTestCase(void) +{ + g_selfTokenID = GetSelfTokenID(); +} + +void CloudDataTest::TearDownTestCase(void) +{ + SetSelfTokenID(g_selfTokenID); +} + +/* * + * @tc.name: CloudDataTest_001 + * @tc.desc: Test the system application permissions of the QueryStatistics API + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(CloudDataTest, CloudDataTest_001, TestSize.Level0) +{ + AllocNormalHapToken(g_normalPolicy); + auto [state, proxy] = CloudManager::GetInstance().GetCloudService(); + if (state != CloudService::SUCCESS) { + EXPECT_TRUE(false); + } else { + auto [status, info] = proxy->QueryStatistics(TEST_ACCOUNT_ID, TEST_BUNDLE_NAME, TEST_STORE_ID); + EXPECT_EQ(status, CloudService::PERMISSION_DENIED); + EXPECT_TRUE(info.empty()); + } +} + +/* * + * @tc.name: CloudDataTest_002 + * @tc.desc: Test the permissions of the QueryStatistics API + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(CloudDataTest, CloudDataTest_002, TestSize.Level0) +{ + AllocSystemHapToken(g_notPermissonPolicy); + auto [state, proxy] = CloudManager::GetInstance().GetCloudService(); + if (state != CloudService::SUCCESS) { + EXPECT_TRUE(false); + } else { + auto [status, info] = proxy->QueryStatistics(TEST_ACCOUNT_ID, TEST_BUNDLE_NAME, TEST_STORE_ID); + EXPECT_EQ(status, CloudService::CLOUD_CONFIG_PERMISSION_DENIED); + EXPECT_TRUE(info.empty()); + } +} + +/* * + * @tc.name: CloudDataTest_003 + * @tc.desc: Test the permissions of the QueryStatistics API + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(CloudDataTest, CloudDataTest_003, TestSize.Level0) +{ + AllocSystemHapToken(g_systemPolicy); + auto [state, proxy] = CloudManager::GetInstance().GetCloudService(); + if (state != CloudService::SUCCESS) { + EXPECT_TRUE(false); + } else { + auto [status, info] = proxy->QueryStatistics(TEST_ACCOUNT_ID, TEST_BUNDLE_NAME, TEST_STORE_ID); + EXPECT_EQ(status, CloudService::ERROR); + EXPECT_TRUE(info.empty()); + } +} + +/* * + * @tc.name: QueryLastSyncInfo001 + * @tc.desc: Test the system application permissions of the QueryLastSyncInfo API + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(CloudDataTest, QueryLastSyncInfo001, TestSize.Level0) +{ + AllocNormalHapToken(g_normalPolicy); + auto [state, proxy] = CloudManager::GetInstance().GetCloudService(); + if (state != CloudService::SUCCESS) { + EXPECT_TRUE(false); + } else { + auto [status, info] = proxy->QueryLastSyncInfo(TEST_ACCOUNT_ID, TEST_BUNDLE_NAME, TEST_STORE_ID); + EXPECT_EQ(status, CloudService::PERMISSION_DENIED); + EXPECT_TRUE(info.empty()); + } +} + +/* * + * @tc.name: QueryLastSyncInfo002 + * @tc.desc: Test the permission name of the QueryLastSyncInfo API + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(CloudDataTest, QueryLastSyncInfo002, TestSize.Level0) +{ + AllocSystemHapToken(g_notPermissonPolicy); + auto [state, proxy] = CloudManager::GetInstance().GetCloudService(); + if (state != CloudService::SUCCESS) { + EXPECT_TRUE(false); + } else { + auto [status, info] = proxy->QueryLastSyncInfo(TEST_ACCOUNT_ID, TEST_BUNDLE_NAME, TEST_STORE_ID); + EXPECT_EQ(status, CloudService::CLOUD_CONFIG_PERMISSION_DENIED); + EXPECT_TRUE(info.empty()); + } +} +} // namespace OHOS::CloudData \ No newline at end of file diff --git a/relational_store/test/native/rdb/BUILD.gn b/relational_store/test/native/rdb/BUILD.gn index 2efdcd81..2ae2a3ab 100644 --- a/relational_store/test/native/rdb/BUILD.gn +++ b/relational_store/test/native/rdb/BUILD.gn @@ -88,6 +88,7 @@ ohos_unittest("NativeRdbTest") { "unittest/rdb_predicates_join_b_test.cpp", "unittest/rdb_predicates_join_test.cpp", "unittest/rdb_predicates_test.cpp", + "unittest/rdb_read_only_test.cpp", "unittest/rdb_sqlite_shared_result_set_test.cpp", "unittest/rdb_step_result_get_row_test.cpp", "unittest/rdb_step_result_set_test.cpp", @@ -108,9 +109,14 @@ ohos_unittest("NativeRdbTest") { sources += [ "../../../frameworks/native/rdb/src/base_transaction.cpp", "../../../frameworks/native/rdb/src/connection.cpp", + "../../../frameworks/native/rdb/src/grd_api_manager.cpp", "../../../frameworks/native/rdb/src/raw_data_parser.cpp", + "../../../frameworks/native/rdb/src/rd_connection.cpp", + "../../../frameworks/native/rdb/src/rd_statement.cpp", + "../../../frameworks/native/rdb/src/rd_utils.cpp", "../../../frameworks/native/rdb/src/rdb_local_db_observer.cpp", "../../../frameworks/native/rdb/src/rdb_security_manager.cpp", + "../../../frameworks/native/rdb/src/rdb_sql_statistic.cpp", "../../../frameworks/native/rdb/src/result_set_proxy.cpp", "../../../frameworks/native/rdb/src/share_block.cpp", "../../../frameworks/native/rdb/src/shared_block_serializer_info.cpp", @@ -122,6 +128,7 @@ ohos_unittest("NativeRdbTest") { "../../../frameworks/native/rdb/src/sqlite_statement.cpp", "../../../frameworks/native/rdb/src/sqlite_utils.cpp", "../../../frameworks/native/rdb/src/string_utils.cpp", + "../../../frameworks/native/rdb/src/task_executor.cpp", ] configs = [ ":module_private_config" ] diff --git a/relational_store/test/native/rdb/unittest/rdb_delete_test.cpp b/relational_store/test/native/rdb/unittest/rdb_delete_test.cpp index 7319c255..82727377 100644 --- a/relational_store/test/native/rdb/unittest/rdb_delete_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_delete_test.cpp @@ -116,7 +116,7 @@ HWTEST_F(RdbDeleteTest, RdbStore_Delete_001, TestSize.Level1) store->QuerySql("SELECT * FROM test WHERE id = ?", std::vector{ "1" }); EXPECT_NE(resultSet, nullptr); ret = resultSet->GoToNextRow(); - EXPECT_EQ(ret, E_ERROR); + EXPECT_EQ(ret, E_ROW_OUT_RANGE); ret = resultSet->Close(); EXPECT_EQ(ret, E_OK); @@ -188,7 +188,7 @@ HWTEST_F(RdbDeleteTest, RdbStore_Delete_002, TestSize.Level1) std::shared_ptr resultSet = store->QuerySql("SELECT * FROM test"); EXPECT_NE(resultSet, nullptr); ret = resultSet->GoToNextRow(); - EXPECT_EQ(ret, E_ERROR); + EXPECT_EQ(ret, E_ROW_OUT_RANGE); ret = resultSet->Close(); EXPECT_EQ(ret, E_OK); } diff --git a/relational_store/test/native/rdb/unittest/rdb_predicates_test.cpp b/relational_store/test/native/rdb/unittest/rdb_predicates_test.cpp index d382d408..a3679713 100644 --- a/relational_store/test/native/rdb/unittest/rdb_predicates_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_predicates_test.cpp @@ -579,7 +579,7 @@ HWTEST_F(RdbStorePredicateTest, RdbStore_RdbPredicates_001, TestSize.Level1) std::shared_ptr allDataTypes = RdbStorePredicateTest::store->Query(predicates, columns); EXPECT_EQ(0, ResultSize(allDataTypes)); allDataTypes->Close(); - + // if predicates HasSpecificField predicates.OrderByAsc("#_number"); bool hasSpecificField = predicates.HasSpecificField(); @@ -2403,4 +2403,82 @@ HWTEST_F(RdbStorePredicateTest, RdbStore_GetStatement_GetBnidArgs_002, TestSize. std::shared_ptr resultSet = RdbStorePredicateTest::store->Query(predicates, columns); resultSet->GetRowCount(count); EXPECT_EQ(1, count); +} + +/* * + * @tc.name: RdbStore_GetString_001 + * @tc.desc: Normal testCase of RdbPredicates for GetString + * @tc.type: FUNC + * @tc.require: AR000FKD4F + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_GetString_001, TestSize.Level1) +{ + ValuesBucket values; + int64_t id; + values.PutInt("id", 1); + values.PutString("name", std::string("")); + values.PutInt("age", 18); + values.PutInt("REAL", 100); + int ret = store->Insert(id, "person", values); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(1, id); + + int errCode = 0; + int columnIndex = 0; + RdbPredicates predicates("person"); + predicates.EqualTo("name", ""); + std::vector columns; + std::shared_ptr resultSet = RdbStorePredicateTest::store->Query(predicates, columns); + EXPECT_EQ(1, ResultSize(resultSet)); + + ret = resultSet->GoToFirstRow(); + EXPECT_EQ(E_OK, ret); + + std::string name; + errCode = resultSet->GetColumnIndex("name", columnIndex); + EXPECT_EQ(errCode, E_OK); + ret = resultSet->GetString(columnIndex, name); + EXPECT_EQ(E_OK, ret); + EXPECT_EQ(name, ""); + resultSet->Close(); + + store->ExecuteSql("DELETE FROM person"); +} + +/* * + * @tc.name: RdbStore_GetString_002 + * @tc.desc: Normal testCase of RdbPredicates for GetString + * @tc.type: FUNC + * @tc.require: AR000FKD4F + */ +HWTEST_F(RdbStorePredicateTest, RdbStore_GetString_002, TestSize.Level1) +{ + ValuesBucket values; + int64_t id; + values.Clear(); + values.PutInt("id", 1); + values.PutString("name", std::string("")); + values.PutInt("age", 18); + values.PutInt("REAL", 100); + int ret = store->Insert(id, "person", values); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(1, id); + + std::shared_ptr resultSet = RdbStorePredicateTest::store->QueryByStep("SELECT * FROM person"); + EXPECT_EQ(1, ResultSize(resultSet)); + + int errCode = 0; + int columnIndex = 0; + ret = resultSet->GoToFirstRow(); + EXPECT_EQ(E_OK, ret); + + std::string name; + errCode = resultSet->GetColumnIndex("name", columnIndex); + EXPECT_EQ(errCode, E_OK); + ret = resultSet->GetString(columnIndex, name); + EXPECT_EQ(E_OK, ret); + EXPECT_EQ(name, ""); + resultSet->Close(); + + store->ExecuteSql("DELETE FROM person"); } \ No newline at end of file diff --git a/relational_store/test/native/rdb/unittest/rdb_read_only_test.cpp b/relational_store/test/native/rdb/unittest/rdb_read_only_test.cpp new file mode 100644 index 00000000..53c4f3b2 --- /dev/null +++ b/relational_store/test/native/rdb/unittest/rdb_read_only_test.cpp @@ -0,0 +1,506 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include + +#include "common.h" +#include "rdb_errno.h" +#include "rdb_helper.h" +#include "rdb_open_callback.h" + +using namespace testing::ext; +using namespace OHOS::NativeRdb; + +class RdbReadOnlyTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + + static const std::string READONLY_DATABASE_NAME; + static const std::string READONLY_DATABASE_BAK_NAME; + static const std::string DATABASE_NAME; + static std::shared_ptr readOnlyStore; +}; + +const std::string RdbReadOnlyTest::DATABASE_NAME = RDB_TEST_PATH + "database.db"; +const std::string RdbReadOnlyTest::READONLY_DATABASE_NAME = RDB_TEST_PATH + "readOnly.db"; +const std::string RdbReadOnlyTest::READONLY_DATABASE_BAK_NAME = RDB_TEST_PATH + "readOnlyBak.db"; +std::shared_ptr RdbReadOnlyTest::readOnlyStore = nullptr; + +class ReadOnlyTestOpenCallback : public RdbOpenCallback { +public: + int OnCreate(RdbStore &store) override; + int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override; + static const std::string CREATE_TABLE_TEST; +}; + +const std::string ReadOnlyTestOpenCallback::CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test " + "(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER, salary REAL, blobType BLOB)"; + +int ReadOnlyTestOpenCallback::OnCreate(RdbStore &store) +{ + return store.ExecuteSql(CREATE_TABLE_TEST); +} + +int ReadOnlyTestOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion) +{ + return E_OK; +} + +void RdbReadOnlyTest::SetUpTestCase(void) +{ + int errCode = E_ERROR; + RdbHelper::DeleteRdbStore(READONLY_DATABASE_NAME); + RdbStoreConfig config(READONLY_DATABASE_NAME); + config.SetBundleName("com.example.readOnly.rdb"); + ReadOnlyTestOpenCallback helper; + // user_version is 1 + auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + EXPECT_NE(nullptr, store); + EXPECT_EQ(E_OK, errCode); + + int64_t id; + ValuesBucket values; + values.PutString("name", "zhangSan"); + int ret = store->Insert(id, "test", values); + EXPECT_EQ(E_OK, ret); + // id is 1 + EXPECT_EQ(1, id); + + RdbHelper::ClearCache(); + + RdbStoreConfig config1(READONLY_DATABASE_NAME); + config1.SetBundleName("com.example.readOnly.rdb"); + config1.SetReadOnly(true); + ReadOnlyTestOpenCallback helper1; + // user_version is 1 + readOnlyStore = RdbHelper::GetRdbStore(config1, 1, helper1, errCode); + EXPECT_NE(nullptr, readOnlyStore); + EXPECT_EQ(E_OK, errCode); +} + +void RdbReadOnlyTest::TearDownTestCase(void) +{ + readOnlyStore = nullptr; + EXPECT_EQ(E_OK, RdbHelper::DeleteRdbStore(RdbReadOnlyTest::DATABASE_NAME)); + EXPECT_EQ(E_OK, RdbHelper::DeleteRdbStore(RdbReadOnlyTest::READONLY_DATABASE_NAME)); + EXPECT_EQ(E_OK, RdbHelper::DeleteRdbStore(RdbReadOnlyTest::READONLY_DATABASE_BAK_NAME)); +} + +void RdbReadOnlyTest::SetUp() +{ +} + +void RdbReadOnlyTest::TearDown() +{ +} + +/** + * @tc.name: RdbStore_ReadOnly_0001, open read-only database if the database is not exist + * @tc.desc: 1. set isReadOnly as true + * 2. open read-only database + * @tc.type: FUNC + */ +HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0001, TestSize.Level1) +{ + int errCode = E_ERROR; + RdbStoreConfig config(RdbReadOnlyTest::DATABASE_NAME); + config.SetReadOnly(true); + ReadOnlyTestOpenCallback helper; + // create read-only database, user_version is 1 + auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + EXPECT_EQ(nullptr, store); + EXPECT_EQ(E_SQLITE_CANTOPEN, errCode); +} + +/** + * @tc.name: RdbStore_ReadOnly_0002, insert data + * @tc.desc: insert data into read-only database + * @tc.type: FUNC + */ +HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0002, TestSize.Level1) +{ + std::shared_ptr &store = RdbReadOnlyTest::readOnlyStore; + + int64_t id; + ValuesBucket values; + values.PutString("name", "liSi"); + int ret = store->Insert(id, "test", values); + EXPECT_EQ(E_NOT_SUPPORT, ret); +} + +/** + * @tc.name: RdbStore_ReadOnly_0003, update data + * @tc.desc: update data in read-only database + * @tc.type: FUNC + */ +HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0003, TestSize.Level1) +{ + std::shared_ptr &store = RdbReadOnlyTest::readOnlyStore; + + int changedRows; + ValuesBucket values; + // salary is 300.5 + values.PutDouble("salary", 300.5); + auto ret = store->Update(changedRows, "test", values); + EXPECT_EQ(E_NOT_SUPPORT, ret); +} + +/** + * @tc.name: RdbStore_ReadOnly_0004, delete data + * @tc.desc: delete data from read-only database + * @tc.type: FUNC + */ +HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0004, TestSize.Level1) +{ + std::shared_ptr &store = RdbReadOnlyTest::readOnlyStore; + + int deletedRows; + auto ret = store->Delete(deletedRows, "test", "id = 1"); + EXPECT_EQ(E_NOT_SUPPORT, ret); +} + +/** + * @tc.name: RdbStore_ReadOnly_0005 + * @tc.desc: execute transaction + * @tc.type: FUNC + */ +HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0005, TestSize.Level1) +{ + std::shared_ptr &store = RdbReadOnlyTest::readOnlyStore; + + auto ret = store->BeginTransaction(); + EXPECT_EQ(E_NOT_SUPPORT, ret); + + ret = store->Commit(); + EXPECT_EQ(E_NOT_SUPPORT, ret); + + ret = store->RollBack(); + EXPECT_EQ(E_NOT_SUPPORT, ret); +} + +/** + * @tc.name: RdbStore_ReadOnly_0006 + * @tc.desc: batch insert data + * @tc.type: FUNC + */ +HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0006, TestSize.Level1) +{ + std::shared_ptr &store = RdbReadOnlyTest::readOnlyStore; + + int64_t number = 0; + std::vector valuesBuckets; + ValuesBucket values; + values.PutString("name", "zhangSan"); + valuesBuckets.push_back(std::move(values)); + int error = store->BatchInsert(number, "test", valuesBuckets); + EXPECT_EQ(E_NOT_SUPPORT, error); +} + +/** + * @tc.name: RdbStore_ReadOnly_0007 + * @tc.desc: get user_version by querySql + * @tc.type: FUNC + */ +HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0007, TestSize.Level1) +{ + std::shared_ptr &store = RdbReadOnlyTest::readOnlyStore; + + auto resultSet = store->QuerySql("PRAGMA user_version"); + + EXPECT_NE(nullptr, resultSet); + EXPECT_EQ(E_OK, resultSet->GoToFirstRow()); + + int value = 0; + // column index is 0 + EXPECT_EQ(E_OK, resultSet->GetInt(0, value)); + EXPECT_EQ(1, value); + + EXPECT_EQ(E_OK, resultSet->Close()); +} + +/** + * @tc.name: RdbStore_ReadOnly_0008 + * @tc.desc: get user_version by execute + * @tc.type: FUNC + */ +HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0008, TestSize.Level1) +{ + std::shared_ptr &store = RdbReadOnlyTest::readOnlyStore; + + auto [ret, object] = store->Execute("PRAGMA user_version"); + EXPECT_EQ(E_NOT_SUPPORT, ret); + + std::tie(ret, object) = store->Execute("PRAGMA user_version=2"); + EXPECT_EQ(E_NOT_SUPPORT, ret); +} + +/** + * @tc.name: RdbStore_ReadOnly_0009 + * @tc.desc: query data + * @tc.type: FUNC + */ +HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0009, TestSize.Level1) +{ + std::shared_ptr &store = RdbReadOnlyTest::readOnlyStore; + + auto resultSet = store->QuerySql("SELECT * FROM test"); + + int count = 0; + EXPECT_EQ(E_OK, resultSet->GetRowCount(count)); + // count is 1 + EXPECT_EQ(1, count); + + EXPECT_EQ(E_OK, resultSet->Close()); +} + +/** + * @tc.name: RdbStore_ReadOnly_0010 + * @tc.desc: get user_version by executeSql + * @tc.type: FUNC + */ +HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0010, TestSize.Level1) +{ + std::shared_ptr &store = RdbReadOnlyTest::readOnlyStore; + + auto ret = store->ExecuteSql("PRAGMA user_version"); + EXPECT_EQ(E_NOT_SUPPORT, ret); + + ret = store->ExecuteSql("SELECT * FROM test"); + EXPECT_EQ(E_NOT_SUPPORT, ret); +} + +/** + * @tc.name: RdbStore_ReadOnly_0011 + * @tc.desc: replace data + * @tc.type: FUNC + */ +HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0011, TestSize.Level1) +{ + std::shared_ptr &store = RdbReadOnlyTest::readOnlyStore; + + int64_t id; + ValuesBucket values; + values.PutString("name", "zhangSan"); + int ret = store->Replace(id, "test", values); + EXPECT_EQ(E_NOT_SUPPORT, ret); +} + +/** + * @tc.name: RdbStore_ReadOnly_0012 + * @tc.desc: test ExecuteAndGetLong + * @tc.type: FUNC + */ +HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0012, TestSize.Level1) +{ + std::shared_ptr &store = RdbReadOnlyTest::readOnlyStore; + + int64_t count; + int ret = store->ExecuteAndGetLong(count, "SELECT COUNT(*) FROM test"); + EXPECT_EQ(E_OK, ret); + + ret = store->ExecuteAndGetLong(count, "PRAGMA user_version"); + EXPECT_EQ(E_DATABASE_BUSY, ret); +} + +/** + * @tc.name: RdbStore_ReadOnly_0013 + * @tc.desc: test ExecuteAndGetString + * @tc.type: FUNC + */ +HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0013, TestSize.Level1) +{ + std::shared_ptr &store = RdbReadOnlyTest::readOnlyStore; + + std::string count; + int ret = store->ExecuteAndGetString(count, "SELECT COUNT(*) FROM test"); + EXPECT_EQ(E_OK, ret); + + ret = store->ExecuteAndGetString(count, "PRAGMA user_version"); + EXPECT_EQ(E_DATABASE_BUSY, ret); +} + +/** + * @tc.name: RdbStore_ReadOnly_0014 + * @tc.desc: test ExecuteForLastInsertedRowId + * @tc.type: FUNC + */ +HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0014, TestSize.Level1) +{ + std::shared_ptr &store = RdbReadOnlyTest::readOnlyStore; + + int64_t outValue; + int ret = store->ExecuteForLastInsertedRowId(outValue, "", {}); + EXPECT_EQ(E_NOT_SUPPORT, ret); +} + +/** + * @tc.name: RdbStore_ReadOnly_0015 + * @tc.desc: test ExecuteForChangedRowCount + * @tc.type: FUNC + */ +HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0015, TestSize.Level1) +{ + std::shared_ptr &store = RdbReadOnlyTest::readOnlyStore; + + int64_t outValue; + int ret = store->ExecuteForChangedRowCount(outValue, "", {}); + EXPECT_EQ(E_NOT_SUPPORT, ret); +} + +/** + * @tc.name: RdbStore_ReadOnly_0016 + * @tc.desc: get user_version by GetVersion + * @tc.type: FUNC + */ +HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0016, TestSize.Level1) +{ + std::shared_ptr &store = RdbReadOnlyTest::readOnlyStore; + + int version = -1; + auto ret = store->GetVersion(version); + EXPECT_EQ(E_OK, ret); + // version is 1 + EXPECT_EQ(1, version); +} + +/** + * @tc.name: RdbStore_ReadOnly_0017 + * @tc.desc: set user_version by SetVersion + * @tc.type: FUNC + */ +HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0017, TestSize.Level1) +{ + std::shared_ptr &store = RdbReadOnlyTest::readOnlyStore; + + int version = 2; + auto ret = store->SetVersion(version); + EXPECT_EQ(E_NOT_SUPPORT, ret); +} + +/** + * @tc.name: RdbStore_ReadOnly_0018 + * @tc.desc: test vector db + * @tc.type: FUNC + */ +HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0018, TestSize.Level1) +{ + int errCode = E_ERROR; + RdbStoreConfig config(RdbReadOnlyTest::READONLY_DATABASE_NAME); + config.SetBundleName("com.example.readOnly.rdb"); + config.SetReadOnly(true); + config.SetIsVector(true); + ReadOnlyTestOpenCallback helper; + // user_version is 1 + auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + EXPECT_NE(nullptr, store); + + auto [ret, id] = store->BeginTrans(); + EXPECT_EQ(E_NOT_SUPPORT, ret); + + // id is 1 + ret = store->Commit(1); + EXPECT_EQ(E_NOT_SUPPORT, ret); + + // id is 1 + ret = store->RollBack(1); + EXPECT_EQ(E_NOT_SUPPORT, ret); + + ValueObject obj; + // id is 1 + std::tie(ret, obj) = store->Execute("PRAGMA user_version", {}, 1); + EXPECT_EQ(E_NOT_SUPPORT, ret); +} + +/** + * @tc.name: RdbStore_ReadOnly_0019 + * @tc.desc: test encrypt db + * @tc.type: FUNC + */ +HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0019, TestSize.Level1) +{ + int errCode = E_ERROR; + RdbStoreConfig config(RdbReadOnlyTest::DATABASE_NAME); + config.SetBundleName("com.example.encrypt.rdb"); + config.SetEncryptStatus(true); + ReadOnlyTestOpenCallback helper; + // user_version is 1 + auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + EXPECT_NE(nullptr, store); + + RdbHelper::ClearCache(); + + RdbStoreConfig config1(RdbReadOnlyTest::DATABASE_NAME); + config1.SetBundleName("com.example.encrypt.rdb"); + config1.SetReadOnly(true); + config1.SetEncryptStatus(true); + // user_version is 1 + store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + EXPECT_NE(nullptr, store); + + EXPECT_EQ(E_OK, RdbHelper::DeleteRdbStore(RdbReadOnlyTest::DATABASE_NAME)); +} + +/** + * @tc.name: RdbStore_ReadOnly_0020 + * @tc.desc: test attach and detach + * @tc.type: FUNC + */ +HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0020, TestSize.Level1) +{ + std::shared_ptr &store = RdbReadOnlyTest::readOnlyStore; + + RdbStoreConfig config(RdbReadOnlyTest::READONLY_DATABASE_NAME); + auto [ret, size] = store->Attach(config, RdbReadOnlyTest::DATABASE_NAME); + EXPECT_EQ(E_NOT_SUPPORT, ret); + + std::tie(ret, size) = store->Detach(RdbReadOnlyTest::DATABASE_NAME); + EXPECT_EQ(E_NOT_SUPPORT, ret); +} + +/** + * @tc.name: RdbStore_ReadOnly_0021 + * @tc.desc: test SetDistributedTables + * @tc.type: FUNC + */ +HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0021, TestSize.Level1) +{ + std::shared_ptr &store = RdbReadOnlyTest::readOnlyStore; + + AbsRdbPredicates predicates("test"); + OHOS::DistributedRdb::DistributedConfig config; + // type is 0 + auto ret = store->SetDistributedTables({}, 0, config); + EXPECT_EQ(E_NOT_SUPPORT, ret); +} + +/** + * @tc.name: RdbStore_ReadOnly_0022 + * @tc.desc: test CleanDirtyData + * @tc.type: FUNC + */ +HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0022, TestSize.Level1) +{ + std::shared_ptr &store = RdbReadOnlyTest::readOnlyStore; + + uint64_t cursor = 1; + auto ret = store->CleanDirtyData("test", cursor); + EXPECT_EQ(E_NOT_SUPPORT, ret); +} + diff --git a/relational_store/test/native/rdb/unittest/rdb_sqlite_shared_result_set_test.cpp b/relational_store/test/native/rdb/unittest/rdb_sqlite_shared_result_set_test.cpp index 61298923..8417f70f 100644 --- a/relational_store/test/native/rdb/unittest/rdb_sqlite_shared_result_set_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_sqlite_shared_result_set_test.cpp @@ -1158,7 +1158,7 @@ HWTEST_F(RdbSqliteSharedResultSetTest, Sqlite_Shared_Result_Set_021, TestSize.Le std::vector columnNames; int ret = resultSet->GetAllColumnNames(columnNames); - EXPECT_EQ(E_NOT_SELECT, ret); + EXPECT_EQ(E_INVALID_ARGS, ret); resultSet->Close(); } @@ -1177,7 +1177,7 @@ HWTEST_F(RdbSqliteSharedResultSetTest, Sqlite_Shared_Result_Set_022, TestSize.Le std::vector columnNames; int ret = resultSet->GetAllColumnNames(columnNames); - EXPECT_EQ(E_ERROR, ret); + EXPECT_EQ(E_SQLITE_ERROR, ret); resultSet->Close(); } @@ -1235,7 +1235,7 @@ HWTEST_F(RdbSqliteSharedResultSetTest, Sqlite_Shared_Result_Set_025, TestSize.Le EXPECT_NE(resultSet, nullptr); int ret = resultSet->GoToRow(-10); - EXPECT_EQ(E_ERROR, ret); + EXPECT_EQ(E_ROW_OUT_RANGE, ret); resultSet->Close(); } @@ -1557,7 +1557,54 @@ HWTEST_F(RdbSqliteSharedResultSetTest, Sqlite_Shared_Result_Set_036, TestSize.Le EXPECT_NE(rstSet, nullptr); int ret = rstSet->GoToFirstRow(); - EXPECT_EQ(ret, E_ERROR); + EXPECT_EQ(ret, E_ROW_OUT_RANGE); ret = rstSet->GoToLastRow(); EXPECT_EQ(ret, E_ERROR); +} + +/* * + * @tc.name: Sqlite_Shared_Result_Set_037 + * @tc.desc: normal testcase of SqliteSharedResultSet for PRAGMA user_version + * @tc.type: FUNC + */ +HWTEST_F(RdbSqliteSharedResultSetTest, Sqlite_Shared_Result_Set_037, TestSize.Level1) +{ + // 2 is used to set the store version + int ret = store->ExecuteSql("PRAGMA user_version = 2"); + EXPECT_EQ(ret, E_OK); + std::shared_ptr resultSet = store->QuerySql("PRAGMA user_version"); + + int64_t longValue; + EXPECT_EQ(E_OK, resultSet->GoToFirstRow()); + EXPECT_EQ(E_OK, resultSet->GetLong(0, longValue)); + EXPECT_EQ(2, longValue); + + resultSet->Close(); +} + +/* * + * @tc.name: Sqlite_Shared_Result_Set_038 + * @tc.desc: normal testcase of SqliteSharedResultSet for PRAGMA table_info + * @tc.type: FUNC + */ +HWTEST_F(RdbSqliteSharedResultSetTest, Sqlite_Shared_Result_Set_038, TestSize.Level1) +{ + int ret = store->ExecuteSql("PRAGMA table_info(test)"); + EXPECT_EQ(ret, E_OK); + std::shared_ptr resultSet = store->QuerySql("PRAGMA table_info(test)"); + + std::string strValue; + EXPECT_EQ(E_OK, resultSet->GoToFirstRow()); + EXPECT_EQ(E_OK, resultSet->GetString(1, strValue)); + EXPECT_EQ("id", strValue); + EXPECT_EQ(E_OK, resultSet->GetString(2, strValue)); + EXPECT_EQ("INTEGER", strValue); + + EXPECT_EQ(E_OK, resultSet->GoToNextRow()); + EXPECT_EQ(E_OK, resultSet->GetString(1, strValue)); + EXPECT_EQ("data1", strValue); + EXPECT_EQ(E_OK, resultSet->GetString(2, strValue)); + EXPECT_EQ("TEXT", strValue); + + resultSet->Close(); } \ No newline at end of file diff --git a/relational_store/test/native/rdb/unittest/rdb_step_result_set_test.cpp b/relational_store/test/native/rdb/unittest/rdb_step_result_set_test.cpp index a59e4be5..1fb6b3fc 100644 --- a/relational_store/test/native/rdb/unittest/rdb_step_result_set_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_step_result_set_test.cpp @@ -347,16 +347,17 @@ HWTEST_F(RdbStepResultSetTest, RdbStore_StepResultSet_004, TestSize.Level1) std::shared_ptr resultSet = store->QueryByStep("SELECT data1, data2, data3, data4 FROM test"); EXPECT_NE(resultSet, nullptr); - CheckResultSetAttribute(resultSet, -1, false, false, false); + CheckResultSetAttribute(resultSet, -1, false, false, true); - EXPECT_NE(E_OK, resultSet->GoToNextRow()); + auto res = resultSet->GoToNextRow(); + EXPECT_NE(E_OK, res); int position = INT_MIN; int iRet = resultSet->GetRowIndex(position); EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(0, position); + EXPECT_EQ(-1, position); - CheckResultSetAttribute(resultSet, 0, true, false, false); + CheckResultSetAttribute(resultSet, -1, false, false, true); } /* * @@ -406,10 +407,10 @@ HWTEST_F(RdbStepResultSetTest, RdbStore_StepResultSet_006, TestSize.Level1) EXPECT_NE(E_OK, resultSet->GoToFirstRow()); - CheckResultSetAttribute(resultSet, 0, true, false, false); + CheckResultSetAttribute(resultSet, -1, false, false, true); EXPECT_NE(E_OK, resultSet->GoToNextRow()); - EXPECT_EQ(E_OK, resultSet->GoToFirstRow()); + EXPECT_NE(E_OK, resultSet->GoToFirstRow()); bool bResultSet = false; int iRet = resultSet->IsAtFirstRow(bResultSet); @@ -419,7 +420,7 @@ HWTEST_F(RdbStepResultSetTest, RdbStore_StepResultSet_006, TestSize.Level1) bResultSet = false; iRet = resultSet->IsStarted(bResultSet); EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, true); + EXPECT_EQ(bResultSet, false); } /* * @@ -471,31 +472,28 @@ HWTEST_F(RdbStepResultSetTest, RdbStore_StepResultSet_008, TestSize.Level1) std::shared_ptr resultSet = store->QueryByStep("SELECT * FROM test"); EXPECT_NE(resultSet, nullptr); - int moveTimes = 0; EXPECT_NE(E_OK, resultSet->GoToFirstRow()); - moveTimes++; int position = INT_MIN; bool bResultSet = false; int iRet = resultSet->GetRowIndex(position); EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(0, position); + EXPECT_EQ(-1, position); iRet = resultSet->IsEnded(bResultSet); EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, false); + EXPECT_EQ(bResultSet, true); while (E_OK == resultSet->GoToNextRow()) { - moveTimes++; } iRet = resultSet->GetRowIndex(position); EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(0, position); + EXPECT_EQ(-1, position); bResultSet = false; iRet = resultSet->IsEnded(bResultSet); EXPECT_EQ(E_OK, iRet); - EXPECT_EQ(bResultSet, false); + EXPECT_EQ(bResultSet, true); } /* * * @tc.name: RdbStore_StepResultSet_009 @@ -1410,7 +1408,7 @@ HWTEST_F(RdbStepResultSetTest, testSqlStep015, TestSize.Level1) EXPECT_NE(resultSet, nullptr); std::vector columnNames; - EXPECT_EQ(E_NOT_SELECT, resultSet->GetAllColumnNames(columnNames)); + EXPECT_EQ(E_INVALID_ARGS, resultSet->GetAllColumnNames(columnNames)); EXPECT_EQ(E_OK, resultSet->Close()); } @@ -1583,6 +1581,54 @@ HWTEST_F(RdbStepResultSetTest, testSqlStep020, TestSize.Level1) EXPECT_EQ(E_OK, resultSet->Close()); } +/* * + * @tc.name: testSqlStep021 + * @tc.desc: normal testcase of SqlStep for QueryByStep, PRAGMA user_version + * @tc.type: FUNC + */ +HWTEST_F(RdbStepResultSetTest, testSqlStep021, TestSize.Level1) +{ + // 2 is used to set the store version + int ret = store->ExecuteSql("PRAGMA user_version = 2"); + EXPECT_EQ(ret, E_OK); + std::shared_ptr resultSet = store->QueryByStep("PRAGMA user_version"); + + int64_t longValue; + EXPECT_EQ(E_OK, resultSet->GoToFirstRow()); + EXPECT_EQ(E_OK, resultSet->GetLong(0, longValue)); + EXPECT_EQ(2, longValue); + + resultSet->Close(); +} + +/* * + * @tc.name: testSqlStep022 + * @tc.desc: normal testcase of SqlStep for QueryByStep, PRAGMA table_info + * @tc.type: FUNC + */ +HWTEST_F(RdbStepResultSetTest, testSqlStep022, TestSize.Level1) +{ + GenerateDefaultEmptyTable(); + int ret = store->ExecuteSql("PRAGMA table_info(test)"); + EXPECT_EQ(ret, E_OK); + std::shared_ptr resultSet = store->QueryByStep("PRAGMA table_info(test)"); + + std::string strValue; + EXPECT_EQ(E_OK, resultSet->GoToFirstRow()); + EXPECT_EQ(E_OK, resultSet->GetString(1, strValue)); + EXPECT_EQ("id", strValue); + EXPECT_EQ(E_OK, resultSet->GetString(2, strValue)); + EXPECT_EQ("INTEGER", strValue); + + EXPECT_EQ(E_OK, resultSet->GoToNextRow()); + EXPECT_EQ(E_OK, resultSet->GetString(1, strValue)); + EXPECT_EQ("data1", strValue); + EXPECT_EQ(E_OK, resultSet->GetString(2, strValue)); + EXPECT_EQ("TEXT", strValue); + + resultSet->Close(); +} + /** * @tc.name: ResultSetProxy001 * @tc.desc: Abnormal testcase of distributed ResultSetProxy, if resultSet is Empty diff --git a/relational_store/test/native/rdb/unittest/rdb_store_config_test.cpp b/relational_store/test/native/rdb/unittest/rdb_store_config_test.cpp index 5d9e461a..bb30e681 100644 --- a/relational_store/test/native/rdb/unittest/rdb_store_config_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_store_config_test.cpp @@ -898,11 +898,11 @@ HWTEST_F(RdbStoreConfigTest, RdbStoreConfig_027, TestSize.Level1) } /** - * @tc.name: RdbStoreConfig_029 + * @tc.name: RdbStoreConfig_028 * @tc.desc: test RdbStoreConfig interfaces: SetDataGroupId/SetAutoClean * @tc.type: FUNC */ -HWTEST_F(RdbStoreConfigTest, RdbStoreConfig_029, TestSize.Level1) +HWTEST_F(RdbStoreConfigTest, RdbStoreConfig_028, TestSize.Level1) { const std::string dbPath = RDB_TEST_PATH + "config_test.db"; RdbStoreConfig config(dbPath); @@ -913,13 +913,13 @@ HWTEST_F(RdbStoreConfigTest, RdbStoreConfig_029, TestSize.Level1) } /** - * @tc.name: RdbStoreConfig_030 + * @tc.name: RdbStoreConfig_029 * @tc.desc: test RdbStoreConfig interfaces: SetModuleName/GetModuleName * @tc.type: FUNC */ -HWTEST_F(RdbStoreConfigTest, RdbStoreConfig_030, TestSize.Level1) +HWTEST_F(RdbStoreConfigTest, RdbStoreConfig_029, TestSize.Level1) { - const std::string dbPath = RDB_TEST_PATH + "config_test_30.db"; + const std::string dbPath = RDB_TEST_PATH + "config_test_29.db"; RdbStoreConfig config(dbPath); std::string bundleName = "com.ohos.config.test30"; @@ -947,73 +947,72 @@ HWTEST_F(RdbStoreConfigTest, RdbStoreConfig_030, TestSize.Level1) } /** - * @tc.name: RdbStoreConfig_040 - * @tc.desc: test RdbStoreConfig interfaces: SetModuleName/GetModuleName + * @tc.name: RdbStoreConfig_030 + * @tc.desc: test RdbStoreConfig interfaces: SetReadTime/GetReadTime * @tc.type: FUNC */ -HWTEST_F(RdbStoreConfigTest, RdbStoreConfig_040, TestSize.Level1) +HWTEST_F(RdbStoreConfigTest, RdbStoreConfig_030, TestSize.Level1) { - const std::string dbPath = RDB_TEST_PATH + "config_test_40.db"; - RdbHelper::DeleteRdbStore(dbPath); + const std::string dbPath = RDB_TEST_PATH + "config_test.db"; RdbStoreConfig config(dbPath); - std::string bundleName = "com.ohos.config.test40"; - config.SetBundleName(bundleName); - config.SetSecurityLevel(SecurityLevel::S1); - config.SetArea(0); - config.SetEncryptStatus(false); + int timeout = 10; + config.SetReadTime(timeout); + EXPECT_EQ(timeout, config.GetReadTime()); - ConfigTestOpenCallback helper; - int errCode = E_ERROR; - std::shared_ptr store = RdbHelper::GetRdbStore(config, 1, helper, errCode); - EXPECT_EQ(errCode, E_OK); - EXPECT_NE(store, nullptr); - - store = nullptr; + // 0 is used to test the situation when outTime is less than MIN_TIMEOUT. + timeout = 0; + config.SetReadTime(timeout); + EXPECT_EQ(1, config.GetReadTime()); - auto invalidConfig = config; - invalidConfig.SetArea(1); - store = RdbHelper::GetRdbStore(invalidConfig, 1, helper, errCode); - EXPECT_EQ(store, nullptr); - EXPECT_EQ(errCode, E_CONFIG_INVALID_CHANGE); - store = nullptr; - - RdbHelper::DeleteRdbStore(dbPath); + // 301 is used to test the situation when outTime is greater than MAX_TIMEOUT. + timeout = 301; + config.SetReadTime(timeout); + EXPECT_EQ(300, config.GetReadTime()); } /** - * @tc.name: RdbStoreConfig_050 - * @tc.desc: test RdbStoreConfig interfaces: SetModuleName/GetModuleName + * @tc.name: RdbStoreConfig_031 + * @tc.desc: test RdbStoreConfig interfaces: SetDataGroupId/SetAutoClean * @tc.type: FUNC */ -HWTEST_F(RdbStoreConfigTest, RdbStoreConfig_050, TestSize.Level1) +HWTEST_F(RdbStoreConfigTest, RdbStoreConfig_031, TestSize.Level1) { - const std::string dbPath = RDB_TEST_PATH + "config_test_50.db"; - RdbHelper::DeleteRdbStore(dbPath); + const std::string dbPath = RDB_TEST_PATH + "config_test.db"; RdbStoreConfig config(dbPath); - std::string bundleName = "com.ohos.config.test1"; - config.SetBundleName(bundleName); - config.SetSecurityLevel(SecurityLevel::S1); - config.SetArea(0); - config.SetEncryptStatus(false); + bool allowRebuild = false; + config.SetAllowRebuild(allowRebuild); + EXPECT_EQ(allowRebuild, config.GetAllowRebuild()); - ConfigTestOpenCallback helper; - int errCode = E_ERROR; - std::shared_ptr store = RdbHelper::GetRdbStore(config, 1, helper, errCode); - EXPECT_EQ(errCode, E_OK); - EXPECT_NE(store, nullptr); + allowRebuild = true; + config.SetAllowRebuild(allowRebuild); + EXPECT_EQ(allowRebuild, config.GetAllowRebuild()); +} - store = nullptr; +/** + * @tc.name: RdbStoreConfig_032 + * @tc.desc: test RdbStoreConfig interfaces: SetWriteTime/GetWriteTime + * @tc.type: FUNC + */ +HWTEST_F(RdbStoreConfigTest, RdbStoreConfig_032, TestSize.Level1) +{ + const std::string dbPath = RDB_TEST_PATH + "config_test.db"; + RdbStoreConfig config(dbPath); - auto invalidConfig = config; - invalidConfig.SetEncryptStatus(true); - store = RdbHelper::GetRdbStore(invalidConfig, 1, helper, errCode); - EXPECT_EQ(store, nullptr); - EXPECT_EQ(errCode, E_CONFIG_INVALID_CHANGE); - store = nullptr; + int timeout = 10; + config.SetWriteTime(timeout); + EXPECT_EQ(timeout, config.GetWriteTime()); - RdbHelper::DeleteRdbStore(dbPath); + // 0 is used to test the situation when outTime is less than MIN_TIMEOUT. + timeout = 0; + config.SetWriteTime(timeout); + EXPECT_EQ(1, config.GetWriteTime()); + + // 301 is used to test the situation when outTime is greater than MAX_TIMEOUT. + timeout = 301; + config.SetWriteTime(timeout); + EXPECT_EQ(300, config.GetWriteTime()); } /** @@ -1040,6 +1039,7 @@ HWTEST_F(RdbStoreConfigTest, RdbStoreConfigVisitor_001, TestSize.Level1) std::shared_ptr visitorStore = RdbHelper::GetRdbStore(visitorConfig, 1, visitorHelper, errCode); EXPECT_NE(visitorStore, nullptr); EXPECT_EQ(errCode, E_OK); + EXPECT_EQ(visitorDir, visitorConfig.GetVisitorDir()); int64_t id; ValuesBucket values; diff --git a/relational_store/test/native/rdb/unittest/rdb_store_impl_test.cpp b/relational_store/test/native/rdb/unittest/rdb_store_impl_test.cpp index cc2ddfbc..9fe31b16 100644 --- a/relational_store/test/native/rdb/unittest/rdb_store_impl_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_store_impl_test.cpp @@ -180,6 +180,7 @@ HWTEST_F(RdbStoreImplTest, GetModifyTimeByRowIdTest_003, TestSize.Level2) RdbStore::PRIKey key = result.GetOriginKey(std::vector{}); RdbStore::PRIKey monostate = std::monostate(); EXPECT_EQ(monostate, key); + EXPECT_EQ(8, result.GetMaxOriginKeySize()); store_->ExecuteSql("DROP TABLE IF EXISTS naturalbase_rdb_aux_rdbstoreimpltest_integer_log"); } @@ -703,3 +704,31 @@ HWTEST_F(RdbStoreImplTest, Abnormal_CleanDirtyDataTest_001, TestSize.Level2) EXPECT_EQ(E_ERROR, errCode); store_->ExecuteSql("DROP TABLE IF EXISTS test"); } + +/* * + * @tc.name: ClearCacheTest_001 + * @tc.desc: Normal testCase for ClearCache + * @tc.type: FUNC + */ +HWTEST_F(RdbStoreImplTest, Normal_ClearCacheTest_001, TestSize.Level2) +{ + store_->ExecuteSql("CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT, data1 TEXT, " + "data2 INTEGER, data3 FLOAT, data4 BLOB, data5 BOOLEAN);"); + int errCode = E_OK; + int64_t id; + ValuesBucket valuesBucket; + valuesBucket.PutString("data1", std::string("zhangsan")); + valuesBucket.PutInt("data2", 10); + errCode = store_->Insert(id, "test", valuesBucket); + EXPECT_EQ(errCode, E_OK); + EXPECT_EQ(1, id); + + int rowCount; + std::shared_ptr resultSet = store_->QueryByStep("SELECT * FROM test"); + EXPECT_NE(resultSet, nullptr); + resultSet->GetRowCount(rowCount); + EXPECT_EQ(rowCount, 1); + int64_t currentMemory = sqlite3_memory_used(); + EXPECT_EQ(E_OK, resultSet->Close()); + EXPECT_LT(sqlite3_memory_used(), currentMemory); +} \ No newline at end of file diff --git a/relational_store/test/native/rdb/unittest/rdb_store_subscribe_test.cpp b/relational_store/test/native/rdb/unittest/rdb_store_subscribe_test.cpp index d9d82493..b111d387 100644 --- a/relational_store/test/native/rdb/unittest/rdb_store_subscribe_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_store_subscribe_test.cpp @@ -22,11 +22,13 @@ #include "rdb_open_callback.h" #include "rdb_store_manager.h" #include "rdb_types.h" +#include "rdb_sql_statistic.h" using namespace testing::ext; using namespace OHOS::NativeRdb; using namespace OHOS::DistributedRdb; using CheckOnChangeFunc = std::function; +using SqlStatisticsFunc = std::function; class SubObserver : public RdbStoreObserver { public: virtual ~SubObserver() {} @@ -40,6 +42,15 @@ private: CheckOnChangeFunc checkOnChangeFunc_; }; +class StatisticsObserver : public SqlObserver { +public: + virtual ~StatisticsObserver() {} + void OnStatistic(const SqlExecutionInfo &info); + void Callback(const SqlStatisticsFunc &callback); +private: + SqlStatisticsFunc sqlStatisticsFunc_; +}; + class RdbStoreSubTest : public testing::Test { public: static void SetUpTestCase(void); @@ -53,6 +64,7 @@ public: static void RegisterCheckUpdateCallback(const std::vector> &SubObservers); static std::shared_ptr store; static std::shared_ptr observer_; + static std::shared_ptr sqlObserver_; }; class TestDetailProgressObserver : public DetailProgressObserver { @@ -64,6 +76,7 @@ public: const std::string RdbStoreSubTest::MAIN_DATABASE_NAME = RDB_TEST_PATH + "subscribe.db"; std::shared_ptr RdbStoreSubTest::store = nullptr; std::shared_ptr RdbStoreSubTest::observer_ = nullptr; +std::shared_ptr RdbStoreSubTest::sqlObserver_ = nullptr; void RdbStoreSubTest::SetUpTestCase(void) { @@ -72,6 +85,9 @@ void RdbStoreSubTest::SetUpTestCase(void) if (observer_ == nullptr) { observer_ = std::make_shared(); } + if (sqlObserver_ == nullptr) { + sqlObserver_ = std::make_shared(); + } } void RdbStoreSubTest::TearDownTestCase(void) @@ -140,6 +156,15 @@ void SubObserver::RegisterCallback(const CheckOnChangeFunc &callback) checkOnChangeFunc_ = callback; } +void StatisticsObserver::OnStatistic(const StatisticsObserver::SqlExecutionInfo &info) +{ +} + +void StatisticsObserver::Callback(const SqlStatisticsFunc &callback) +{ + sqlStatisticsFunc_ = callback; +} + std::shared_ptr RdbStoreSubTest::CreateRDB(int version) { RdbStoreConfig config(RdbStoreSubTest::MAIN_DATABASE_NAME); @@ -504,6 +529,268 @@ HWTEST_F(RdbStoreSubTest, RdbStoreSubscribeLocalDetail006, TestSize.Level1) observer_->RegisterCallback(nullptr); } +/** + * @tc.name: RdbStoreSubscribeStatistics001 + * @tc.desc: test statistics observer when insert data + * @tc.type: FUNC + * @tc.require: + * @tc.author: + */ +HWTEST_F(RdbStoreSubTest, RdbStoreSubscribeStatistics001, TestSize.Level1) +{ + EXPECT_NE(store, nullptr) << "store is null"; + EXPECT_NE(sqlObserver_, nullptr) << "observer is null"; + constexpr const char *createTableTest = "CREATE TABLE IF NOT EXISTS statistics_test " + "(id INTEGER PRIMARY KEY AUTOINCREMENT, " + "name TEXT NOT NULL, age INTEGER)"; + store->ExecuteSql(createTableTest); + auto status = SqlStatistic::Subscribe(sqlObserver_); + EXPECT_EQ(status, E_OK); + auto observer2 = std::make_shared(); + status = SqlStatistic::Subscribe(sqlObserver_); + ValuesBucket values; + int64_t id; + values.PutInt("id", 1); + values.PutString("name", std::string("zhangsan")); + values.PutInt("age", 18); // 18 is random age + status = store->Insert(id, "statistics_test", values); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(id, 1); + sqlObserver_->Callback([](SqlObserver::SqlExecutionInfo &info) { + ASSERT_EQ(info.sql_.size(), 1); + }); + observer2->Callback([](SqlObserver::SqlExecutionInfo &info) { + ASSERT_EQ(info.sql_.size(), 1); + }); + status = SqlStatistic::Unsubscribe(sqlObserver_); + EXPECT_EQ(status, E_OK); + status = SqlStatistic::Unsubscribe(observer2); + EXPECT_EQ(status, E_OK); +} + +/** + * @tc.name: RdbStoreSubscribeStatistics002 + * @tc.desc: test statistics observer when update data + * @tc.type: FUNC + * @tc.require: + * @tc.author: + */ +HWTEST_F(RdbStoreSubTest, RdbStoreSubscribeStatistics002, TestSize.Level1) +{ + EXPECT_NE(store, nullptr) << "store is null"; + EXPECT_NE(sqlObserver_, nullptr) << "observer is null"; + auto status = SqlStatistic::Subscribe(sqlObserver_); + EXPECT_EQ(status, E_OK); + int id; + ValuesBucket values; + values.PutString("name", std::string("zhangsan_update2")); + values.PutInt("age", 20); // 20 is random age + AbsRdbPredicates predicates("statistics_test"); + predicates.EqualTo("id", 1); + status = store->Update(id, values, predicates); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(id, 1); + sqlObserver_->Callback([](SqlObserver::SqlExecutionInfo &info) { + ASSERT_EQ(info.sql_.size(), 1); + }); + status = SqlStatistic::Unsubscribe(sqlObserver_); + EXPECT_EQ(status, E_OK); +} + +/** + * @tc.name: RdbStoreSubscribeStatistics003 + * @tc.desc: test statistics observer when delete data + * @tc.type: FUNC + * @tc.require: + * @tc.author: + */ +HWTEST_F(RdbStoreSubTest, RdbStoreSubscribeStatistics003, TestSize.Level1) +{ + EXPECT_NE(store, nullptr) << "store is null"; + EXPECT_NE(sqlObserver_, nullptr) << "observer is null"; + auto status = SqlStatistic::Subscribe(sqlObserver_); + EXPECT_EQ(status, E_OK); + sqlObserver_->Callback([](SqlObserver::SqlExecutionInfo &info) { + ASSERT_EQ(info.sql_.size(), 1); + }); + int id; + status = store->Delete(id, "statistics_test", "id = ?", std::vector{ "1" }); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(id, 1); + + status = SqlStatistic::Unsubscribe(sqlObserver_); + EXPECT_EQ(status, E_OK); + sqlObserver_->Callback(nullptr); +} + +/** + * @tc.name: RdbStoreSubscribeStatistics001 + * @tc.desc: test statistics observer when batchinsert data + * @tc.type: FUNC + * @tc.require: + * @tc.author: + */ +HWTEST_F(RdbStoreSubTest, RdbStoreSubscribeStatistics004, TestSize.Level1) +{ + int num = 10; + EXPECT_NE(store, nullptr) << "store is null"; + EXPECT_NE(sqlObserver_, nullptr) << "observer is null"; + auto status = SqlStatistic::Subscribe(sqlObserver_); + EXPECT_EQ(status, E_OK); + sqlObserver_->Callback([](SqlObserver::SqlExecutionInfo &info) { + ASSERT_EQ(info.sql_.size(), 1); + }); + int64_t id; + std::vector values; + for (int i = 0; i < num; i++) { + ValuesBucket value; + value.PutInt("id", i); + value.PutString("name", std::string("zhangsan")); + value.PutInt("age", 18); // 18 is random age + values.push_back(value); + } + status = store->BatchInsert(id, "statistics_test", values); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(id, num); + status = SqlStatistic::Unsubscribe(sqlObserver_); + EXPECT_EQ(status, E_OK); +} + +/** + * @tc.name: RdbStoreSubscribeStatistics001 + * @tc.desc: test statistics observer when create table after register observer + * @tc.type: FUNC + * @tc.require: + * @tc.author: + */ +HWTEST_F(RdbStoreSubTest, RdbStoreSubscribeStatistics005, TestSize.Level1) +{ + EXPECT_NE(store, nullptr) << "store is null"; + EXPECT_NE(sqlObserver_, nullptr) << "observer is null"; + auto status = SqlStatistic::Subscribe(sqlObserver_); + EXPECT_EQ(status, E_OK); + constexpr const char *createTableTest = "CREATE TABLE IF NOT EXISTS statistics_test1 " + "(id INTEGER PRIMARY KEY AUTOINCREMENT, " + "name TEXT NOT NULL, age INTEGER)"; + store->ExecuteSql(createTableTest); + + sqlObserver_->Callback([](SqlObserver::SqlExecutionInfo &info) { + ASSERT_EQ(info.sql_.size(), 3); + }); + ValuesBucket values; + int64_t id; + values.PutInt("id", 1); + values.PutString("name", std::string("zhangsan")); + values.PutInt("age", 18); // 18 is random age + status = store->Insert(id, "statistics_test1", values); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(id, 1); + status = SqlStatistic::Unsubscribe(sqlObserver_); + EXPECT_EQ(status, E_OK); +} + +/** + * @tc.name: RdbStoreSubscribeStatistics006 + * @tc.desc: test statistics observer when query data + * @tc.type: FUNC + * @tc.require: + * @tc.author: + */ +HWTEST_F(RdbStoreSubTest, RdbStoreSubscribeStatistics006, TestSize.Level1) +{ + EXPECT_NE(store, nullptr) << "store is null"; + EXPECT_NE(sqlObserver_, nullptr) << "observer is null"; + auto status = SqlStatistic::Subscribe(sqlObserver_); + EXPECT_EQ(status, E_OK); + sqlObserver_->Callback([](SqlObserver::SqlExecutionInfo &info) { + ASSERT_EQ(info.sql_.size(), 2); + }); + std::shared_ptr resultSet = store->QueryByStep("SELECT * FROM statistics_test"); + EXPECT_NE(resultSet, nullptr); + status = SqlStatistic::Unsubscribe(sqlObserver_); + EXPECT_EQ(status, E_OK); +} + +/** + * @tc.name: RdbStoreSubscribeStatistics007 + * @tc.desc: test statistics observer when query data + * @tc.type: FUNC + * @tc.require: + * @tc.author: + */ +HWTEST_F(RdbStoreSubTest, RdbStoreSubscribeStatistics007, TestSize.Level1) +{ + EXPECT_NE(store, nullptr) << "store is null"; + EXPECT_NE(sqlObserver_, nullptr) << "observer is null"; + auto status = SqlStatistic::Subscribe(sqlObserver_); + EXPECT_EQ(status, E_OK); + sqlObserver_->Callback([](SqlObserver::SqlExecutionInfo &info) { + ASSERT_EQ(info.sql_.size(), 2); + }); + std::shared_ptr resultSet = store->QuerySql("SELECT * FROM statistics_test"); + EXPECT_NE(resultSet, nullptr); + status = SqlStatistic::Unsubscribe(sqlObserver_); + EXPECT_EQ(status, E_OK); +} + +/** + * @tc.name: RdbStoreSubscribeStatistics008 + * @tc.desc: test statistics observer when Execute pragma + * @tc.type: FUNC + * @tc.require: + * @tc.author: + */ +HWTEST_F(RdbStoreSubTest, RdbStoreSubscribeStatistics008, TestSize.Level1) +{ + EXPECT_NE(store, nullptr) << "store is null"; + EXPECT_NE(sqlObserver_, nullptr) << "observer is null"; + auto status = SqlStatistic::Subscribe(sqlObserver_); + EXPECT_EQ(status, E_OK); + sqlObserver_->Callback([](SqlObserver::SqlExecutionInfo &info) { + ASSERT_EQ(info.sql_[0], "PRAGMA quick_check"); + }); + auto [ret, object] = store->Execute("PRAGMA quick_check"); + status = SqlStatistic::Unsubscribe(sqlObserver_); + EXPECT_EQ(status, E_OK); +} + +/** + * @tc.name: RdbStoreSubscribeStatistics009 + * @tc.desc: test statistics observer when ExecuteSql + * @tc.type: FUNC + * @tc.require: + * @tc.author: + */ +HWTEST_F(RdbStoreSubTest, RdbStoreSubscribeStatistics009, TestSize.Level1) +{ + EXPECT_NE(store, nullptr) << "store is null"; + EXPECT_NE(sqlObserver_, nullptr) << "observer is null"; + std::string value = "with test as (select * from statistics_test) select * from test1"; + auto status = SqlStatistic::Subscribe(sqlObserver_); + EXPECT_EQ(status, E_OK); + sqlObserver_->Callback([value](SqlObserver::SqlExecutionInfo &info) { + ASSERT_EQ(info.sql_[0], value); + }); + store->ExecuteSql(value); + status = SqlStatistic::Unsubscribe(sqlObserver_); + EXPECT_EQ(status, E_OK); +} + +/** + * @tc.name: RdbStoreSubscribeStatistics010 + * @tc.desc: test abnormal parametar subscribe + * @tc.type: FUNC + * @tc.require: + * @tc.author: + */ +HWTEST_F(RdbStoreSubTest, RdbStoreSubscribeStatistics010, TestSize.Level1) +{ + EXPECT_NE(store, nullptr) << "store is null"; + EXPECT_NE(sqlObserver_, nullptr) << "observer is null"; + auto status = SqlStatistic::Subscribe(nullptr); + EXPECT_EQ(status, E_OK); +} + /** * @tc.name: RdbStore_RegisterAutoSyncCallbackAndRdbStore_UnregisterAutoSyncCallback_001 * @tc.desc: Test RegisterAutoSyncCallback and UnregisterAutoSyncCallback diff --git a/relational_store/test/native/rdb/unittest/rdb_utils_test.cpp b/relational_store/test/native/rdb/unittest/rdb_utils_test.cpp index c4603eb7..88a5b412 100644 --- a/relational_store/test/native/rdb/unittest/rdb_utils_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_utils_test.cpp @@ -15,6 +15,7 @@ #include +#include #include #include "sqlite_utils.h" @@ -90,3 +91,24 @@ HWTEST_F(RdbUtilsTest, RdbStore_SqliteUtils_005, TestSize.Level1) { EXPECT_EQ("\"AND\"", StringUtils::SurroundWithQuote("AND", "\"")); } + +/** + * @tc.name: RdbStore_SqliteUtils_006 + * @tc.desc: Normal testCase of string_utils, if fileName is "" + * @tc.type: FUNC + */ +HWTEST_F(RdbUtilsTest, RdbStore_SqliteUtils_006, TestSize.Level1) +{ + // fileName size is 0 + EXPECT_EQ(0, SqliteUtils::GetFileSize("")); +} + +/** + * @tc.name: RdbStore_SqliteUtils_007 + * @tc.desc: AbNormal testCase of string_utils, if fileName is "" + * @tc.type: FUNC + */ +HWTEST_F(RdbUtilsTest, RdbStore_SqliteUtils_007, TestSize.Level1) +{ + EXPECT_EQ(0, SqliteUtils::GetFileSize("act.txt")); +} \ No newline at end of file diff --git a/relational_store/test/native/rdb_data_ability_adapter/unittest/data_ability_utils_test.cpp b/relational_store/test/native/rdb_data_ability_adapter/unittest/data_ability_utils_test.cpp index ce957501..90afb9c1 100644 --- a/relational_store/test/native/rdb_data_ability_adapter/unittest/data_ability_utils_test.cpp +++ b/relational_store/test/native/rdb_data_ability_adapter/unittest/data_ability_utils_test.cpp @@ -114,4 +114,4 @@ HWTEST_F(DataAbilityUtilsTest, DataAbilityUtilsTest_002, TestSize.Level1) std::string dataShareOrder = dataSharePredicates.GetOrder(); EXPECT_EQ(dataShareOrder, order); -} +} \ No newline at end of file diff --git a/relational_store/test/ndk/BUILD.gn b/relational_store/test/ndk/BUILD.gn index 70cf9826..b68ae477 100644 --- a/relational_store/test/ndk/BUILD.gn +++ b/relational_store/test/ndk/BUILD.gn @@ -34,6 +34,7 @@ ohos_unittest("NativeRdbNdkTest") { module_out_path = module_output_path sources = [ + "${relational_store_base_path}/interfaces/ndk/src/convertor_error_code.cpp", "${relational_store_base_path}/interfaces/ndk/src/modify_time_cursor.cpp", "${relational_store_base_path}/interfaces/ndk/src/relational_asset.cpp", "${relational_store_base_path}/interfaces/ndk/src/relational_cursor.cpp", diff --git a/relational_store/test/ndk/unittest/rdb_cursor_test.cpp b/relational_store/test/ndk/unittest/rdb_cursor_test.cpp index 2d8ba889..b3772e5e 100644 --- a/relational_store/test/ndk/unittest/rdb_cursor_test.cpp +++ b/relational_store/test/ndk/unittest/rdb_cursor_test.cpp @@ -625,7 +625,7 @@ HWTEST_F(RdbNativeCursorTest, Abnormal_cursor_PutAssets_test_010, TestSize.Level char table[] = "asset_table"; int assetsCount = 2; int curRow = 3; - + OH_VBucket *valueBucket = OH_Rdb_CreateValuesBucket(); Data_Asset *asset = OH_Data_Asset_CreateOne(); diff --git a/relational_store/test/ndk/unittest/rdb_store_test.cpp b/relational_store/test/ndk/unittest/rdb_store_test.cpp index 747bb27b..76624755 100644 --- a/relational_store/test/ndk/unittest/rdb_store_test.cpp +++ b/relational_store/test/ndk/unittest/rdb_store_test.cpp @@ -956,7 +956,6 @@ HWTEST_F(RdbNativeStoreTest, Abnormal_RDB_OH_interface_test_021, TestSize.Level1 EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_INVALID_ARGS); } - /** * @tc.name: Abnormal_RDB_OH_interface_test_022 * @tc.desc: Abnormal testCase of store for OH interface. @@ -1046,7 +1045,7 @@ HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_023, TestSize.Level1) valueObject->putText(valueObject, data1Value); predicates->equalTo(predicates, "data1", valueObject); errCode = OH_Rdb_LockRow(storeTestRdbStore_, predicates); - EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_ERROR); + EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_NO_ROW_IN_QUERY); predicates->clear(predicates); OH_Cursor *cursor = OH_Rdb_QueryLockedRow(storeTestRdbStore_, predicates, NULL, 0); @@ -1058,7 +1057,7 @@ HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_023, TestSize.Level1) predicates->clear(predicates); errCode = OH_Rdb_UnlockRow(storeTestRdbStore_, predicates); - EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_ERROR); + EXPECT_EQ(errCode, OH_Rdb_ErrCode::RDB_E_NO_ROW_IN_QUERY); predicates->clear(predicates); cursor = OH_Rdb_QueryLockedRow(storeTestRdbStore_, predicates, NULL, 0); @@ -1072,4 +1071,427 @@ HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_023, TestSize.Level1) valueBucket->destroy(valueBucket); predicates->destroy(predicates); cursor->destroy(cursor); -} \ No newline at end of file +} + +void LocalDataChangeObserverCallback1(void *context, const Rdb_ChangeInfo **changeInfo, uint32_t count) +{ + for (uint32_t i = 0; i < count; i++) { + EXPECT_EQ(DISTRIBUTED_CHANGE_INFO_VERSION, changeInfo[i]->version); + // 0 represent table name is store_test + EXPECT_EQ(strcmp(changeInfo[i]->tableName, "store_test"), 0); + EXPECT_EQ(RDB_DATA_CHANGE, changeInfo[i]->ChangeType); + // insert row count is 1 + EXPECT_EQ(1, changeInfo[i]->inserted.count); + EXPECT_EQ(TYPE_INT64, changeInfo[i]->inserted.type); + // insert rowId is 2 + EXPECT_EQ(2, changeInfo[i]->inserted.data->integer); + // update row count is 0 + EXPECT_EQ(0, changeInfo[i]->updated.count); + // delete row count is 0 + EXPECT_EQ(0, changeInfo[i]->deleted.count); + } +} + +/** + * @tc.name: RDB_Native_store_test_024 + * @tc.desc: normal testCase for OH_Rdb_Subscribe, insert data into local database + * @tc.type: FUNC + */ +HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_024, TestSize.Level1) +{ + EXPECT_NE(storeTestRdbStore_, nullptr); + + Rdb_DetailsObserver callback = LocalDataChangeObserverCallback1; + Rdb_DataObserver observer = { nullptr, { callback } }; + EXPECT_EQ(OH_Rdb_Subscribe(storeTestRdbStore_, RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS, &observer), RDB_OK); + + OH_VBucket* valueBucket = OH_Rdb_CreateValuesBucket(); + // id is 2 + valueBucket->putInt64(valueBucket, "id", 2); + valueBucket->putText(valueBucket, "data1", "zhangSan"); + int errCode = OH_Rdb_Insert(storeTestRdbStore_, "store_test", valueBucket); + // insert rowId is 2 + EXPECT_EQ(2, errCode); + + EXPECT_EQ(OH_Rdb_Unsubscribe(storeTestRdbStore_, RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS, &observer), RDB_OK); + valueBucket->destroy(valueBucket); +} + +void LocalDataChangeObserverCallback2(void *context, const Rdb_ChangeInfo **changeInfo, uint32_t count) +{ + for (uint32_t i = 0; i < count; i++) { + EXPECT_EQ(DISTRIBUTED_CHANGE_INFO_VERSION, changeInfo[i]->version); + // 0 represent table name is store_test + EXPECT_EQ(strcmp(changeInfo[i]->tableName, "store_test"), 0); + EXPECT_EQ(RDB_DATA_CHANGE, changeInfo[i]->ChangeType); + EXPECT_EQ(TYPE_INT64, changeInfo[i]->updated.type); + // update row count is 1 + EXPECT_EQ(1, changeInfo[i]->updated.count); + // update rowId is 1 + EXPECT_EQ(1, changeInfo[i]->updated.data->integer); + // insert row count is 0 + EXPECT_EQ(0, changeInfo[i]->inserted.count); + // delete row count is 0 + EXPECT_EQ(0, changeInfo[i]->deleted.count); + } +} + +/** + * @tc.name: RDB_Native_store_test_025 + * @tc.desc: normal testCase for OH_Rdb_Subscribe, update a data into local database + * @tc.type: FUNC + */ +HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_025, TestSize.Level1) +{ + EXPECT_NE(storeTestRdbStore_, nullptr); + + Rdb_DetailsObserver callback = LocalDataChangeObserverCallback2; + Rdb_DataObserver observer = { nullptr, { callback } }; + + EXPECT_EQ(OH_Rdb_Subscribe(storeTestRdbStore_, RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS, &observer), RDB_OK); + + OH_VBucket* valueBucket = OH_Rdb_CreateValuesBucket(); + valueBucket->putText(valueBucket, "data1", "liSi"); + + OH_Predicates *predicates = OH_Rdb_CreatePredicates("store_test"); + OH_VObject *valueObject = OH_Rdb_CreateValueObject(); + const char *data1Value = "zhangSan"; + valueObject->putText(valueObject, data1Value); + predicates->equalTo(predicates, "data1", valueObject); + int errCode = OH_Rdb_Update(storeTestRdbStore_, valueBucket, predicates); + // update row count is 1 + EXPECT_EQ(errCode, 1); + + EXPECT_EQ(OH_Rdb_Unsubscribe(storeTestRdbStore_, RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS, &observer), RDB_OK); + valueObject->destroy(valueObject); + valueBucket->destroy(valueBucket); + predicates->destroy(predicates); +} + +void LocalDataChangeObserverCallback3(void *context, const Rdb_ChangeInfo **changeInfo, uint32_t count) +{ + for (uint32_t i = 0; i < count; i++) { + EXPECT_EQ(DISTRIBUTED_CHANGE_INFO_VERSION, changeInfo[i]->version); + // 0 represent table name is 0 + EXPECT_EQ(strcmp(changeInfo[i]->tableName, "store_test"), 0); + EXPECT_EQ(RDB_DATA_CHANGE, changeInfo[i]->ChangeType); + EXPECT_EQ(TYPE_INT64, changeInfo[i]->deleted.type); + // delete count is 1 + EXPECT_EQ(1, changeInfo[i]->deleted.count); + // delete rowId is 1 + EXPECT_EQ(1, changeInfo[i]->deleted.data->integer); + // insert count is 0 + EXPECT_EQ(0, changeInfo[i]->inserted.count); + // update count is 0 + EXPECT_EQ(0, changeInfo[i]->updated.count); + } +} + +/** + * @tc.name: RDB_Native_store_test_026 + * @tc.desc: normal testCase for OH_Rdb_Subscribe, delete data into local database + * @tc.type: FUNC + */ +HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_026, TestSize.Level1) +{ + EXPECT_NE(storeTestRdbStore_, nullptr); + + Rdb_DetailsObserver callback = LocalDataChangeObserverCallback3; + Rdb_DataObserver observer = { nullptr, { callback } }; + + EXPECT_EQ(OH_Rdb_Subscribe(storeTestRdbStore_, RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS, &observer), RDB_OK); + + OH_Predicates *predicates = OH_Rdb_CreatePredicates("store_test"); + OH_VObject *valueObject = OH_Rdb_CreateValueObject(); + const char *data1Value = "zhangSan"; + valueObject->putText(valueObject, data1Value); + predicates->equalTo(predicates, "data1", valueObject); + int errCode = OH_Rdb_Delete(storeTestRdbStore_, predicates); + // delete row count is 1 + EXPECT_EQ(errCode, 1); + + EXPECT_EQ(OH_Rdb_Unsubscribe(storeTestRdbStore_, RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS, &observer), RDB_OK); + valueObject->destroy(valueObject); + predicates->destroy(predicates); +} + +/** + * @tc.name: RDB_Native_store_test_027 + * @tc.desc: normal testCase for OH_Rdb_Subscribe, register two observers for local database + * @tc.type: FUNC + */ +HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_027, TestSize.Level1) +{ + EXPECT_NE(storeTestRdbStore_, nullptr); + + Rdb_DetailsObserver callback1 = LocalDataChangeObserverCallback1; + Rdb_DataObserver observer1 = { nullptr, { callback1 } }; + + Rdb_DetailsObserver callback2 = LocalDataChangeObserverCallback1; + Rdb_DataObserver observer2 = { nullptr, { callback2 } }; + + EXPECT_EQ(OH_Rdb_Subscribe(storeTestRdbStore_, RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS, &observer1), RDB_OK); + EXPECT_EQ(OH_Rdb_Subscribe(storeTestRdbStore_, RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS, &observer2), RDB_OK); + + OH_VBucket* valueBucket = OH_Rdb_CreateValuesBucket(); + // id is 2 + valueBucket->putInt64(valueBucket, "id", 2); + valueBucket->putText(valueBucket, "data1", "zhangSan"); + int errCode = OH_Rdb_Insert(storeTestRdbStore_, "store_test", valueBucket); + // rowId is 2 + EXPECT_EQ(2, errCode); + + EXPECT_EQ(OH_Rdb_Unsubscribe(storeTestRdbStore_, RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS, &observer1), RDB_OK); + EXPECT_EQ(OH_Rdb_Unsubscribe(storeTestRdbStore_, RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS, &observer2), RDB_OK); + valueBucket->destroy(valueBucket); +} + +void LocalDataChangeObserverCallback4(void *context, const Rdb_ChangeInfo **changeInfo, uint32_t count) +{ + EXPECT_EQ(0, count); +} + +/** + * @tc.name: RDB_Native_store_test_028 + * @tc.desc: normal testCase for OH_Rdb_Subscribe. + * 1.register two observers for local database + * 2.unRegister one of observers + * @tc.type: FUNC + */ +HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_028, TestSize.Level1) +{ + EXPECT_NE(storeTestRdbStore_, nullptr); + + Rdb_DetailsObserver callback1 = LocalDataChangeObserverCallback4; + Rdb_DataObserver observer1 = { nullptr, { callback1 } }; + + Rdb_DetailsObserver callback2 = LocalDataChangeObserverCallback1; + Rdb_DataObserver observer2 = { nullptr, { callback2 } }; + + EXPECT_EQ(OH_Rdb_Subscribe(storeTestRdbStore_, RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS, &observer1), RDB_OK); + EXPECT_EQ(OH_Rdb_Subscribe(storeTestRdbStore_, RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS, &observer2), RDB_OK); + EXPECT_EQ(OH_Rdb_Unsubscribe(storeTestRdbStore_, RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS, &observer1), RDB_OK); + + OH_VBucket* valueBucket = OH_Rdb_CreateValuesBucket(); + // id is 2 + valueBucket->putInt64(valueBucket, "id", 2); + valueBucket->putText(valueBucket, "data1", "zhangSan"); + int errCode = OH_Rdb_Insert(storeTestRdbStore_, "store_test", valueBucket); + // rowId is 2 + EXPECT_EQ(2, errCode); + + EXPECT_EQ(OH_Rdb_Unsubscribe(storeTestRdbStore_, RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS, &observer2), RDB_OK); + valueBucket->destroy(valueBucket); +} + +void LocalDataChangeObserverCallback5(void *context, const Rdb_ChangeInfo **changeInfo, uint32_t count) +{ + for (uint32_t i = 0; i < count; i++) { + EXPECT_EQ(DISTRIBUTED_CHANGE_INFO_VERSION, changeInfo[i]->version); + // 0 represent table name is test1 + EXPECT_EQ(strcmp(changeInfo[i]->tableName, "test1"), 0); + EXPECT_EQ(RDB_DATA_CHANGE, changeInfo[i]->ChangeType); + // insert a data + EXPECT_EQ(1, changeInfo[i]->inserted.count); + EXPECT_EQ(TYPE_INT64, changeInfo[i]->inserted.type); + // insert rowId is 1 + EXPECT_EQ(1, changeInfo[i]->inserted.data->integer); + // update count is 0 + EXPECT_EQ(0, changeInfo[i]->updated.count); + // delete count is 0 + EXPECT_EQ(0, changeInfo[i]->deleted.count); + } +} + +/** + * @tc.name: RDB_Native_store_test_029 + * @tc.desc: normal testCase for OH_Rdb_Subscribe. + * 1.register observer for local database + * 2.create new table test + * 3.insert data into table test + * 2.unRegister one of observer + * @tc.type: FUNC + */ +HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_029, TestSize.Level1) +{ + EXPECT_NE(storeTestRdbStore_, nullptr); + + Rdb_DetailsObserver callback = LocalDataChangeObserverCallback5; + Rdb_DataObserver observer = { nullptr, { callback } }; + + EXPECT_EQ(OH_Rdb_Subscribe(storeTestRdbStore_, RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS, &observer), RDB_OK); + + constexpr const char* createTableSql = "CREATE TABLE test1 (id INTEGER PRIMARY KEY AUTOINCREMENT, " + "data1 TEXT, data2 INTEGER, data3 FLOAT, data4 BLOB, data5 TEXT);"; + int errCode = OH_Rdb_Execute(storeTestRdbStore_, createTableSql); + // errCode is 0 + EXPECT_EQ(errCode, 0); + + OH_VBucket* valueBucket = OH_Rdb_CreateValuesBucket(); + valueBucket->putInt64(valueBucket, "id", 1); + valueBucket->putText(valueBucket, "data1", "zhangSan"); + errCode = OH_Rdb_Insert(storeTestRdbStore_, "test1", valueBucket); + // rowId is 1 + EXPECT_EQ(1, errCode); + + EXPECT_EQ(OH_Rdb_Unsubscribe(storeTestRdbStore_, RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS, &observer), RDB_OK); + + constexpr const char* dropTableSql = "DROP TABLE IF EXISTS test1"; + errCode = OH_Rdb_Execute(storeTestRdbStore_, dropTableSql); + // errCode is 0 + EXPECT_EQ(errCode, 0); + valueBucket->destroy(valueBucket); +} + +void LocalDataChangeObserverCallback6(void *context, const Rdb_ChangeInfo **changeInfo, uint32_t count) +{ + for (uint32_t i = 0; i < count; i++) { + EXPECT_EQ(DISTRIBUTED_CHANGE_INFO_VERSION, changeInfo[i]->version); + // 0 represent table name is store_test + EXPECT_EQ(strcmp(changeInfo[i]->tableName, "store_test"), 0); + EXPECT_EQ(RDB_DATA_CHANGE, changeInfo[i]->ChangeType); + // update row count is 2 + EXPECT_EQ(2, changeInfo[i]->updated.count); + EXPECT_EQ(TYPE_INT64, changeInfo[i]->updated.type); + // update rowId is 1 + EXPECT_EQ(1, changeInfo[i]->updated.data->integer); + // update rowId is 2 + EXPECT_EQ(2, ++(changeInfo[i]->updated.data)->integer); + // insert count is 0 + EXPECT_EQ(0, changeInfo[i]->inserted.count); + // delete count is 0 + EXPECT_EQ(0, changeInfo[i]->deleted.count); + } +} + +/** + * @tc.name: RDB_Native_store_test_030 + * @tc.desc: normal testCase for OH_Rdb_Subscribe, update two data in local database + * @tc.type: FUNC + */ +HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_030, TestSize.Level1) +{ + EXPECT_NE(storeTestRdbStore_, nullptr); + + OH_VBucket* valueBucket1 = OH_Rdb_CreateValuesBucket(); + valueBucket1->putText(valueBucket1, "data1", "zhangSan"); + int errCode = OH_Rdb_Insert(storeTestRdbStore_, "store_test", valueBucket1); + // rowId is 2 + EXPECT_EQ(2, errCode); + + Rdb_DetailsObserver callback = LocalDataChangeObserverCallback6; + Rdb_DataObserver observer = { nullptr, { callback } }; + + EXPECT_EQ(OH_Rdb_Subscribe(storeTestRdbStore_, RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS, &observer), RDB_OK); + + OH_VBucket* valueBucket2 = OH_Rdb_CreateValuesBucket(); + valueBucket2->putText(valueBucket2, "data1", "liSi"); + + OH_Predicates *predicates = OH_Rdb_CreatePredicates("store_test"); + OH_VObject *valueObject = OH_Rdb_CreateValueObject(); + const char *data1Value = "zhangSan"; + valueObject->putText(valueObject, data1Value); + predicates->equalTo(predicates, "data1", valueObject); + errCode = OH_Rdb_Update(storeTestRdbStore_, valueBucket2, predicates); + // update row count is 2 + EXPECT_EQ(errCode, 2); + + EXPECT_EQ(OH_Rdb_Unsubscribe(storeTestRdbStore_, RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS, &observer), RDB_OK); + valueObject->destroy(valueObject); + valueBucket1->destroy(valueBucket1); + valueBucket2->destroy(valueBucket2); + predicates->destroy(predicates); +} + +void LocalDataChangeObserverCallback7(void *context, const Rdb_ChangeInfo **changeInfo, uint32_t count) +{ + // count is 0 + EXPECT_EQ(0, count); +} + +void LocalDataChangeObserverCallback8(void *context, const Rdb_ChangeInfo **changeInfo, uint32_t count) +{ + // count is 0 + EXPECT_EQ(0, count); +} + +/** + * @tc.name: RDB_Native_store_test_031 + * @tc.desc: normal testCase for OH_Rdb_Subscribe. + * 1.register two observers for local database + * 2.unRegister one of observers + * @tc.type: FUNC + */ +HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_031, TestSize.Level1) +{ + EXPECT_NE(storeTestRdbStore_, nullptr); + + Rdb_DetailsObserver callback1 = LocalDataChangeObserverCallback7; + Rdb_DataObserver observer1 = { nullptr, { callback1 } }; + + Rdb_DetailsObserver callback2 = LocalDataChangeObserverCallback8; + Rdb_DataObserver observer2 = { nullptr, { callback2 } }; + + EXPECT_EQ(OH_Rdb_Subscribe(storeTestRdbStore_, RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS, &observer1), RDB_OK); + EXPECT_EQ(OH_Rdb_Subscribe(storeTestRdbStore_, RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS, &observer1), RDB_OK); + EXPECT_EQ(OH_Rdb_Subscribe(storeTestRdbStore_, RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS, &observer2), RDB_OK); + EXPECT_EQ(OH_Rdb_Unsubscribe(storeTestRdbStore_, RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS, nullptr), RDB_OK); + + OH_VBucket* valueBucket = OH_Rdb_CreateValuesBucket(); + valueBucket->putInt64(valueBucket, "id", 2); + valueBucket->putText(valueBucket, "data1", "zhangSan"); + int errCode = OH_Rdb_Insert(storeTestRdbStore_, "store_test", valueBucket); + // rowId is 2 + EXPECT_EQ(2, errCode); + + valueBucket->destroy(valueBucket); +} + +/** + * @tc.name: RDB_Native_store_test_032 + * @tc.desc: abNormal testCase for OH_Rdb_Subscribe. + * 1.store is nullptr + * 2.register observer for local database + * @tc.type: FUNC + */ +HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_032, TestSize.Level1) +{ + EXPECT_NE(storeTestRdbStore_, nullptr); + + Rdb_DetailsObserver callback = LocalDataChangeObserverCallback7; + Rdb_DataObserver observer = { nullptr, { callback } }; + EXPECT_EQ(OH_Rdb_Subscribe(nullptr, RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS, &observer), RDB_E_INVALID_ARGS); +} + +/** + * @tc.name: RDB_Native_store_test_033 + * @tc.desc: abNormal testCase for OH_Rdb_Subscribe. + * 1.subscribe type is invalid + * 2.observer is invalid + * 2.register observer for local database + * @tc.type: FUNC + */ +HWTEST_F(RdbNativeStoreTest, RDB_Native_store_test_033, TestSize.Level1) +{ + EXPECT_NE(storeTestRdbStore_, nullptr); + + Rdb_DetailsObserver callback = LocalDataChangeObserverCallback7; + Rdb_DataObserver observer1 = { nullptr, { callback } }; + int errCode = OH_Rdb_Subscribe(nullptr, static_cast(RDB_SUBSCRIBE_TYPE_CLOUD - 1), &observer1); + EXPECT_EQ(RDB_E_INVALID_ARGS, errCode); + errCode = + OH_Rdb_Subscribe(nullptr, static_cast(RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS + 1), &observer1); + EXPECT_EQ(RDB_E_INVALID_ARGS, errCode); + + Rdb_DataObserver observer2 = { nullptr, { nullptr } }; + errCode = OH_Rdb_Subscribe(storeTestRdbStore_, RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS, &observer2); + EXPECT_EQ(RDB_E_INVALID_ARGS, errCode); + errCode = OH_Rdb_Subscribe(storeTestRdbStore_, RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS, nullptr); + EXPECT_EQ(RDB_E_INVALID_ARGS, errCode); + + errCode = OH_Rdb_Unsubscribe(nullptr, static_cast(RDB_SUBSCRIBE_TYPE_CLOUD - 1), &observer1); + EXPECT_EQ(RDB_E_INVALID_ARGS, errCode); + errCode = + OH_Rdb_Unsubscribe(nullptr, static_cast(RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS + 1), &observer1); + EXPECT_EQ(RDB_E_INVALID_ARGS, errCode); +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index c1b66c56..71e12da6 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -58,10 +58,13 @@ aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/../datamgr_service/services/dis aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/../datamgr_service/services/distributeddataservice/adapter/test DataMgrTestSrc) add_executable(DataMgrServiceTest ${DataMgrTestSrc} ${mainSrc} ${serviceSrc}) target_link_libraries(DataMgrServiceTest ${links} gtest_main gcov relational_store data_share preferences distributeddb data_object kvdb udmf) +target_include_directories(DataMgrServiceTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../datamgr_service/services/distributeddataservice/adapter/account/src) +target_include_directories(DataMgrServiceTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../datamgr_service/services/distributeddataservice/adapter/communicator/src) target_include_directories(DataMgrServiceTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../datamgr_service/services/distributeddataservice/service/backup/include) 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/cloud) 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) @@ -75,6 +78,7 @@ target_include_directories(DataMgrServiceTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR target_include_directories(DataMgrServiceTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../datamgr_service/services/distributeddataservice/service/udmf/preprocess) target_include_directories(DataMgrServiceTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../datamgr_service/services/distributeddataservice/service/udmf/store) 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/test/mock) 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/) diff --git a/udmf/BUILD.gn b/udmf/BUILD.gn index 32d165c9..4ad46294 100644 --- a/udmf/BUILD.gn +++ b/udmf/BUILD.gn @@ -17,6 +17,7 @@ group("udmf_packages") { if (is_standard_system) { deps = [ "interfaces/innerkits:udmf_client", + "interfaces/innerkits:utd_client", "interfaces/jskits:udmf_data_napi", "interfaces/jskits:unifieddatachannel_napi", "interfaces/jskits:uniformtypedescriptor_napi", diff --git a/udmf/bundle.json b/udmf/bundle.json index f79fb11f..69f4b376 100644 --- a/udmf/bundle.json +++ b/udmf/bundle.json @@ -28,8 +28,10 @@ "ability_runtime", "access_token", "bundle_framework", + "cJSON", "c_utils", "hilog", + "hisysevent", "hitrace", "image_framework", "ipc", @@ -40,8 +42,7 @@ "selinux_adapter" ], "third_party": [ - "bounds_checking_function", - "cJSON" + "bounds_checking_function" ] }, "build": { @@ -115,6 +116,24 @@ ], "header_base":"//foundation/distributeddatamgr/udmf/interfaces/jskits/common" } + }, + { + "name": "//foundation/distributeddatamgr/udmf/interfaces/innerkits:utd_client", + "header": { + "header_files": [ + "utd_client.h" + ], + "header_base":"//foundation/distributeddatamgr/udmf/interfaces/innerkits/client" + } + }, + { + "name": "//foundation/distributeddatamgr/udmf/interfaces/innerkits:utd_client", + "header": { + "header_files": [ + "type_descriptor.h" + ], + "header_base":"//foundation/distributeddatamgr/udmf/interfaces/innerkits/data" + } } ], "test": [ diff --git a/udmf/framework/common/custom_utd_json_parser.cpp b/udmf/framework/common/custom_utd_json_parser.cpp index 7d5be8c1..b492f41c 100644 --- a/udmf/framework/common/custom_utd_json_parser.cpp +++ b/udmf/framework/common/custom_utd_json_parser.cpp @@ -121,8 +121,7 @@ bool CustomUtdJsonParser::GetTypeDescriptors(const json &jsonRoot, const std::st cJSON *node = cJSON_GetArrayItem(subNode, i); TypeDescriptorCfg typeCfg; typeCfg.typeId = GetStringValue(*node, TYPEID); - std::vector belongingToTypes = GetStringArrayValue(*node, BELONGINGTOTYPES); - typeCfg.belongingToTypes.insert(belongingToTypes.begin(), belongingToTypes.end()); + typeCfg.belongingToTypes = GetStringArrayValue(*node, BELONGINGTOTYPES); typeCfg.filenameExtensions = GetStringArrayValue(*node, FILE_NAME_EXTENSTENSIONS); typeCfg.mimeTypes = GetStringArrayValue(*node, MIME_TYPES); typeCfg.description = GetStringValue(*node, DESCRIPTION); diff --git a/udmf/framework/common/custom_utd_json_parser.h b/udmf/framework/common/custom_utd_json_parser.h index 310cfa63..fe2d259d 100644 --- a/udmf/framework/common/custom_utd_json_parser.h +++ b/udmf/framework/common/custom_utd_json_parser.h @@ -25,7 +25,7 @@ #include "utd_common.h" namespace OHOS { namespace UDMF { -class CustomUtdJsonParser { +class API_EXPORT CustomUtdJsonParser { public: using json = cJSON; CustomUtdJsonParser(); diff --git a/udmf/framework/common/custom_utd_store.h b/udmf/framework/common/custom_utd_store.h index b617e604..105ed623 100644 --- a/udmf/framework/common/custom_utd_store.h +++ b/udmf/framework/common/custom_utd_store.h @@ -25,7 +25,7 @@ #include "custom_utd_json_parser.h" namespace OHOS { namespace UDMF { -class CustomUtdStore { +class API_EXPORT CustomUtdStore { public: static CustomUtdStore &GetInstance(); std::vector GetTypeCfgs(const std::string &cfgFilePath); diff --git a/udmf/framework/common/graph.cpp b/udmf/framework/common/graph.cpp index 7ac8a11a..9c588411 100644 --- a/udmf/framework/common/graph.cpp +++ b/udmf/framework/common/graph.cpp @@ -42,7 +42,6 @@ bool Graph::Dfs(uint32_t startNode, Action action, bool isInit) EdgeNode *edge = nullptr; visited_[startNode] = 1; nodes.push(startNode); - result_.push_back(startNode); if (action(adjList_[startNode].value)) { return true; } @@ -51,26 +50,19 @@ bool Graph::Dfs(uint32_t startNode, Action action, bool isInit) while (edge) { if (visited_[edge->adjIndex] == 0) { visited_[edge->adjIndex] = 1; - if (adjList_[edge->adjIndex].firstEdge != nullptr) { - auto iter = find(result_.begin(), result_.end(), adjList_[edge->adjIndex].firstEdge->adjIndex); - if (iter != result_.end() && visited_[adjList_[edge->adjIndex].firstEdge->adjIndex] == 1) { - return false; // current node, iscycle - } - } + nodes.push(edge->adjIndex); if (action(adjList_[edge->adjIndex].value)) { return true; } - result_.push_back(startNode); - nodes.push(edge->adjIndex); edge = adjList_[edge->adjIndex].firstEdge; + } else if (visited_[edge->adjIndex] == 1) { + return false; } else { edge = edge->next; } } - if (edge == nullptr) { - visited_[nodes.top()] = 2; // 2: all edge of the adj is visited. - nodes.pop(); - } + visited_[nodes.top()] = 2; // 2: all edge of the adj is visited. + nodes.pop(); } return true; } @@ -79,7 +71,6 @@ bool Graph::DfsUnconnectedGraph(Action action) { visited_.resize(vertexNum_); fill(visited_.begin(), visited_.end(), 0); - result_.clear(); for (uint32_t node = 0; node < vertexNum_; node++) { if (!visited_[node]) { if (!Dfs(node, action, false)) { diff --git a/udmf/framework/common/graph.h b/udmf/framework/common/graph.h index 39b58f5c..cdff7e23 100644 --- a/udmf/framework/common/graph.h +++ b/udmf/framework/common/graph.h @@ -44,7 +44,6 @@ private: uint32_t vertexNum_; std::vector adjList_; // Adjacency List std::vector visited_; // Determine whether the vertex has been accessed, index=vertex value - std::vector result_; }; } // namespace UDMF } // namespace OHOS diff --git a/udmf/framework/common/tlv_object.h b/udmf/framework/common/tlv_object.h index c730630b..c4f83b47 100644 --- a/udmf/framework/common/tlv_object.h +++ b/udmf/framework/common/tlv_object.h @@ -22,7 +22,7 @@ #include "unified_meta.h" #include "unified_types.h" #include "endian_converter.h" - +#include "visibility.h" namespace OHOS { namespace UDMF { enum class TAG { @@ -46,7 +46,7 @@ struct TLVHead { }; #pragma pack() -class TLVObject { +class API_EXPORT TLVObject { public: TLVObject() = default; ~TLVObject() = default; diff --git a/udmf/framework/common/tlv_util.cpp b/udmf/framework/common/tlv_util.cpp index bd71df5f..cc0dab62 100644 --- a/udmf/framework/common/tlv_util.cpp +++ b/udmf/framework/common/tlv_util.cpp @@ -12,9 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +#define LOG_TAG "TlvUtil" #include "tlv_util.h" +#include "logger.h" + namespace OHOS { namespace TLVUtil { template<> @@ -233,6 +235,7 @@ bool CountBufferSize(const Runtime &input, TLVObject &data) data.Count(input.createPackage); data.Count(input.deviceId); data.Count(input.recordTotalNum); + data.Count(input.tokenId); return true; } @@ -1400,6 +1403,9 @@ bool Writing(const Runtime &input, TLVObject &data) if (!Writing(input.recordTotalNum, data)) { return false; } + if (!Writing(input.tokenId, data)) { + return false; + } return true; } @@ -1418,6 +1424,7 @@ bool Reading(Runtime &output, TLVObject &data) std::string createPackage; std::string deviceId; uint32_t recordTotalNum; + uint32_t tokenId = 0; if (!Reading(key, data)) { return false; } @@ -1458,6 +1465,9 @@ bool Reading(Runtime &output, TLVObject &data) if (!Reading(recordTotalNum, data)) { return false; } + if (!Reading(tokenId, data)) { + LOG_WARN(UDMF_CLIENT, "Reading tokenId empty."); + } output.key = key; output.isPrivate = isPrivate; output.privileges = privileges; @@ -1469,6 +1479,7 @@ bool Reading(Runtime &output, TLVObject &data) output.createPackage = createPackage; output.deviceId = deviceId; output.recordTotalNum = recordTotalNum; + output.tokenId = tokenId; return true; } } // namespace TLVUtil diff --git a/udmf/framework/common/tlv_util.h b/udmf/framework/common/tlv_util.h index e3d330b0..6767dfa9 100644 --- a/udmf/framework/common/tlv_util.h +++ b/udmf/framework/common/tlv_util.h @@ -17,7 +17,7 @@ #define UDMF_TLV_UTIL_H #include - +#include "visibility.h" #include "application_defined_record.h" #include "audio.h" #include "file.h" @@ -43,181 +43,181 @@ namespace OHOS { namespace TLVUtil { using namespace OHOS::UDMF; template -bool CountBufferSize(const T &input, TLVObject &data); +bool API_EXPORT CountBufferSize(const T &input, TLVObject &data); template<> -bool CountBufferSize(const std::shared_ptr &input, TLVObject &data); +bool API_EXPORT CountBufferSize(const std::shared_ptr &input, TLVObject &data); template<> -bool CountBufferSize(const Runtime &input, TLVObject &data); +bool API_EXPORT CountBufferSize(const Runtime &input, TLVObject &data); template<> -bool CountBufferSize(const UnifiedData &input, TLVObject &data); +bool API_EXPORT CountBufferSize(const UnifiedData &input, TLVObject &data); template<> -bool CountBufferSize(const std::vector &input, TLVObject &data); +bool API_EXPORT CountBufferSize(const std::vector &input, TLVObject &data); template -bool Writing(const T &input, TLVObject &data); +bool API_EXPORT Writing(const T &input, TLVObject &data); template -bool Reading(T &output, TLVObject &data); +bool API_EXPORT Reading(T &output, TLVObject &data); template<> -bool Writing(const int32_t &input, TLVObject &data); +bool API_EXPORT Writing(const int32_t &input, TLVObject &data); template<> -bool Reading(int32_t &output, TLVObject &data); +bool API_EXPORT Reading(int32_t &output, TLVObject &data); template<> -bool Writing(const int64_t &input, TLVObject &data); +bool API_EXPORT Writing(const int64_t &input, TLVObject &data); template<> -bool Reading(int64_t &output, TLVObject &data); +bool API_EXPORT Reading(int64_t &output, TLVObject &data); template<> -bool Writing(const bool &input, TLVObject &data); +bool API_EXPORT Writing(const bool &input, TLVObject &data); template<> -bool Reading(bool &output, TLVObject &data); +bool API_EXPORT Reading(bool &output, TLVObject &data); template<> -bool Reading(uint32_t &output, TLVObject &data); +bool API_EXPORT Reading(uint32_t &output, TLVObject &data); template<> -bool Writing(const uint32_t &input, TLVObject &data); +bool API_EXPORT Writing(const uint32_t &input, TLVObject &data); template<> -bool Reading(uint64_t &output, TLVObject &data); +bool API_EXPORT Reading(uint64_t &output, TLVObject &data); template<> -bool Writing(const uint64_t &input, TLVObject &data); +bool API_EXPORT Writing(const uint64_t &input, TLVObject &data); template<> -bool Writing(const std::string &input, TLVObject &data); +bool API_EXPORT Writing(const std::string &input, TLVObject &data); template<> -bool Reading(std::string &output, TLVObject &data); +bool API_EXPORT Reading(std::string &output, TLVObject &data); template<> -bool Writing(const std::vector &input, TLVObject &data); +bool API_EXPORT Writing(const std::vector &input, TLVObject &data); template<> -bool Reading(std::vector &output, TLVObject &data); +bool API_EXPORT Reading(std::vector &output, TLVObject &data); template<> -bool Writing(const UDVariant &input, TLVObject &data); +bool API_EXPORT Writing(const UDVariant &input, TLVObject &data); template<> -bool Reading(UDVariant &output, TLVObject &data); +bool API_EXPORT Reading(UDVariant &output, TLVObject &data); template<> -bool Writing(const UDDetails &input, TLVObject &data); +bool API_EXPORT Writing(const UDDetails &input, TLVObject &data); template<> -bool Reading(UDDetails &output, TLVObject &data); +bool API_EXPORT Reading(UDDetails &output, TLVObject &data); template<> -bool Writing(const UDType &input, TLVObject &data); +bool API_EXPORT Writing(const UDType &input, TLVObject &data); template<> -bool Reading(UDType &output, TLVObject &data); +bool API_EXPORT Reading(UDType &output, TLVObject &data); template<> -bool Writing(const Text &input, TLVObject &data); +bool API_EXPORT Writing(const Text &input, TLVObject &data); template<> -bool Reading(Text &output, TLVObject &data); +bool API_EXPORT Reading(Text &output, TLVObject &data); template<> -bool Writing(const PlainText &input, TLVObject &data); +bool API_EXPORT Writing(const PlainText &input, TLVObject &data); template<> -bool Reading(PlainText &output, TLVObject &data); +bool API_EXPORT Reading(PlainText &output, TLVObject &data); template<> -bool Writing(const Html &input, TLVObject &data); +bool API_EXPORT Writing(const Html &input, TLVObject &data); template<> -bool Reading(Html &output, TLVObject &data); +bool API_EXPORT Reading(Html &output, TLVObject &data); template<> -bool Writing(const Link &input, TLVObject &data); +bool API_EXPORT Writing(const Link &input, TLVObject &data); template<> -bool Reading(Link &output, TLVObject &data); +bool API_EXPORT Reading(Link &output, TLVObject &data); template<> -bool Writing(const File &input, TLVObject &data); +bool API_EXPORT Writing(const File &input, TLVObject &data); template<> -bool Reading(File &output, TLVObject &data); +bool API_EXPORT Reading(File &output, TLVObject &data); template<> -bool Writing(const Image &input, TLVObject &data); +bool API_EXPORT Writing(const Image &input, TLVObject &data); template<> -bool Reading(Image &output, TLVObject &data); +bool API_EXPORT Reading(Image &output, TLVObject &data); template<> -bool Writing(const Video &input, TLVObject &data); +bool API_EXPORT Writing(const Video &input, TLVObject &data); template<> -bool Reading(Video &output, TLVObject &data); +bool API_EXPORT Reading(Video &output, TLVObject &data); template<> -bool Writing(const Audio &input, TLVObject &data); +bool API_EXPORT Writing(const Audio &input, TLVObject &data); template<> -bool Reading(Audio &output, TLVObject &data); +bool API_EXPORT Reading(Audio &output, TLVObject &data); template<> -bool Writing(const Folder &input, TLVObject &data); +bool API_EXPORT Writing(const Folder &input, TLVObject &data); template<> -bool Reading(Folder &output, TLVObject &data); +bool API_EXPORT Reading(Folder &output, TLVObject &data); template<> -bool Writing(const SystemDefinedRecord &input, TLVObject &data); +bool API_EXPORT Writing(const SystemDefinedRecord &input, TLVObject &data); template<> -bool Reading(SystemDefinedRecord &output, TLVObject &data); +bool API_EXPORT Reading(SystemDefinedRecord &output, TLVObject &data); template<> -bool Writing(const SystemDefinedForm &input, TLVObject &data); +bool API_EXPORT Writing(const SystemDefinedForm &input, TLVObject &data); template<> -bool Reading(SystemDefinedForm &output, TLVObject &data); +bool API_EXPORT Reading(SystemDefinedForm &output, TLVObject &data); template<> -bool Writing(const SystemDefinedAppItem &input, TLVObject &data); +bool API_EXPORT Writing(const SystemDefinedAppItem &input, TLVObject &data); template<> -bool Reading(SystemDefinedAppItem &output, TLVObject &data); +bool API_EXPORT Reading(SystemDefinedAppItem &output, TLVObject &data); template<> -bool Writing(const SystemDefinedPixelMap &input, TLVObject &data); +bool API_EXPORT Writing(const SystemDefinedPixelMap &input, TLVObject &data); template<> -bool Reading(SystemDefinedPixelMap &output, TLVObject &data); +bool API_EXPORT Reading(SystemDefinedPixelMap &output, TLVObject &data); template<> -bool Writing(const ApplicationDefinedRecord &input, TLVObject &data); +bool API_EXPORT Writing(const ApplicationDefinedRecord &input, TLVObject &data); template<> -bool Reading(ApplicationDefinedRecord &output, TLVObject &data); +bool API_EXPORT Reading(ApplicationDefinedRecord &output, TLVObject &data); template<> -bool Writing(const std::shared_ptr &input, TLVObject &data); +bool API_EXPORT Writing(const std::shared_ptr &input, TLVObject &data); template<> -bool Reading(std::shared_ptr &output, TLVObject &data); +bool API_EXPORT Reading(std::shared_ptr &output, TLVObject &data); template<> -bool Writing(const UnifiedData &input, TLVObject &data); +bool API_EXPORT Writing(const UnifiedData &input, TLVObject &data); template<> -bool Reading(UnifiedData &output, TLVObject &data); +bool API_EXPORT Reading(UnifiedData &output, TLVObject &data); template<> -bool Writing(const std::vector &input, TLVObject &data); +bool API_EXPORT Writing(const std::vector &input, TLVObject &data); template<> -bool Reading(std::vector &output, TLVObject &data); +bool API_EXPORT Reading(std::vector &output, TLVObject &data); template<> -bool Writing(const UnifiedKey &input, TLVObject &data); +bool API_EXPORT Writing(const UnifiedKey &input, TLVObject &data); template<> -bool Reading(UnifiedKey &output, TLVObject &data); +bool API_EXPORT Reading(UnifiedKey &output, TLVObject &data); template<> -bool Writing(const Privilege &input, TLVObject &data); +bool API_EXPORT Writing(const Privilege &input, TLVObject &data); template<> -bool Reading(Privilege &output, TLVObject &data); +bool API_EXPORT Reading(Privilege &output, TLVObject &data); template<> -bool Writing(const DataStatus &input, TLVObject &data); +bool API_EXPORT Writing(const DataStatus &input, TLVObject &data); template<> -bool Reading(DataStatus &output, TLVObject &data); +bool API_EXPORT Reading(DataStatus &output, TLVObject &data); template<> -bool Writing(const Runtime &input, TLVObject &data); +bool API_EXPORT Writing(const Runtime &input, TLVObject &data); template<> -bool Reading(Runtime &output, TLVObject &data); +bool API_EXPORT Reading(Runtime &output, TLVObject &data); } // namespace TLVUtil } // namespace OHOS #endif // UDMF_TLV_UTIL_H \ No newline at end of file diff --git a/udmf/framework/common/udmf_radar_reporter.h b/udmf/framework/common/udmf_radar_reporter.h new file mode 100644 index 00000000..378f523f --- /dev/null +++ b/udmf/framework/common/udmf_radar_reporter.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UDMF_RADAR_REPORTER_H +#define UDMF_RADAR_REPORTER_H + +#include "hisysevent.h" + +namespace OHOS { +namespace UDMF { +namespace RadarReporter { +enum BizScene : std::int32_t { + SET_DATA = 1, + SYNC_DATA = 2, + GET_DATA = 3, + UTD_REGISTER = 4 +}; + +enum SetDataStage : std::int32_t { + SET_DATA_BEGIN = 1, + VERIFY_SHARE_PERMISSIONS = 2, + GERERATE_DFS_URI = 3, + SET_DATA_END = 4 +}; + +enum SyncDataStage : std::int32_t { + SYNC_BEGIN = 1, + SYNC_END = 2 +}; + +enum GetDataStage : std::int32_t { + GET_DATA_BEGIN = 1, + VERIFY_PRIVILEGE = 2, + GRANT_URI_PERMISSION = 3, + GET_DATA_END = 4 +}; + +enum UtdRegisterStage : std::int32_t { + UTD_REGISTER_BEGIN = 1, + UTD_REGISTER_END = 2, +}; + +enum StageRes : std::int32_t { + IDLE = 0, + SUCCESS = 1, + FAILED = 2, + CANCELLED = 3 +}; +enum BizState : std::int32_t { + DFX_BEGIN = 0, + DFX_NORMAL_END = 1, + DFX_ABNORMAL_END = 2 +}; + +const constexpr char BIZ_STATE[] = "BIZ_STATE"; +const constexpr char ERROR_CODE[] = "ERROR_CODE"; +} // namespace RadarReporter + +const constexpr char DOMAIN[] = "DISTDATAMGR"; +const constexpr char EVENT_NAME[] = "DISTRIBUTED_UDMF_BEHAVIOR"; +const constexpr HiviewDFX::HiSysEvent::EventType TYPE = HiviewDFX::HiSysEvent::EventType::BEHAVIOR; +const constexpr char ORG_PKG[] = "distributeddata"; + +#define RADAR_REPORT(bizScene, bizStage, stageRes, ...) \ +({ \ + HiSysEventWrite(DOMAIN, EVENT_NAME, TYPE, "ORG_PKG", ORG_PKG, "FUNC", __FUNCTION__, \ + "BIZ_SCENE", bizScene, "BIZ_STAGE", bizStage, "STAGE_RES", stageRes, ##__VA_ARGS__); \ +}) +} // namespace UDMF +} // namespace OHOS +#endif // UDMF_RADAR_REPORTER_H \ No newline at end of file diff --git a/udmf/framework/common/udmf_types_util.h b/udmf/framework/common/udmf_types_util.h index 53f181cc..e2170d8b 100644 --- a/udmf/framework/common/udmf_types_util.h +++ b/udmf/framework/common/udmf_types_util.h @@ -15,7 +15,7 @@ #ifndef UDMF_TYPES_UTIL_H #define UDMF_TYPES_UTIL_H - +#include "visibility.h" #include "itypes_util.h" #include "unified_data.h" @@ -33,44 +33,44 @@ using UDType = UDMF::UDType; using Intention = UDMF::Intention; template<> -bool Marshalling(const UnifiedData &input, MessageParcel &parcel); +bool API_EXPORT Marshalling(const UnifiedData &input, MessageParcel &parcel); template<> -bool Unmarshalling(UnifiedData &output, MessageParcel &parcel); +bool API_EXPORT Unmarshalling(UnifiedData &output, MessageParcel &parcel); template<> -bool Marshalling(const std::vector &input, MessageParcel &parcel); +bool API_EXPORT Marshalling(const std::vector &input, MessageParcel &parcel); template<> -bool Unmarshalling(std::vector &output, MessageParcel &parcel); +bool API_EXPORT Unmarshalling(std::vector &output, MessageParcel &parcel); template<> -bool Marshalling(const Summary &input, MessageParcel &parcel); +bool API_EXPORT Marshalling(const Summary &input, MessageParcel &parcel); template<> -bool Unmarshalling(Summary &output, MessageParcel &parcel); +bool API_EXPORT Unmarshalling(Summary &output, MessageParcel &parcel); template<> -bool Marshalling(const Privilege &input, MessageParcel &parcel); +bool API_EXPORT Marshalling(const Privilege &input, MessageParcel &parcel); template<> -bool Unmarshalling(Privilege &output, MessageParcel &parcel); +bool API_EXPORT Unmarshalling(Privilege &output, MessageParcel &parcel); template<> -bool Marshalling(const CustomOption &input, MessageParcel &parcel); +bool API_EXPORT Marshalling(const CustomOption &input, MessageParcel &parcel); template<> -bool Unmarshalling(CustomOption &output, MessageParcel &parcel); +bool API_EXPORT Unmarshalling(CustomOption &output, MessageParcel &parcel); template<> -bool Marshalling(const QueryOption &input, MessageParcel &parcel); +bool API_EXPORT Marshalling(const QueryOption &input, MessageParcel &parcel); template<> -bool Unmarshalling(QueryOption &output, MessageParcel &parcel); +bool API_EXPORT Unmarshalling(QueryOption &output, MessageParcel &parcel); template<> -bool Marshalling(const UDType &input, MessageParcel &parcel); +bool API_EXPORT Marshalling(const UDType &input, MessageParcel &parcel); template<> -bool Unmarshalling(UDType &output, MessageParcel &parcel); +bool API_EXPORT Unmarshalling(UDType &output, MessageParcel &parcel); template<> -bool Marshalling(const Intention &input, MessageParcel &parcel); +bool API_EXPORT Marshalling(const Intention &input, MessageParcel &parcel); template<> -bool Unmarshalling(Intention &output, MessageParcel &parcel); +bool API_EXPORT Unmarshalling(Intention &output, MessageParcel &parcel); } // namespace ITypesUtil } // namespace OHOS #endif // UDMF_TYPES_UTIL_H \ No newline at end of file diff --git a/udmf/framework/common/udmf_utils.cpp b/udmf/framework/common/udmf_utils.cpp index 4733d6c5..45d9935b 100644 --- a/udmf/framework/common/udmf_utils.cpp +++ b/udmf/framework/common/udmf_utils.cpp @@ -13,10 +13,18 @@ * limitations under the License. */ #include "udmf_utils.h" +#include +#include #include + namespace OHOS { namespace UDMF { namespace UTILS { +static constexpr int ID_LEN = 32; +static constexpr int MINIMUM = 48; +static constexpr int MAXIMUM = 121; +const char SPECIAL = '^'; + std::vector StrSplit(std::string str, std::string subStr) { std::vector result; @@ -29,6 +37,29 @@ std::vector StrSplit(std::string str, std::string subStr) } return result; } + +std::vector Random(int32_t len, int32_t minimum, int32_t maximum) +{ + std::random_device randomDevice; + std::uniform_int_distribution distribution(minimum, maximum); + std::vector key(len); + for (int32_t i = 0; i < len; i++) { + key[i] = static_cast(distribution(randomDevice)); + } + return key; +} + +std::string GenerateId() +{ + std::vector randomDevices = Random(ID_LEN, MINIMUM, MAXIMUM); + std::stringstream idStr; + for (auto &randomDevice : randomDevices) { + auto asc = randomDevice; + asc = asc >= SPECIAL ? asc + 1 : asc; + idStr << static_cast(asc); + } + return idStr.str(); +} } // namespace UTILS } // namespace UDMF } // namespace OHOS \ No newline at end of file diff --git a/udmf/framework/common/udmf_utils.h b/udmf/framework/common/udmf_utils.h index 6fac1681..87a60680 100644 --- a/udmf/framework/common/udmf_utils.h +++ b/udmf/framework/common/udmf_utils.h @@ -18,10 +18,15 @@ #include #include +#include namespace OHOS { namespace UDMF { namespace UTILS { std::vector StrSplit(std::string str, std::string subStr); +std::vector Random(int32_t len, int32_t minimum = 0, + int32_t maximum = std::numeric_limits::max()); +std::string GenerateId(); + } // namespace UTILS } // namespace UDMF } // namespace OHOS diff --git a/udmf/framework/common/utd_cfgs_checker.h b/udmf/framework/common/utd_cfgs_checker.h index ff5727cd..07ef9a80 100644 --- a/udmf/framework/common/utd_cfgs_checker.h +++ b/udmf/framework/common/utd_cfgs_checker.h @@ -16,9 +16,10 @@ #ifndef UDMF_UTD_CFGS_CHERCKER_H #define UDMF_UTD_CFGS_CHERCKER_H #include "utd_common.h" +#include "visibility.h" namespace OHOS { namespace UDMF { -class UtdCfgsChecker { +class API_EXPORT UtdCfgsChecker { public: static UtdCfgsChecker &GetInstance(); bool CheckTypeDescriptors(CustomUtdCfgs &typeCfgs, const std::vector &presetCfgs, diff --git a/udmf/framework/common/utd_common.h b/udmf/framework/common/utd_common.h index ac621f7e..0fbd28e1 100644 --- a/udmf/framework/common/utd_common.h +++ b/udmf/framework/common/utd_common.h @@ -25,7 +25,7 @@ struct TypeDescriptorCfg; using CustomUtdCfgs = std::pair, std::vector>; struct TypeDescriptorCfg { std::string typeId; - std::set belongingToTypes; + std::vector belongingToTypes; std::vector filenameExtensions; std::vector mimeTypes; std::string description; diff --git a/udmf/framework/common/utd_graph.cpp b/udmf/framework/common/utd_graph.cpp index 01b9da0e..5a269673 100644 --- a/udmf/framework/common/utd_graph.cpp +++ b/udmf/framework/common/utd_graph.cpp @@ -55,13 +55,13 @@ void UtdGraph::InitUtdGraph(const std::vector &descriptorCfgs { typeIdIndex_.clear(); uint32_t descriptorsNum = static_cast(descriptorCfgs.size()); - std::unique_lock Lock(graphMutex_); + std::unique_lock Lock(graphMutex_); graph_ = new Graph(descriptorsNum); for (uint32_t i = 0; i < descriptorsNum; i++) { typeIdIndex_.insert(std::make_pair(descriptorCfgs[i].typeId, i)); } for (const auto &descriptorCfg : descriptorCfgs) { - std::set belongsTo = descriptorCfg.belongingToTypes; + std::vector belongsTo = descriptorCfg.belongingToTypes; for (auto belongsToType : belongsTo) { AddEdge(belongsToType, descriptorCfg.typeId); } @@ -91,7 +91,7 @@ bool UtdGraph::IsLowerLevelType(const std::string &lowerLevelType, const std::st } uint32_t uStart = static_cast(start); uint32_t uEnd = static_cast(end); - std::shared_lock Lock(graphMutex_); + std::unique_lock Lock(graphMutex_); graph_->Dfs(uStart, [&isFind, &uEnd](uint32_t currNode)-> bool { if (uEnd == currNode) { isFind = true; @@ -104,7 +104,7 @@ bool UtdGraph::IsLowerLevelType(const std::string &lowerLevelType, const std::st bool UtdGraph::IsDAG() { - std::shared_lock Lock(graphMutex_); + std::unique_lock Lock(graphMutex_); return graph_->DfsUnconnectedGraph([&](uint32_t currNode) -> bool {return false; }); } } // namespace UDMF diff --git a/udmf/framework/common/utd_graph.h b/udmf/framework/common/utd_graph.h index 877487c1..db4c491d 100644 --- a/udmf/framework/common/utd_graph.h +++ b/udmf/framework/common/utd_graph.h @@ -41,7 +41,7 @@ private: UtdGraph &operator=(const UtdGraph &obj) = delete; int32_t GetIndex(const std::string &node); void AddEdge(const std::string &startNode, const std::string &endNode); - mutable std::shared_mutex graphMutex_; + std::mutex graphMutex_; Graph *graph_ = nullptr; std::map typeIdIndex_; }; diff --git a/udmf/framework/innerkitsimpl/client/udmf_client.cpp b/udmf/framework/innerkitsimpl/client/udmf_client.cpp index 0bf79a9a..64f53122 100644 --- a/udmf/framework/innerkitsimpl/client/udmf_client.cpp +++ b/udmf/framework/innerkitsimpl/client/udmf_client.cpp @@ -16,34 +16,68 @@ #include "udmf_client.h" #include "dds_trace.h" +#include "udmf_radar_reporter.h" #include "error_code.h" #include "logger.h" #include "udmf_service_client.h" +#include "udmf_utils.h" +#include "accesstoken_kit.h" +#include "ipc_skeleton.h" +#include "unified_data_helper.h" namespace OHOS { namespace UDMF { const std::string TAG = "UdmfClient::"; using namespace OHOS::DistributedDataDfx; +using namespace RadarReporter; UdmfClient &UdmfClient::GetInstance() { - static auto instance_ = new UdmfClient(); - return *instance_; + static UdmfClient instance; + return instance; } Status UdmfClient::SetData(CustomOption &option, UnifiedData &unifiedData, std::string &key) { DdsTrace trace( std::string(TAG) + std::string(__FUNCTION__), TraceSwitch::BYTRACE_ON | TraceSwitch::TRACE_CHAIN_ON); + RADAR_REPORT(BizScene::SET_DATA, SetDataStage::SET_DATA_BEGIN, StageRes::IDLE, BIZ_STATE, BizState::DFX_BEGIN); auto service = UdmfServiceClient::GetInstance(); if (service == nullptr) { LOG_ERROR(UDMF_CLIENT, "Service unavailable"); + RADAR_REPORT(BizScene::SET_DATA, SetDataStage::SET_DATA_BEGIN, StageRes::FAILED, ERROR_CODE, E_IPC, + BIZ_STATE, BizState::DFX_ABNORMAL_END); return E_IPC; } + + if (option.intention == UD_INTENTION_DRAG) { + ShareOptions shareOption = SHARE_OPTIONS_BUTT; + auto status = GetAppShareOption(UD_INTENTION_MAP.at(option.intention), shareOption); + if (status != E_NOT_FOUND && status != E_OK) { + LOG_ERROR(UDMF_CLIENT, "get appShareOption fail, intention:%{public}s", + UD_INTENTION_MAP.at(option.intention).c_str()); + return static_cast(status); + } + if (shareOption == ShareOptions::IN_APP) { + std::string bundleName = "udmf.inapp.data"; + UnifiedKey udKey = UnifiedKey(UD_INTENTION_MAP.at(option.intention), bundleName, UTILS::GenerateId()); + key = udKey.GetUnifiedKey(); + dataCache_.Clear(); + dataCache_.Insert(key, unifiedData); + LOG_INFO(UDMF_CLIENT, "SetData in app success, bundleName:%{public}s.", bundleName.c_str()); + RADAR_REPORT(BizScene::SET_DATA, SetDataStage::SET_DATA_END, StageRes::SUCCESS, + BIZ_STATE, BizState::DFX_NORMAL_END); + return E_OK; + } + } int32_t ret = service->SetData(option, unifiedData, key); if (ret != E_OK) { + RADAR_REPORT(BizScene::SET_DATA, SetDataStage::SET_DATA_END, StageRes::FAILED, ERROR_CODE, ret, + BIZ_STATE, BizState::DFX_ABNORMAL_END); LOG_ERROR(UDMF_CLIENT, "failed! ret = %{public}d", ret); } + RADAR_REPORT(BizScene::SET_DATA, SetDataStage::SET_DATA_END, StageRes::SUCCESS, + BIZ_STATE, BizState::DFX_NORMAL_END); return static_cast(ret); } @@ -51,15 +85,32 @@ Status UdmfClient::GetData(const QueryOption &query, UnifiedData &unifiedData) { DdsTrace trace( std::string(TAG) + std::string(__FUNCTION__), TraceSwitch::BYTRACE_ON | TraceSwitch::TRACE_CHAIN_ON); + RADAR_REPORT(BizScene::GET_DATA, GetDataStage::GET_DATA_BEGIN, StageRes::IDLE, BIZ_STATE, BizState::DFX_BEGIN); + auto service = UdmfServiceClient::GetInstance(); if (service == nullptr) { LOG_ERROR(UDMF_CLIENT, "Service unavailable"); + RADAR_REPORT(BizScene::GET_DATA, GetDataStage::GET_DATA_BEGIN, StageRes::FAILED, ERROR_CODE, E_IPC, + BIZ_STATE, BizState::DFX_ABNORMAL_END); return E_IPC; } + auto it = dataCache_.Find(query.key); + if (it.first) { + unifiedData = it.second; + dataCache_.Erase(query.key); + RADAR_REPORT(BizScene::GET_DATA, GetDataStage::GET_DATA_END, StageRes::SUCCESS, + BIZ_STATE, BizState::DFX_NORMAL_END); + return E_OK; + } + LOG_WARN(UDMF_CLIENT, "query data from cache failed! key = %{public}s", query.key.c_str()); int32_t ret = service->GetData(query, unifiedData); if (ret != E_OK) { + RADAR_REPORT(BizScene::GET_DATA, GetDataStage::GET_DATA_END, StageRes::FAILED, ERROR_CODE, ret, + BIZ_STATE, BizState::DFX_ABNORMAL_END); LOG_ERROR(UDMF_CLIENT, "failed! ret = %{public}d", ret); } + RADAR_REPORT(BizScene::GET_DATA, GetDataStage::GET_DATA_END, StageRes::SUCCESS, + BIZ_STATE, BizState::DFX_NORMAL_END); return static_cast(ret); } @@ -120,6 +171,13 @@ Status UdmfClient::GetSummary(const QueryOption &query, Summary &summary) LOG_ERROR(UDMF_CLIENT, "Service unavailable"); return E_IPC; } + auto it = dataCache_.Find(query.key); + if (it.first) { + UnifiedDataHelper::GetSummary(it.second, summary); + LOG_INFO(UDMF_CLIENT, "GetSummary in cache! key = %{public}s", query.key.c_str()); + return E_OK; + } + int32_t ret = service->GetSummary(query, summary); if (ret != E_OK) { LOG_ERROR(UDMF_CLIENT, "failed! ret = %{public}d", ret); @@ -174,5 +232,69 @@ Status UdmfClient::IsRemoteData(const QueryOption &query, bool &result) } return static_cast(ret); } + +Status UdmfClient::SetAppShareOption(const std::string &intention, enum ShareOptions shareOption) +{ + DdsTrace trace( + std::string(TAG) + std::string(__FUNCTION__), TraceSwitch::BYTRACE_ON | TraceSwitch::TRACE_CHAIN_ON); + auto service = UdmfServiceClient::GetInstance(); + if (service == nullptr) { + LOG_ERROR(UDMF_CLIENT, "Service unavailable"); + return E_IPC; + } + int32_t ret = service->SetAppShareOption(intention, shareOption); + if (ret != E_OK) { + LOG_ERROR(UDMF_CLIENT, "failed! ret = %{public}d", ret); + } + return static_cast(ret); +} + +Status UdmfClient::GetAppShareOption(const std::string &intention, enum ShareOptions &shareOption) +{ + DdsTrace trace( + std::string(TAG) + std::string(__FUNCTION__), TraceSwitch::BYTRACE_ON | TraceSwitch::TRACE_CHAIN_ON); + auto service = UdmfServiceClient::GetInstance(); + if (service == nullptr) { + LOG_ERROR(UDMF_CLIENT, "Service unavailable"); + return E_IPC; + } + int32_t shareOptionRet = SHARE_OPTIONS_BUTT; + int32_t ret = service->GetAppShareOption(intention, shareOptionRet); + if (ShareOptionsUtil::IsValid(shareOptionRet)) { + shareOption = static_cast(shareOptionRet); + } + if (ret != E_OK) { + LOG_ERROR(UDMF_CLIENT, "failed! ret = %{public}d", ret); + } + return static_cast(ret); +} + + +Status UdmfClient::RemoveAppShareOption(const std::string &intention) +{ + DdsTrace trace( + std::string(TAG) + std::string(__FUNCTION__), TraceSwitch::BYTRACE_ON | TraceSwitch::TRACE_CHAIN_ON); + auto service = UdmfServiceClient::GetInstance(); + if (service == nullptr) { + LOG_ERROR(UDMF_CLIENT, "Service unavailable"); + return E_IPC; + } + int32_t ret = service->RemoveAppShareOption(intention); + if (ret != E_OK) { + LOG_ERROR(UDMF_CLIENT, "failed! ret = %{public}d", ret); + } + return static_cast(ret); +} + +std::string UdmfClient::GetSelfBundleName() +{ + uint32_t tokenId = IPCSkeleton::GetSelfTokenID(); + Security::AccessToken::HapTokenInfo hapInfo; + if (Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo) + != Security::AccessToken::AccessTokenKitRet::RET_SUCCESS) { + return ""; + } + return hapInfo.bundleName; +} } // namespace UDMF } // namespace OHOS \ No newline at end of file diff --git a/udmf/framework/innerkitsimpl/client/utd_client.cpp b/udmf/framework/innerkitsimpl/client/utd_client.cpp index 296568a9..331d2b11 100644 --- a/udmf/framework/innerkitsimpl/client/utd_client.cpp +++ b/udmf/framework/innerkitsimpl/client/utd_client.cpp @@ -14,6 +14,7 @@ */ #define LOG_TAG "UtdClient" #include +#include #include "utd_client.h" #include "logger.h" #include "utd_graph.h" @@ -173,5 +174,39 @@ Status UtdClient::GetUniformDataTypeByMIMEType(const std::string &mimeType, std: return Status::E_OK; } + +Status UtdClient::IsUtd(std::string typeId, bool &result) +{ + try { + if (typeId.empty()) { + result = false; + return Status::E_INVALID_PARAMETERS; + } + if (typeId[0] == '.' || find(typeId.begin(), typeId.end(), '/') != typeId.end()) { + result = false; + return Status::E_OK; + } + constexpr const char *preSetTypeIdRegexRule = + R"(^(general\.|openharmony\.|org\.|com\.|macos\.|debian\.|io\.|de\.|net\.)[a-z0-9-\.]+(\-[a-z0-9-]+)*$)"; + if (std::regex_match(typeId, std::regex(preSetTypeIdRegexRule))) { + result = true; + return Status::E_OK; + } + constexpr const char *customUtdRegexRule = + R"(^([A-Za-z][\w]*[A-Za-z\d])(\.([A-Za-z\d]+_?)+[A-Za-z\d]+){2,}(\.[A-Za-z\d]+[-|\.]?[A-Za-z\d]+)+)"; + if (std::regex_match(typeId, std::regex(customUtdRegexRule))) { + result = true; + return Status::E_OK; + } + result = false; + } catch (...) { + LOG_ERROR(UDMF_CLIENT, "exception, typeId:%{public}s", typeId.c_str()); + result = false; + return Status::E_ERROR; + } + LOG_ERROR(UDMF_CLIENT, "is not utd, typeId:%{public}s", typeId.c_str()); + return Status::E_OK; +} + } // namespace UDMF } // namespace OHOS diff --git a/udmf/framework/innerkitsimpl/common/unified_meta.cpp b/udmf/framework/innerkitsimpl/common/unified_meta.cpp index 5c9e3f7f..3c20802e 100644 --- a/udmf/framework/innerkitsimpl/common/unified_meta.cpp +++ b/udmf/framework/innerkitsimpl/common/unified_meta.cpp @@ -19,6 +19,448 @@ namespace OHOS { namespace UDMF { +static constexpr UtdType UTD_TYPES[] = { + { ENTITY, "ENTITY", "general.entity" }, + { OBJECT, "OBJECT", "general.object" }, + { COMPOSITE_OBJECT, "COMPOSITE_OBJECT", "general.composite-object" }, + { TEXT, "TEXT", "general.text" }, + { PLAIN_TEXT, "PLAIN_TEXT", "general.plain-text" }, + { HTML, "HTML", "general.html" }, + { HYPERLINK, "HYPERLINK", "general.hyperlink" }, + { XML, "XML", "general.xml" }, + { SOURCE_CODE, "SOURCE_CODE", "general.source-code" }, + { SCRIPT, "SCRIPT", "general.script" }, + { SHELL_SCRIPT, "SHELL_SCRIPT", "general.shell-script" }, + { CSH_SCRIPT, "CSH_SCRIPT", "general.csh-script" }, + { PERL_SCRIPT, "PERL_SCRIPT", "general.perl-script" }, + { PHP_SCRIPT, "PHP_SCRIPT", "general.php-script" }, + { PYTHON_SCRIPT, "PYTHON_SCRIPT", "general.python-script" }, + { RUBY_SCRIPT, "RUBY_SCRIPT", "general.ruby-script" }, + { TYPE_SCRIPT, "TYPE_SCRIPT", "general.type-script" }, + { JAVA_SCRIPT, "JAVA_SCRIPT", "general.java-script" }, + { C_HEADER, "C_HEADER", "general.c-header" }, + { C_SOURCE, "C_SOURCE", "general.c-source" }, + { C_PLUS_PLUS_HEADER, "C_PLUS_PLUS_HEADER", "general.c-plus-plus-header" }, + { C_PLUS_PLUS_SOURCE, "C_PLUS_PLUS_SOURCE", "general.c-plus-plus-source" }, + { JAVA_SOURCE, "JAVA_SOURCE", "general.java-source" }, + { EBOOK, "EBOOK", "general.ebook" }, + { EPUB, "EPUB", "general.epub" }, + { AZW, "AZW", "com.amazon.azw" }, + { AZW3, "AZW3", "com.amazon.azw3" }, + { KFX, "KFX", "com.amazon.kfx" }, + { MOBI, "MOBI", "com.amazon.mobi" }, + { MEDIA, "MEDIA", "general.media" }, + { IMAGE, "IMAGE", "general.image" }, + { JPEG, "JPEG", "general.jpeg" }, + { PNG, "PNG", "general.png" }, + { RAW_IMAGE, "RAW_IMAGE", "general.raw-image" }, + { TIFF, "TIFF", "general.tiff" }, + { BMP, "BMP", "com.microsoft.bmp" }, + { ICO, "ICO", "com.microsoft.ico" }, + { PHOTOSHOP_IMAGE, "PHOTOSHOP_IMAGE", "com.adobe.photoshop-image" }, + { AI_IMAGE, "AI_IMAGE", "com.adobe.illustrator.ai-image" }, + { WORD_DOC, "WORD_DOC", "com.microsoft.word.doc" }, + { EXCEL, "EXCEL", "com.microsoft.excel.xls" }, + { PPT, "PPT", "com.microsoft.powerpoint.ppt" }, + { PDF, "PDF", "com.adobe.pdf" }, + { POSTSCRIPT, "POSTSCRIPT", "com.adobe.postscript" }, + { ENCAPSULATED_POSTSCRIPT, "ENCAPSULATED_POSTSCRIPT", "com.adobe.encapsulated-postscript" }, + { VIDEO, "VIDEO", "general.video" }, + { AVI, "AVI", "general.avi" }, + { MPEG, "MPEG", "general.mpeg" }, + { MPEG4, "MPEG4", "general.mpeg-4" }, + { VIDEO_3GPP, "VIDEO_3GPP", "general.3gpp" }, + { VIDEO_3GPP2, "VIDEO_3GPP2", "general.3gpp2" }, + { WINDOWS_MEDIA_WM, "WINDOWS_MEDIA_WM", "com.microsoft.windows-media-wm" }, + { WINDOWS_MEDIA_WMV, "WINDOWS_MEDIA_WMV", "com.microsoft.windows-media-wmv" }, + { WINDOWS_MEDIA_WMP, "WINDOWS_MEDIA_WMP", "com.microsoft.windows-media-wmp" }, + { AUDIO, "AUDIO", "general.audio" }, + { AAC, "AAC", "general.aac" }, + { AIFF, "AIFF", "general.aiff" }, + { ALAC, "ALAC", "general.alac" }, + { FLAC, "FLAC", "general.flac" }, + { MP3, "MP3", "general.mp3" }, + { OGG, "OGG", "general.ogg" }, + { PCM, "PCM", "general.pcm" }, + { WINDOWS_MEDIA_WMA, "WINDOWS_MEDIA_WMA", "com.microsoft.windows-media-wma" }, + { WAVEFORM_AUDIO, "WAVEFORM_AUDIO", "com.microsoft.waveform-audio" }, + { WINDOWS_MEDIA_WMX, "WINDOWS_MEDIA_WMX", "com.microsoft.windows-media-wmx" }, + { WINDOWS_MEDIA_WVX, "WINDOWS_MEDIA_WVX", "com.microsoft.windows-media-wvx" }, + { WINDOWS_MEDIA_WAX, "WINDOWS_MEDIA_WAX", "com.microsoft.windows-media-wax" }, + { FILE, "FILE", "general.file" }, + { DIRECTORY, "DIRECTORY", "general.directory" }, + { FOLDER, "FOLDER", "general.folder" }, + { SYMLINK, "SYMLINK", "general.symlink" }, + { ARCHIVE, "ARCHIVE", "general.archive" }, + { BZ2_ARCHIVE, "BZ2_ARCHIVE", "general.bz2-archive" }, + { DISK_IMAGE, "DISK_IMAGE", "general.disk-image" }, + { TAR_ARCHIVE, "TAR_ARCHIVE", "general.tar-archive" }, + { ZIP_ARCHIVE, "ZIP_ARCHIVE", "general.zip-archive" }, + { JAVA_ARCHIVE, "JAVA_ARCHIVE", "com.sun.java-archive" }, + { GNU_TAR_ARCHIVE, "GNU_TAR_ARCHIVE", "org.gnu.gnu-tar-archive" }, + { GNU_ZIP_ARCHIVE, "GNU_ZIP_ARCHIVE", "org.gnu.gnu-zip-archive" }, + { GNU_ZIP_TAR_ARCHIVE, "GNU_ZIP_TAR_ARCHIVE", "org.gnu.gnu-zip-tar-archive" }, + { CALENDAR, "CALENDAR", "general.calendar" }, + { CONTACT, "CONTACT", "general.contact" }, + { DATABASE, "DATABASE", "general.database" }, + { MESSAGE, "MESSAGE", "general.message" }, + { VCARD, "VCARD", "general.vcard" }, + { NAVIGATION, "NAVIGATION", "general.navigation" }, + { LOCATION, "LOCATION", "general.location" }, + { SYSTEM_DEFINED_RECORD, "SYSTEM_DEFINED_RECORD", "SystemDefinedType" }, + { SYSTEM_DEFINED_FORM, "OPENHARMONY_FORM", "openharmony.form" }, + { SYSTEM_DEFINED_APP_ITEM, "OPENHARMONY_APP_ITEM", "openharmony.app-item" }, + { SYSTEM_DEFINED_PIXEL_MAP, "OPENHARMONY_PIXEL_MAP", "openharmony.pixel-map" }, + { OPENHARMONY_ATOMIC_SERVICE, "OPENHARMONY_ATOMIC_SERVICE", "openharmony.atomic-service" }, + { APPLICATION_DEFINED_RECORD, "APPLICATION_DEFINED_RECORD", "ApplicationDefinedType" }, + { OPENHARMONY_PACKAGE, "OPENHARMONY_PACKAGE", "openharmony.package" }, + { OPENHARMONY_HAP, "OPENHARMONY_HAP", "openharmony.hap" }, + { SMIL, "SMIL", "com.real.smil" }, + { MARKDOWN, "MARKDOWN", "general.markdown" }, + { FAX, "FAX", "general.fax" }, + { JFX_FAX, "JFX_FAX", "com.j2.jfx-fax" }, + { EFX_FAX, "EFX_FAX", "com.js.efx-fax" }, + { XBITMAP_IMAGE, "XBITMAP_IMAGE", "general.xbitmap-image" }, + { TGA_IMAGE, "TGA_IMAGE", "com.truevision.tga-image" }, + { SGI_IMAGE, "SGI_IMAGE", "com.sgi.sgi-image" }, + { OPENEXR_IMAGE, "OPENEXR_IMAGE", "com.ilm.openexr-image" }, + { FLASHPIX_IMAGE, "FLASHPIX_IMAGE", "com.kodak.flashpix.image" }, + { REALMEDIA, "REALMEDIA", "com.real.realmedia" }, + { AU_AUDIO, "AU_AUDIO", "general.au-audio" }, + { AIFC_AUDIO, "AIFC_AUDIO", "general.aifc-audio" }, + { SD2_AUDIO, "SD2_AUDIO", "com.digidesign.sd2-audio" }, + { REALAUDIO, "REALAUDIO", "com.real.realaudio" }, + { OPENXML, "OPENXML", "org.openxmlformats.openxml" }, + { WORDPROCESSINGML_DOCUMENT, "WORDPROCESSINGML_DOCUMENT", + "org.openxmlformats.wordprocessingml.document" }, + { SPREADSHEETML_SHEET, "SPREADSHEETML_SHEET", "org.openxmlformats.spreadsheetml.sheet" }, + { PRESENTATIONML_PRESENTATION, "PRESENTATIONML_PRESENTATION", + "org.openxmlformats.presentationml.presentation" }, + { OPENDOCUMENT, "OPENDOCUMENT", "org.oasis.opendocument" }, + { OPENDOCUMENT_TEXT, "OPENDOCUMENT_TEXT", "org.oasis.opendocument.text" }, + { OPENDOCUMENT_SPREADSHEET, "OPENDOCUMENT_SPREADSHEET", "org.oasis.opendocument.spreadsheet" }, + { OPENDOCUMENT_PRESENTATION, "OPENDOCUMENT_PRESENTATION", "org.oasis.opendocument.presentation" }, + { OPENDOCUMENT_GRAPHICS, "OPENDOCUMENT_GRAPHICS", "org.oasis.opendocument.graphics" }, + { OPENDOCUMENT_FORMULA, "OPENDOCUMENT_FORMULA", "org.oasis.opendocument.formula" }, + { STUFFIT_ARCHIVE, "STUFFIT_ARCHIVE", "com.allume.stuffit-archive" }, + { VCS, "VCS", "general.vcs" }, + { ICS, "ICS", "general.ics" }, + { EXECUTABLE, "EXECUTABLE", "general.executable" }, + { PORTABLE_EXECUTABLE, "PORTABLE_EXECUTABLE", "com.microsoft.portable-executable" }, + { SUN_JAVA_CLASS, "SUN_JAVA_CLASS", "com.sun.java-class" }, + { FONT, "FONT", "general.font" }, + { TRUETYPE_FONT, "TRUETYPE_FONT", "general.truetype-font" }, + { TRUETYPE_COLLECTION_FONT, "TRUETYPE_COLLECTION_FONT", "general.truetype-collection-font" }, + { OPENTYPE_FONT, "OPENTYPE_FONT", "general.opentype-font" }, + { POSTSCRIPT_FONT, "POSTSCRIPT_FONT", "com.adobe.postscript-font" }, + { POSTSCRIPT_PFB_FONT, "POSTSCRIPT_PFB_FONT", "com.adobe.postscript-pfb-font" }, + { POSTSCRIPT_PFA_FONT, "POSTSCRIPT_PFA_FONT", "com.adobe.postscript-pfa-font" }, + { OPENHARMONY_HDOC, "OPENHARMONY_HDOC", "openharmony.hdoc" }, + { OPENHARMONY_HINOTE, "OPENHARMONY_HINOTE", "openharmony.hinote" }, + { OPENHARMONY_STYLED_STRING, "OPENHARMONY_STYLED_STRING", "openharmony.styled-string" }, + { OPENHARMONY_WANT, "OPENHARMONY_WANT", "openharmony.want" }, + { OFD, "OFD", "general.ofd" }, + { OPG, "OPG", "general.opg" }, + { TEX, "TEX", "general.tex" }, + { CSS, "CSS", "general.css" }, + { VOB, "VOB", "general.vob" }, + { DIF_VIDEO, "DIF_VIDEO", "general.dif-video" }, + { DV_VIDEO, "DV_VIDEO", "general.dv-video" }, + { FLC_ANIMATION, "FLC_ANIMATION", "general.flc-animation" }, + { MNG, "MNG", "general.mng" }, + { MPEGURL_VIDEO, "MPEGURL_VIDEO", "general.mpegurl-video" }, + { TS, "TS", "general.ts" }, + { AMR, "AMR", "general.amr" }, + { AMR_WB, "AMR_WB", "general.amr-wb" }, + { GMS, "GSM", "general.gsm" }, + { IMY, "IMY", "general.imy" }, + { KAR, "KAR", "general.kar" }, + { MPEGURL_AUDIO, "MPEGURL_AUDIO", "general.mpegurl-audio" }, + { MPEG_4_AUDIO, "MPEG_4_AUDIO", "general.mpeg-4-audio" }, + { MIDI_AUDIO, "MIDI_AUDIO", "general.midi-audio" }, + { MP2, "MP2", "general.mp2" }, + { MPEG_AUDIO, "MPEG_AUDIO", "general.mpeg-audio" }, + { MXMF, "MXMF", "general.mxmf" }, + { OTA, "OTA", "general.ota" }, + { PLS, "PLS", "general.pls" }, + { RTTTL, "RTTTL", "general.rtttl" }, + { PSID, "PSID", "general.psid" }, + { ULAW_AUDIO, "ULAW_AUDIO", "general.ulaw-audio" }, + { XMF, "XMF", "general.xmf" }, + { GIF, "GIF", "general.gif" }, + { DJVU_IMAGE, "DJVU_IMAGE", "general.djvu-image" }, + { JNG_IMAGE, "JNG_IMAGE", "general.jng-image" }, + { PCX_IMAGE, "PCX_IMAGE", "general.pcx-image" }, + { PBM_IMAGE, "PBM_IMAGE", "general.pbm-image" }, + { PGM_IMAGE, "PGM_IMAGE", "general.pgm-image" }, + { PNM_IMAGE, "PNM_IMAGE", "general.pnm-image" }, + { PPM_IMAGE, "PPM_IMAGE", "general.ppm-image" }, + { RGB_IMAGE, "RGB_IMAGE", "general.rgb-image" }, + { SVG_IMAGE, "SVG_IMAGE", "general.svg-image" }, + { WBMP_IMAGE, "WBMP_IMAGE", "general.wbmp-image" }, + { XPIXMP_IMAGE, "XPIXMAP_IMAGE", "general.xpixmap-image" }, + { XWINDOWDUMP_IMAGE, "XWINDOWDUMP_IMAGE", "general.xwindowdump-image" }, + { HEIF, "HEIF", "general.heif" }, + { HEIC, "HEIC", "general.heic" }, + { VIRTUAL_CD, "VIRTUAL_CD", "general.virtual-cd" }, + { BOO_SOURCE, "BOO_SOURCE", "general.boo-source" }, + { D_SOURCE, "D_SOURCE", "general.d-source" }, + { HTML_COMPONENT, "HTML_COMPONENT", "general.html-component" }, + { PASCAL_SOURCE, "PASCAL_SOURCE", "general.pascal-source" }, + { HASKELL_SCRIPT, "HASKELL_SCRIPT", "general.haskell-script" }, + { LITERATE_HASKELL_SCRIPT, "LITERATE_HASKELL_SCRIPT", "general.literate-haskell-script" }, + { TCL_SCRIPT, "TCL_SCRIPT", "general.tcl-script" }, + { ASC_TEXT, "ASC_TEXT", "general.asc-text" }, + { PORTABLE_OBJECT, "PORTABLE_OBJECT", "general.portable-object" }, + { RICH_TEXT, "RICH_TEXT", "general.rich-text" }, + { DELIMITED_VALUES_TEXT, "DELIMITED_VALUES_TEXT", "general.delimited-values-text" }, + { COMMA_SEPARATED_VALUES_TEXT, "COMMA_SEPARATED_VALUES_TEXT", "general.comma-separated-values-text" }, + { DIFF, "DIFF", "general.diff" }, + { SETEXT, "SETEXT", "general.setext" }, + { GCD, "GCD", "general.gcd" }, + { TAB_SEPARATED_VALUES_TEXT, "TAB_SEPARATED_VALUES_TEXT", "general.tab-separated-values-text" }, + { P7R, "P7R", "general.p7r" }, + { PEM, "PEM", "general.pem" }, + { CHESS_PGN, "CHESS_PGN", "general.chess-pgn" }, + { LHA_ARCHIVE, "LHA_ARCHIVE", "general.lha-archive" }, + { LZH_ARCHIVE, "LZH_ARCHIVE", "general.lzh-archive" }, + { LZX_ARCHIVE, "LZX_ARCHIVE", "general.lzx-archive" }, + { TAZ_ARCHIVE, "TAZ_ARCHIVE", "general.taz-archive" }, + { SHAR_ARCHIVE, "SHAR_ARCHIVE", "general.shar-archive" }, + { CPIO_ARCHIVE, "CPIO_ARCHIVE", "general.cpio-archive" }, + { WEB_ARCHIVE, "WEB_ARCHIVE", "general.web-archive" }, + { USTAR, "USTAR", "general.ustar" }, + { MATHML, "MATHML", "general.mathml" }, + { XHTML, "XHTML", "general.xhtml" }, + { RSS, "RSS", "general.rss" }, + { RDF, "RDF", "general.rdf" }, + { IGES, "IGES", "general.iges" }, + { CAD, "CAD", "general.cad" }, + { OCTET_STREAM, "OCTET_STREAM", "general.octet-stream" }, + { ISO, "ISO", "general.iso" }, + { MESH_MODEL, "MESH_MODEL", "general.mesh-model" }, + { CERTIFICATE, "CERTIFICATE", "general.certificate" }, + { C_OBJECT, "C_OBJECT", "general.c-object" }, + { DVI, "DVI", "general.dvi" }, + { CER_CERTIFICATE, "CER_CERTIFICATE", "general.cer-certificate" }, + { CRT_CERTIFICATE, "CRT_CERTIFICATE", "general.crt-certificate" }, + { CRL_CERTIFICATE, "CRL_CERTIFICATE", "general.crl-certificate" }, + { PRN, "PRN", "general.prn" }, + { OPENDOCUMENT_CHART, "OPENDOCUMENT_CHART", "org.oasis-open.opendocument.chart" }, + { OPENDOCUMENT_TEXT_MASTER, "OPENDOCUMENT_TEXT_MASTER", "org.oasis-open.opendocument.text-master" }, + { OPENDOCUMENT_TEXT_WEB, "OPENDOCUMENT_TEXT_WEB", "org.oasis-open.opendocument.text-web" }, + { OPENDOCUMENT_DATABASE, "OPENDOCUMENT_DATABASE", "org.oasis-open.opendocument.database" }, + { OPENDOCUMENT_IMAGE, "OPENDOCUMENT_IMAGE", "org.oasis-open.opendocument.image" }, + { OPENDOCUMENT_FORMULA_TEMPLATE, "OPENDOCUMENT_FORMULA_TEMPLATE", "org.oasis-open.opendocument.formula-template" }, + { OPENDOCUMENT_CHART_TEMPLATE, "OPENDOCUMENT_CHART_TEMPLATE", "org.oasis-open.opendocument.chart-template" }, + { OPENDOCUMENT_PRESENTATION_TEMPLATE, "OPENDOCUMENT_PRESENTATION_TEMPLATE", + "org.oasis-open.opendocument.presentation-template" }, + { OPENDOCUMENT_IMAGE_TEMPLATE, "OPENDOCUMENT_IMAGE_TEMPLATE", "org.oasis-open.opendocument.image-template" }, + { OPENDOCUMENT_GRAPHICS_TEMPLATE, "OPENDOCUMENT_GRAPHICS_TEMPLATE", + "org.oasis-open.opendocument.graphics-template" }, + { OPENDOCUMENT_SPREADSHEET_TEMPLATE, "OPENDOCUMENT_SPREADSHEET_TEMPLATE", + "org.oasis-open.opendocument.spreadsheet-template" }, + { OPENDOCUMENT_TEXT_TEMPLATE, "OPENDOCUMENT_TEXT_TEMPLATE", "org.oasis-open.opendocument.text-template" }, + { WORD_DOT, "WORD_DOT", "com.microsoft.word.dot" }, + { POWERPOINT_PPS, "POWERPOINT_PPS", "com.microsoft.powerpoint.pps" }, + { POWERPOINT_POT, "POWERPOINT_POT", "com.microsoft.powerpoint.pot" }, + { EXCEL_XLT, "EXCEL_XLT", "com.microsoft.excel.xlt" }, + { VISIO_VSD, "VISIO_VSD", "com.microsoft.visio.vsd" }, + { DRAWINGML_VISIO, "DRAWINGML_VISIO", "org.openxmlformats.drawingml.visio" }, + { DRAWINGML_TEMPLATE, "DRAWINGML_TEMPLATE", "org.openxmlformats.drawingml.template" }, + { DRAWINGML_VISIO_MACROENABLED, "DRAWINGML_VISIO_MACROENABLED", "org.openxmlformats.drawingml.visio.macroenabled" }, + { DRAWINGML_TEMPLATE_MACROENABLED, "DRAWINGML_TEMPLATE_MACROENABLED", + "org.openxmlformats.drawingml.template.macroenabled" }, + { WORDPROCESSINGML_TEMPLATE, "WORDPROCESSINGML_TEMPLATE", "org.openxmlformats.wordprocessingml.template" }, + { PRESENTATIONML_TEMPLATE, "PRESENTATIONML_TEMPLATE", "org.openxmlformats.presentationml.template" }, + { PRESENTATIONML_SLIDESHOW, "PRESENTATIONML_SLIDESHOW", "org.openxmlformats.presentationml.slideshow" }, + { SPREADSHEETML_TEMPLATE, "SPREADSHEETML_TEMPLATE", "org.openxmlformats.spreadsheetml.template" }, + { WORDPROCESSINGML_DOCUMENT_MACROENABLED, "WORDPROCESSINGML_DOCUMENT_MACROENABLED", + "org.openxmlformats.wordprocessingml.document.macroenabled" }, + { WORDPROCESSINGML_TEMPLATE_MACROENABLED, "WORDPROCESSINGML_TEMPLATE_MACROENABLED", + "org.openxmlformats.wordprocessingml.template.macroenabled" }, + { SPREADSHEETML_TEMPLATE_MACROENABLED, "SPREADSHEETML_TEMPLATE_MACROENABLED", + "org.openxmlformats.spreadsheetml.template.macroenabled" }, + { SPREADSHEETML_ADDIN_MACROENABLED, "SPREADSHEETML_ADDIN_MACROENABLED", + "org.openxmlformats.spreadsheetml.addin.macroenabled" }, + { SPREADSHEETML_BINARY_MACROENABLED, "SPREADSHEETML_BINARY_MACROENABLED", + "org.openxmlformats.spreadsheetml.binary.macroenabled" }, + { SPREADSHEETML_SHEET_MACROENABLED, "SPREADSHEETML_SHEET_MACROENABLED", + "org.openxmlformats.spreadsheetml.sheet.macroenabled" }, + { PRESENTATIONALML_ADDIN_MACROENABLED, "PRESENTATIONALML_ADDIN_MACROENABLED", + "org.openxmlformats.presentationml.addin.macroenabled" }, + { PRESENTATIONALML_PRESENTATION_MACROENABLED, "PRESENTATIONALML_PRESENTATION_MACROENABLED", + "org.openxmlformats.presentationml.presentation.macroenabled" }, + { PRESENTATIONALML_SLIDESHOW_MACROENABLED, "PRESENTATIONALML_SLIDESHOW_MACROENABLED", + "org.openxmlformats.presentationml.slideshow.macroenabled" }, + { PRESENTATIONALML_TEMPLATE_MACROENABLED, "PRESENTATIONALML_TEMPLATE_MACROENABLED", + "org.openxmlformats.presentationml.template.macroenabled" }, + { OPENOFFICE, "OPENOFFICE", "org.openoffice" }, + { OPENOFFICE_CALC, "OPENOFFICE_CALC", "org.openoffice.calc" }, + { OPENOFFICE_DRAW, "OPENOFFICE_DRAW", "org.openoffice.draw" }, + { OPENOFFICE_WRITER_GLOBAL, "OPENOFFICE_WRITER_GLOBAL", "org.openoffice.writer-global" }, + { OPENOFFICE_IMPRESS, "OPENOFFICE_IMPRESS", "org.openoffice.impress" }, + { OPENOFFICE_MATH, "OPENOFFICE_MATH", "org.openoffice.math" }, + { OPENOFFICE_WRITER, "OPENOFFICE_WRITER", "org.openoffice.writer" }, + { OPENOFFICE_CALC_TEMPLATE, "OPENOFFICE_CALC_TEMPLATE", "org.openoffice.calc.template" }, + { OPENOFFICE_DRAW_TEMPLATE, "OPENOFFICE_DRAW_TEMPLATE", "org.openoffice.draw.template" }, + { OPENOFFICE_IMPRESS_TEMPLATE, "OPENOFFICE_IMPRESS_TEMPLATE", "org.openoffice.impress.template" }, + { OPENOFFICE_WRITER_TEMPLATE, "OPENOFFICE_WRITER_TEMPLATE", "org.openoffice.writer.template" }, + { STAROFFICE, "STAROFFICE", "com.staroffice" }, + { STAROFFICE_DRAW, "STAROFFICE_DRAW", "com.staroffice.draw" }, + { STAROFFICE_CALC, "STAROFFICE_CALC", "com.staroffice.calc" }, + { STAROFFICE_IMPRESS, "STAROFFICE_IMPRESS", "com.staroffice.impress" }, + { STAROFFICE_WRITER, "STAROFFICE_WRITER", "com.staroffice.writer" }, + { STAROFFICE_CHART, "STAROFFICE_CHART", "com.staroffice.chart" }, + { STAROFFICE_MAIL, "STAROFFICE_MAIL", "com.staroffice.mail" }, + { STAROFFICE_WRITER_GLOBAL, "STAROFFICE_WRITER_GLOBAL", "com.staroffice.writer-global" }, + { STAROFFICE_MATH, "STAROFFICE_MATH", "com.staroffice.math" }, + { STAROFFICE_TEMPLATE, "STAROFFICE_TEMPLATE", "com.staroffice.template" }, + { TUG_BIB, "TUG_BIB", "org.tug.bib" }, + { TUG_CLS, "TUG_CLS", "org.tug.cls" }, + { TUG_STY, "TUG_STY", "org.tug.sty" }, + { TUG_TEX, "TUG_TEX", "org.tug.tex" }, + { LATEX, "LATEX", "org.latex-project.latex" }, + { ADVANCED_SYSTEMS_FORMAT, "ADVANCED_SYSTEMS_FORMAT", "com.microsoft.advanced-systems-format" }, + { ADVANCED_STREAM_REDIRECTOR, "ADVANCED_STREAM_REDIRECTOR", "com.microsoft.advanced-stream-redirector" }, + { MATROSKA_VIDEO, "MATROSKA_VIDEO", "org.matroska.mkv" }, + { MATROSKA_AUDIO, "MATROSKA_AUDIO", "org.matroska.mka" }, + { SGI_MOVIE, "SGI_MOVIE", "com.sgi.movie" }, + { APPLE_M4V, "APPLE_M4V", "com.apple.m4v" }, + { WEBM, "WEBM", "org.webmproject.webm" }, + { QUICKTIME_MOVIE, "QUICKTIME_MOVIE", "com.apple.quicktime-movie" }, + { CORELDRAW_CDR, "CORELDRAW_CDR", "com.coreldraw.cdr" }, + { CORELDRAW_CDT, "CORELDRAW_CDT", "com.coreldraw.cdt" }, + { CORELDRAW_CPT, "CORELDRAW_CPT", "com.coreldraw.cpt" }, + { CORELDRAW_PAT, "CORELDRAW_PAT", "com.coreldraw.pat" }, + { MICROSOFT_CUR, "MICROSOFT_CUR", "com.microsoft.cur" }, + { SUN_RASTER, "SUN_RASTER", "com.sun.raster" }, + { GOOGLE_WEBP, "GOOGLE_WEBP", "com.google.webp" }, + { KOAN_AUDIO, "KOAN_AUDIO", "com.sseyo.koan-audio" }, + { QT_MOC, "QT_MOC", "io.qt.moc" }, + { GHOSTSCRIPT_FONT, "GHOSTSCRIPT_FONT", "com.ghostscript.font" }, + { X_PCF_FONT, "X_PCF_FONT", "org.x.pcf-font" }, + { WINDOWS_MEDIA_WMD, "WINDOWS_MEDIA_WMD", "com.microsoft.windows-media-wmd" }, + { WINDOWS_MEDIA_WMZ, "WINDOWS_MEDIA_WMZ", "com.microsoft.windows-media-wmz" }, + { WINDOWS_INSTALLER, "WINDOWS_INSTALLER", "com.microsoft.windows-installer" }, + { PUBLISHER_PUB, "PUBLISHER_PUB", "com.microsoft.publisher.pub" }, + { WINDOWS_MEDIA_PLAYLIST, "WINDOWS_MEDIA_PLAYLIST", "com.microsoft.windows-media-playlist" }, + { ACCESS_MDB, "ACCESS_MDB", "com.microsoft.access.mdb" }, + { STEREOLITHOGRAPHY, "STEREOLITHOGRAPHY", "com.3dsystems.stereolithography" }, + { APPLE_MEDIA_PLAYLIST, "APPLE_MEDIA_PLAYLIST", "com.apple.media.playlist" }, + { ABISOURCE_WORD, "ABISOURCE_WORD", "com.abisource.word" }, + { ADOBE_FRAMEMAKER, "ADOBE_FRAMEMAKER", "com.adobe.framemaker" }, + { WOLFRAM_CDF, "WOLFRAM_CDF", "com.wolfram.cdf" }, + { CINDERELLA_CDY, "CINDERELLA_CDY", "de.cinderella.cdy" }, + { ADOBE_DCR, "ADOBE_DCR", "com.adobe.dcr" }, + { ADOBE_DIR, "ADOBE_DIR", "com.adobe.dir" }, + { ADOBE_DXR, "ADOBE_DXR", "com.adobe.dxr" }, + { GNUMERIC_SPREADSHEET, "GNUMERIC_SPREADSHEET", "org.gnumeric.spreadsheet" }, + { HDFGROUP_HDF, "HDFGROUP_HDF", "org.hdfgroup.hdf" }, + { BINHEX_ARCHIVE, "BINHEX_ARCHIVE", "com.apple.binhex-archive" }, + { MICROSOFT_HTA, "MICROSOFT_HTA", "com.microsoft.hta" }, + { INTERNET_INS, "INTERNET_INS", "com.microsoft.internet.ins" }, + { INTERNET_ISP, "INTERNET_ISP", "com.microsoft.internet.isp" }, + { TROFF, "TROFF", "org.troff" }, + { ADOBE_MIF, "ADOBE_MIF", "com.adobe.framemaker.mif" }, + { FREEMIND, "FREEMIND", "io.sourceforge.freemind" }, + { YAMAHA_SMAF, "YAMAHA_SMAF", "com.yamaha.smaf" }, + { MATHEMATICA_NOTEBOOK, "MATHEMATICA_NOTEBOOK", "com.wolfram.mathematica.notebook" }, + { XIPH_OGG, "XIPH_OGG", "org.xiph.ogg" }, + { PROXY_AUTOCONFIG, "PROXY_AUTOCONFIG", "com.netscape.proxy-autoconfig" }, + { PKCS_12, "PKCS_12", "com.rsa.pkcs-12" }, + { PGP_SIGNATURE, "PGP_SIGNATURE", "org.openpgp.signature" }, + { QUICKTIME_LINK, "QUICKTIME_LINK", "com.apple.quicktime-link" }, + { RAR_ARCHIVE, "RAR_ARCHIVE", "com.rarlab.rar-archive" }, + { SEVEN_ZIP_ARCHIVE, "SEVEN_ZIP_ARCHIVE", "org.7-zip.7-zip-archive" }, + { RED_BEAN_SGF, "RED_BEAN_SGF", "com.red-bean.sgf" }, + { SIT_ARCHIVE, "SIT_ARCHIVE", "com.stuffit.sit-archive" }, + { FUTURESPLASH, "FUTURESPLASH", "com.adobe.futuresplash" }, + { FLASH, "FLASH", "com.adobe.flash" }, + { TEXINFO, "TEXINFO", "org.gnu.texinfo" }, + { TORRENT, "TORRENT", "org.bittorrent.torrent" }, + { DOOM, "DOOM", "com.idsoftware.doom" }, + { APPLE_WEBARCHIVE, "APPLE_WEBARCHIVE", "com.apple.webarchive" }, + { ANDROID_WEBARCHIVE, "ANDROID_WEBARCHIVE", "com.android.webarchive" }, + { GIMP_XCF, "GIMP_XCF", "org.gimp.xcf" }, + { EDRWMAX, "EDRWMAX", "com.edrawsoft.edrawmax" }, + { EDRWMIND, "EDRWMIND", "com.edrawsoft.edrawmind" }, + { CNKI_CAJ, "CNKI_CAJ", "net.cnki.caj" }, + { DBASE_DBF, "DBASE_DBF", "com.dbase.dbf" }, + { AUTODESK_DWG, "AUTODESK_DWG", "com.autodesk.dwg" }, + { AUTODESK_DXF, "AUTODESK_DXF", "com.autodesk.dxf" }, + { AUTODESK_DWS, "AUTODESK_DWS", "com.autodesk.dws" }, + { AUTODESK_DWT, "AUTODESK_DWT", "com.autodesk.dwt" }, + { AUTODESK_DWF, "AUTODESK_DWF", "com.autodesk.dwf" }, + { AUTODESK_DWFX, "AUTODESK_DWFX", "com.autodesk.dwfx" }, + { AUTODESK_SHP, "AUTODESK_SHP", "com.autodesk.shp" }, + { AUTODESK_SHX, "AUTODESK_SHX", "com.autodesk.shx" }, + { AUTODESK_SLIDE_LIB, "AUTODESK_SLIDE_LIB", "com.autodesk.slide-library" }, + { AUTODESK_LINE, "AUTODESK_LINE", "com.autodesk.line" }, + { AUTODESK_PLOTTER, "AUTODESK_PLOTTER", "com.autodesk.plotter" }, + { HP_GRAPHICS_LANG, "HP_GRAPHICS_LANG", "com.hp.graphics-language" }, + { MICROSOFT_METAFILE, "MICROSOFT_METAFILE", "com.microsoft.metafile" }, + { ACIS_SAT, "ACIS_SAT", "com.spatial.acis.sat" }, + { AVIF_IMAGE, "AVIF_IMAGE", "org.aomedia.avif-image" }, + { MICROSOFT_DDS, "MICROSOFT_DDS", "com.microsoft.dds" }, + { IFF_ILBM, "IFF_ILBM", "com.ea.iff-ilbm" }, + { CR2_RAW_IMAGE, "CR2_RAW_IMAGE", "com.canon.cr2-raw-image" }, + { CR3_RAW_IMAGE, "CR3_RAW_IMAGE", "com.canon.cr3-raw-image" }, + { CRW_RAW_IMAGE, "CRW_RAW_IMAGE", "com.canon.crw-raw-image" }, + { DNG_RAW_IMAGE, "DNG_RAW_IMAGE", "com.adobe.dng-raw-image" }, + { ARW_RAW_IMAGE, "ARW_RAW_IMAGE", "com.sony.arw-raw-image" }, + { NEF_RAW_IMAGE, "NEF_RAW_IMAGE", "com.nikon.nef-raw-image" }, + { MINDMANAGER_MMAP, "MINDMANAGER_MMAP", "com.mindjet.mindmanager.mmap" }, + { MICROSOFT_EMAIL, "MICROSOFT_EMAIL", "com.microsoft.email" }, + { MICROSOFT_MESSAGE, "MICROSOFT_MESSAGE", "com.microsoft.message" }, + { MICROSOFT_PST, "MICROSOFT_PST", "com.microsoft.pst" }, + { KINSOFT_OFFICE, "KINSOFT_OFFICE", "com.kingsoft.office general.zip-archive" }, + { KINSOFT_WRITER_WPS, "KINSOFT_WRITER_WPS", "com.kingsoft.office.writer.wps" }, + { KINSOFT_WRITER_WPT, "KINSOFT_WRITER_WPT", "com.kingsoft.office.writer.wpt" }, + { KINSOFT_PRESENTATION_DPS, "KINSOFT_PRESENTATION_DPS", "com.kingsoft.office.presentation.dps" }, + { KINSOFT_PRESENTATION_TEMPLATE, "KINSOFT_PRESENTATION_TEMPLATE", "com.kingsoft.office.presentation.template" }, + { KINSOFT_SPREADSHEETS_ET, "KINSOFT_SPREADSHEETS_ET", "com.kingsoft.office.spreadsheets.et" }, + { KINSOFT_SPREADSHEETS_TEMPLATE, "KINSOFT_SPREADSHEETS_TEMPLATE", "com.kingsoft.office.spreadsheets.template" } +}; + +namespace UtdUtils { +bool IsValidUtdId(const std::string &utdId) +{ + for (const auto &item : UTD_TYPES) { + if (item.UtdId == utdId) { + return true; + } + } + return false; +} + +int32_t GetUtdEnumFromUtdId(const std::string &utdId) +{ + for (const auto &item : UTD_TYPES) { + if (item.UtdId == utdId) { + return item.UtdEnum; + } + } + return UD_BUTT; +} + +std::string GetUtdIdFromUtdEnum(int32_t utdType) +{ + for (const auto &item : UTD_TYPES) { + if (item.UtdEnum == utdType) { + return item.UtdId; + } + } + return ""; +} + +std::vector GetUtdTypes() +{ + std::vector utdTypes(UTD_TYPES, UTD_TYPES + sizeof(UTD_TYPES) / sizeof(UtdType)); + return utdTypes; +} +} // namespace UtdUtils + bool UnifiedDataUtils::IsValidType(int32_t value) { return value >= ENTITY && value < UD_BUTT; @@ -29,6 +471,39 @@ bool UnifiedDataUtils::IsValidIntention(int32_t value) return value > UD_INTENTION_BASE && value < UD_INTENTION_BUTT; } +static constexpr AppShareOption APP_SHARE_OPTIONS[] = { + { IN_APP, "IN_APP"}, + { CROSS_APP, "CROSS_APP"}, +}; + +bool ShareOptionsUtil::IsValid(int32_t shareOption) +{ + if (shareOption < 0 || shareOption >= SHARE_OPTIONS_BUTT) { + return false; + } + return true; +} + +int32_t ShareOptionsUtil::GetEnumNum(const std::string &shareOption) +{ + for (const auto &item : APP_SHARE_OPTIONS) { + if (item.enumStr == shareOption) { + return item.enumNum; + } + } + return SHARE_OPTIONS_BUTT; +} + +std::string ShareOptionsUtil::GetEnumStr(int32_t shareOption) +{ + for (const auto &item : APP_SHARE_OPTIONS) { + if (item.enumNum == shareOption) { + return item.enumStr; + } + } + return ""; +} + size_t UnifiedDataUtils::GetVariantSize(UDVariant &variant) { auto int32Value = std::get_if(&variant); diff --git a/udmf/framework/innerkitsimpl/data/flexible_type.cpp b/udmf/framework/innerkitsimpl/data/flexible_type.cpp index 78e2127f..77269979 100644 --- a/udmf/framework/innerkitsimpl/data/flexible_type.cpp +++ b/udmf/framework/innerkitsimpl/data/flexible_type.cpp @@ -50,7 +50,7 @@ bool FlexibleType::ParseFlexibleUtd(const std::string &typeId, TypeDescriptorCfg std::vector attrkv = UTILS::StrSplit(attr, "="); std::string attrName = attrkv[0]; if (attrName.find(std::to_string(BELONGINGTO_TYPE)) != attrName.npos) { - flexibleTypeDescriptorCfg.belongingToTypes.insert(attrkv[1]); + flexibleTypeDescriptorCfg.belongingToTypes.push_back(attrkv[1]); } else if (attrName.find(std::to_string(MIMETYPE)) != attrName.npos) { flexibleTypeDescriptorCfg.mimeTypes.push_back(attrkv[1]); } else if (attrName.find(std::to_string(FILE_EXTENTSION)) != attrName.npos) { diff --git a/udmf/framework/innerkitsimpl/data/preset_type_descriptors.cpp b/udmf/framework/innerkitsimpl/data/preset_type_descriptors.cpp index e233e9d3..685e7c24 100644 --- a/udmf/framework/innerkitsimpl/data/preset_type_descriptors.cpp +++ b/udmf/framework/innerkitsimpl/data/preset_type_descriptors.cpp @@ -51,7 +51,7 @@ void PresetTypeDescriptors::InitDescriptors() {"general.object", {}, {}, - {}, + {"*/*"}, "Base type for logical hierarchy.", REFERENCE_URL, ""}, @@ -71,7 +71,7 @@ void PresetTypeDescriptors::InitDescriptors() ""}, {"general.plain-text", {"general.text"}, - {".txt"}, + {".txt", ".text"}, {"text/plain"}, "Text of unspecified encoding, with no markup.", REFERENCE_URL, @@ -121,14 +121,14 @@ void PresetTypeDescriptors::InitDescriptors() {"general.shell-script", {"general.script"}, {".sh", ".command"}, - {}, + {"text/x-shellscript"}, "Shell script.", REFERENCE_URL, ""}, {"general.csh-script", {"general.shell-script"}, {".csh"}, - {}, + {"text/x-csh"}, "C-shell script.", REFERENCE_URL, ""}, @@ -177,28 +177,28 @@ void PresetTypeDescriptors::InitDescriptors() {"general.c-header", {"general.source-code"}, {".h"}, - {}, + {"text/-chdr"}, "C header file.", REFERENCE_URL, ""}, {"general.c-source", {"general.source-code"}, {".c"}, - {}, + {"text/x-csrc"}, "C source code.", REFERENCE_URL, ""}, {"general.c-plus-plus-header", {"general.source-code"}, - {".hpp", ".h++", ".hxx"}, - {}, + {".hpp", ".h++", ".hxx", ".hh"}, + {"text/x-c++hdr"}, "C++ header file.", REFERENCE_URL, ""}, {"general.c-plus-plus-source", {"general.source-code"}, {".cp", ".cpp", ".c++", ".cc", ".cxx"}, - {}, + {"text/x-c++src"}, "C++ source code.", REFERENCE_URL, ""}, @@ -274,7 +274,7 @@ void PresetTypeDescriptors::InitDescriptors() "sys.media.ohos_ic_normal_white_grid_image"}, {"general.jpeg", {"general.image"}, - {".jpg", ".jpeg"}, + {".jpg", ".jpeg", ".jpe"}, {"image/jpeg"}, "JPEG image.", REFERENCE_URL, @@ -303,14 +303,14 @@ void PresetTypeDescriptors::InitDescriptors() {"com.microsoft.bmp", {"general.image"}, {".bmp"}, - {}, + {"image/bmp", "image/x-ms-bmp"}, "Windows bitmap image.", REFERENCE_URL, "sys.media.ohos_ic_normal_white_grid_image"}, {"com.microsoft.ico", {"general.image"}, {".ico"}, - {}, + {"image/ico", "image/x-icon"}, "Windows icon image.", REFERENCE_URL, "sys.media.ohos_ic_normal_white_grid_image"}, @@ -352,7 +352,7 @@ void PresetTypeDescriptors::InitDescriptors() {"general.xbitmap-image", {"general.image"}, {".xbm"}, - {"image/x-quicktime"}, + {"image/x-xbitmap", "image/x-xbm"}, "X bitmap image.", REFERENCE_URL, ""}, @@ -401,7 +401,7 @@ void PresetTypeDescriptors::InitDescriptors() {"com.microsoft.powerpoint.ppt", {"general.composite-object"}, {".ppt"}, - {"application/mspowerpoint"}, + {"application/vnd.ms-powerpoint"}, "Microsoft PowerPoint presentation.", REFERENCE_URL, ""}, @@ -442,7 +442,7 @@ void PresetTypeDescriptors::InitDescriptors() "sys.media.ohos_ic_normal_white_grid_video"}, {"general.mpeg", {"general.video"}, - {".mpg", ".mpeg", ".m75", ".m15"}, + {".mpg", ".mpeg", ".m75", ".m15", ".mpe"}, {"video/mpg", "video/mpeg", "video/x-mpg", "video/x-mpeg"}, "MPEG-1 or MPEG-2 video.", REFERENCE_URL, @@ -463,41 +463,41 @@ void PresetTypeDescriptors::InitDescriptors() "sys.media.ohos_ic_normal_white_grid_video"}, {"general.3gpp2", {"general.video"}, - {".3g2", ".3gp2"}, + {".3g2", ".3gp2", ".3gpp2"}, {"video/3gpp2"}, "3GPP2 video.", REFERENCE_URL, "sys.media.ohos_ic_normal_white_grid_video"}, {"com.microsoft.windows-media-wm", - {"general.video"}, + {"general.video", "com.microsoft.advanced-systems-format"}, {".wm"}, {"video/x-ms-wm"}, "Windows WM video.", REFERENCE_URL, "sys.media.ohos_ic_normal_white_grid_video"}, {"com.microsoft.windows-media-wmv", - {"general.video"}, + {"general.video", "com.microsoft.advanced-systems-format"}, {".wmv"}, {"video/x-ms-wmv"}, "Windows WMV video.", REFERENCE_URL, "sys.media.ohos_ic_normal_white_grid_video"}, {"com.microsoft.windows-media-wmp", - {"general.video"}, + {"general.video", "com.microsoft.advanced-systems-format"}, {".wmp"}, {"video/x-ms-wmp"}, "Windows WMP video.", REFERENCE_URL, "sys.media.ohos_ic_normal_white_grid_video"}, {"com.microsoft.windows-media-wvx", - {"general.video"}, + {"general.video", "com.microsoft.advanced-systems-format"}, {".wvx"}, {"video/x-ms-wvx"}, "Windows WVX video.", REFERENCE_URL, "sys.media.ohos_ic_normal_white_grid_video"}, {"com.microsoft.windows-media-wmx", - {"general.video"}, + {"general.video", "com.microsoft.advanced-systems-format"}, {".wmx"}, {"video/x-ms-wmx"}, "Windows WMX video.", @@ -566,22 +566,36 @@ void PresetTypeDescriptors::InitDescriptors() "PCM audio.", REFERENCE_URL, "sys.media.ohos_ic_normal_white_grid_audio"}, + {"com.microsoft.advanced-systems-format", + {"general.media"}, + {".asf"}, + {"video/x-ms-asf", "application/vnd.ms-asf"}, + "Advanced Systems format", + REFERENCE_URL, + ""}, + {"com.microsoft.advanced-stream-redirector", + {"general.video"}, + {".asx"}, + {"video/x-ms-asf"}, + "Advanced stream redirector", + REFERENCE_URL, + ""}, {"com.microsoft.windows-media-wma", - {"general.audio"}, + {"general.audio", "com.microsoft.advanced-systems-format"}, {".wma"}, {"audio/x-ms-wma"}, "Windows WMA audio.", REFERENCE_URL, "sys.media.ohos_ic_normal_white_grid_wma"}, {"com.microsoft.waveform-audio", - {"general.audio"}, + {"general.audio", "com.microsoft.advanced-systems-format"}, {".wav", ".wave"}, - {"audio/wav", "audio/wave"}, + {"audio/wav", "audio/wave", "audio/x-wav"}, "Waveform audio.", REFERENCE_URL, "sys.media.ohos_ic_normal_white_grid_wav"}, {"com.microsoft.windows-media-wax", - {"general.audio"}, + {"general.audio", "com.microsoft.advanced-systems-format"}, {".wax"}, {"audio/x-ms-wax"}, "Windows WAX audio.", @@ -596,7 +610,7 @@ void PresetTypeDescriptors::InitDescriptors() ""}, {"general.aifc-audio", {"general.audio"}, - {".aifc", ".aif"}, + {".aifc", ".aif", ".aiff"}, {"audio/x-aiff"}, "Audio Interchange File Format.", REFERENCE_URL, @@ -604,7 +618,7 @@ void PresetTypeDescriptors::InitDescriptors() {"com.digidesign.sd2-audio", {"general.audio"}, {".sd2"}, - {}, + {"audio/x-sd2"}, "Digidesign Sound Designer II audio.", REFERENCE_URL, ""}, @@ -702,7 +716,7 @@ void PresetTypeDescriptors::InitDescriptors() {"org.gnu.gnu-zip-tar-archive", {"general.archive"}, {".tgz"}, - {}, + {"application/x-gtar"}, "Gzip tar archive.", REFERENCE_URL, "sys.media.ohos_ic_normal_white_grid_compress"}, @@ -714,22 +728,22 @@ void PresetTypeDescriptors::InitDescriptors() REFERENCE_URL, ""}, {"org.openxmlformats.wordprocessingml.document", - {"org.openxmlformats.openxml", "general.composite-object"}, - {".docx", ".docm"}, + {"general.composite-object", "org.openxmlformats.openxml"}, + {".docx"}, {"application/vnd.openxmlformats-officedocument.wordprocessingml.document"}, "Office Open XML Document.", REFERENCE_URL, ""}, {"org.openxmlformats.spreadsheetml.sheet", - {"org.openxmlformats.openxml", "general.composite-object"}, - {".xlsx", ".xlsm"}, + {"general.composite-object", "org.openxmlformats.openxml"}, + {".xlsx"}, {"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}, "Office Open XML Workbook.", REFERENCE_URL, ""}, {"org.openxmlformats.presentationml.presentation", - {"org.openxmlformats.openxml", "general.composite-object"}, - {".pptx", ".pptm"}, + {"general.composite-object", "org.openxmlformats.openxml"}, + {".pptx"}, {"application/vnd.openxmlformats-officedocument.presentationml.presentation"}, "Office Open XML Presentation.", REFERENCE_URL, @@ -742,28 +756,28 @@ void PresetTypeDescriptors::InitDescriptors() REFERENCE_URL, ""}, {"org.oasis.opendocument.text", - {"org.oasis.opendocument", "general.composite-object"}, + {"general.composite-object", "org.oasis.opendocument"}, {".odt", ".fodt"}, {"application/vnd.oasis.opendocument.text"}, "OpenDocument Text.", REFERENCE_URL, ""}, {"org.oasis.opendocument.spreadsheet", - {"org.oasis.opendocument", "general.composite-object"}, + {"general.composite-object", "org.oasis.opendocument"}, {".ods", ".fods"}, {"application/vnd.oasis.opendocument.spreadsheet"}, "OpenDocument Spreadsheet.", REFERENCE_URL, ""}, {"org.oasis.opendocument.presentation", - {"org.oasis.opendocument", "general.composite-object"}, + {"general.composite-object", "org.oasis.opendocument"}, {".odp", ".fodp"}, {"application/vnd.oasis.opendocument.presentation"}, "OpenDocument Presentation.", REFERENCE_URL, ""}, {"org.oasis.opendocument.graphics", - {"org.oasis.opendocument", "general.composite-object"}, + {"general.composite-object", "org.oasis.opendocument"}, {".odg", ".fodg"}, {"application/vnd.oasis.opendocument.graphics"}, "OpenDocument Graphics.", @@ -784,23 +798,23 @@ void PresetTypeDescriptors::InitDescriptors() REFERENCE_URL, ""}, {"general.calendar", - {"general.object"}, + {"general.text"}, {}, {"text/calendar"}, "Base type for scheduled events.", REFERENCE_URL, "sys.media.ohos_ic_normal_white_grid_calendar"}, {"general.vcs", - {"general.calendar", "general.text"}, + {"general.calendar"}, {".vcs"}, - {"application/vcs"}, + {"text/calendar"}, "vCalendar type.", REFERENCE_URL, ""}, {"general.ics", - {"general.calendar", "general.text"}, + {"general.calendar"}, {".ics"}, - {"application/ics"}, + {"text/calendar"}, "iCalendar type.", REFERENCE_URL, ""}, @@ -848,8 +862,8 @@ void PresetTypeDescriptors::InitDescriptors() ""}, {"general.vcard", {"general.object"}, - {}, - {}, + {".vcf", ".vcard"}, + {"text/vcard", "text/x-vcard"}, "Base type for electronic business card.", REFERENCE_URL, ""}, @@ -985,6 +999,1749 @@ void PresetTypeDescriptors::InitDescriptors() {}, "OpenHarmony system defined Want.", REFERENCE_URL, + ""}, + {"openharmony.moving-photo", + {"general.media"}, + {}, + {}, + "OpenHarmony system defined moving photo.", + REFERENCE_URL, + ""}, + {"macos.dmg", + {"general.disk-image"}, + {".dmg"}, + {"application/x-apple-diskimage"}, + "Apple Disk Image", + REFERENCE_URL, + ""}, + {"debian.deb", + {"general.archive"}, + {".deb", ".udeb"}, + {"application/x-debian-package", "application/vnd.debian.binary-package"}, + "OpenHarmony system defined Want.", + REFERENCE_URL, + ""}, + {"general.ofd", + {"general.composite-object"}, + {".ofd"}, + {}, + "Open fixed-layout document, a national standard for format documents", + REFERENCE_URL, + ""}, + {"general.opg", + {"general.archive"}, + {".opg"}, + {}, + "OPG archive", + REFERENCE_URL, + ""}, + {"general.tex", + {"general.source-code"}, + {}, + {}, + "Base type for TeX source code", + REFERENCE_URL, + ""}, + {"general.css", + {"general.script"}, + {".css"}, + {"text/css"}, + "Cascading style sheets", + REFERENCE_URL, + ""}, + {"general.vob", + {"general.video"}, + {".vob"}, + {"video/mpeg", "video/x-ms-vob"}, + "", + REFERENCE_URL, + ""}, + {"general.dif-video", + {"general.video"}, + {".dif"}, + {"video/dv"}, + "Digital interface format", + REFERENCE_URL, + ""}, + {"general.dv-video", + {"general.video"}, + {".dv"}, + {"video/dv"}, + "DV video", + REFERENCE_URL, + ""}, + {"general.flc-animation", + {"general.video"}, + {".fli", ".flc"}, + {"video/fli", "video/flc"}, + "FLIC file format", + REFERENCE_URL, + ""}, + {"general.mng", + {"general.video"}, + {".mng"}, + {"video/x-mng"}, + "Multiple-image network graphics", + REFERENCE_URL, + ""}, + {"general.mpegurl-video", + {"general.video"}, + {".mxu", ".m4u"}, + {"video/vnd.mpegurl"}, + "Video playlist", + REFERENCE_URL, + ""}, + {"general.ts", + {"general.video"}, + {".ts"}, + {"video/mp2ts", "video/mp2t"}, + "MPEG transport stream", + REFERENCE_URL, + ""}, + {"general.amr", + {"general.audio"}, + {".amr"}, + {"audio/amr"}, + "The adaptive multi-rate audio codecs", + REFERENCE_URL, + ""}, + {"general.amr-wb", + {"general.audio"}, + {".awb"}, + {"audio/amr-wb"}, + "Adaptive multi-rate wideband", + REFERENCE_URL, + ""}, + {"general.gsm", + {"general.audio"}, + {".gsm"}, + {"audio/x-gsm", "audio/gsm"}, + "Global system form mobile audio format", + REFERENCE_URL, + ""}, + {"general.imy", + {"general.audio"}, + {".imy"}, + {"audio/imelody"}, + "Non-polyphonic ringtone exchange object format", + REFERENCE_URL, + ""}, + {"general.kar", + {"general.audio"}, + {".kar"}, + {"audio/midi"}, + "Karaoke MIDI file format", + REFERENCE_URL, + ""}, + {"general.mpegurl-audio", + {"general.audio"}, + {".m3u"}, + {"audio/mpegurl", "audio/x-mpegurl"}, + "Audio playlist", + REFERENCE_URL, + ""}, + {"general.mpeg-4-audio", + {"general.audio"}, + {".m4a"}, + {"audio/mpeg"}, + "Audio-only MPEG-4 file", + REFERENCE_URL, + ""}, + {"general.midi-audio", + {"general.audio"}, + {".mid", ".midi"}, + {"audio/midi"}, + "MIDI audio", + REFERENCE_URL, + ""}, + {"general.mp2", + {"general.audio"}, + {".mp2"}, + {"audio/mpeg"}, + "MPEG-1 audio layer II or MPEG-2 audio layer II", + REFERENCE_URL, + ""}, + {"general.mpeg-audio", + {"general.audio"}, + {".mpga"}, + {"audio/mpeg"}, + "MPEG audio format", + REFERENCE_URL, + ""}, + {"general.mxmf", + {"general.audio"}, + {".mxmf"}, + {"audio/mobile-xmf"}, + "Mobile XMF audio format", + REFERENCE_URL, + ""}, + {"general.ota", + {"general.audio"}, + {".ota"}, + {"audio/midi"}, + "OTA ringtone file", + REFERENCE_URL, + ""}, + {"general.pls", + {"general.audio"}, + {".pls"}, + {"audio/x-scpls"}, + "Multimedia playlist format", + REFERENCE_URL, + ""}, + {"general.rtttl", + {"general.audio"}, + {".rtttl"}, + {"audio/midi"}, + "Ring tone transfer language file", + REFERENCE_URL, + ""}, + {"general.psid", + {"general.audio"}, + {".sid", ".psid"}, + {"audio/prs.sid"}, + "SID audio", + REFERENCE_URL, + ""}, + {"general.ulaw-audio", + {"general.audio"}, + {".au", ".ulw", ".snd"}, + {"audio/basic", "audio/au", "audio/snd"}, + "uLaw audio", + REFERENCE_URL, + ""}, + {"general.xmf", + {"general.audio"}, + {".xmf"}, + {"audio/midi"}, + "Extensible music file", + REFERENCE_URL, + ""}, + {"general.gif", + {"general.image"}, + {".gif"}, + {"image/gif"}, + "GIF image", + REFERENCE_URL, + ""}, + {"general.djvu-image", + {"general.image"}, + {".djv", ".djvu"}, + {"image/vnd.djvu"}, + "Djvu image", + REFERENCE_URL, + ""}, + {"general.jng-image", + {"general.image"}, + {".jng"}, + {"image/x-jng"}, + "JPEG network graphic", + REFERENCE_URL, + ""}, + {"general.pcx-image", + {"general.image"}, + {".pcx"}, + {"image/vnd.zbrush.pcx"}, + "Paintbrush bitmap image", + REFERENCE_URL, + ""}, + {"general.pbm-image", + {"general.image"}, + {".pbm"}, + {"image/x-portable-bitmap"}, + "Portable bitmap image", + REFERENCE_URL, + ""}, + {"general.pgm-image", + {"general.image"}, + {".pgm"}, + {"image/x-portable-graymap"}, + "Portable gray map image", + REFERENCE_URL, + ""}, + {"general.pnm-image", + {"general.image"}, + {".pnm"}, + {"image/x-portable-anymap"}, + "Portable any map image file", + REFERENCE_URL, + ""}, + {"general.ppm-image", + {"general.image"}, + {".ppm"}, + {"image/x-portable-pixmap"}, + "Portable pixmap image", + REFERENCE_URL, + ""}, + {"general.rgb-image", + {"general.image"}, + {".rgb"}, + {"image/x-rgb"}, + "RGB bitmap", + REFERENCE_URL, + ""}, + {"general.svg-image", + {"general.image"}, + {".svg", ".svgz"}, + {"image/svg+xml"}, + "Scalable vector graphic", + REFERENCE_URL, + ""}, + {"general.wbmp-image", + {"general.image"}, + {".wbmp"}, + {"image/vnd.wap.wbmp"}, + "Wireless bitmap image", + REFERENCE_URL, + ""}, + {"general.xpixmap-image", + {"general.image"}, + {".xpm"}, + {"image/x-xpixmap"}, + "X11 pixmap graphic", + REFERENCE_URL, + ""}, + {"general.xwindowdump-image", + {"general.image"}, + {".xwd"}, + {"image/x-xwindowdump"}, + "X windows dump image", + REFERENCE_URL, + ""}, + {"general.heif", + {"general.image"}, + {".heif"}, + {"image/heif"}, + "High efficiency image format", + REFERENCE_URL, + ""}, + {"general.heic", + {"general.image"}, + {".heic"}, + {"image/heic"}, + "High efficiency image format", + REFERENCE_URL, + ""}, + {"general.virtual-cd", + {"general.image"}, + {".vcd"}, + {"application/x-cdlink"}, + "Virtual CD", + REFERENCE_URL, + ""}, + {"general.boo-source", + {"general.source-code"}, + {".boo"}, + {"text/x-boo"}, + "Boo source code", + REFERENCE_URL, + ""}, + {"general.d-source", + {"general.source-code"}, + {".d"}, + {"text/x-dsrc"}, + "D source code file", + REFERENCE_URL, + ""}, + {"general.html-component", + {"general.source-code"}, + {".htc"}, + {"text/x-component"}, + "HTML component", + REFERENCE_URL, + ""}, + {"general.pascal-source", + {"general.source-code"}, + {".p", ".pas"}, + {"text/x-pascal"}, + "Pascal source code", + REFERENCE_URL, + ""}, + {"general.haskell-script", + {"general.script"}, + {".hs"}, + {"text/x-haskell"}, + "Haskell script", + REFERENCE_URL, + ""}, + {"general.literate-haskell-script", + {"general.script"}, + {".lhs"}, + {"text/x-literate-haskell"}, + "Literate haskell script", + REFERENCE_URL, + ""}, + {"general.tcl-script", + {"general.script"}, + {".tcl"}, + {"text/x-tcl"}, + "Tcl script", + REFERENCE_URL, + ""}, + {"general.asc-text", + {"general.text"}, + {".asc"}, + {"text/plain"}, + "ASCII text file", + REFERENCE_URL, + ""}, + {"general.portable-object", + {"general.text"}, + {".po"}, + {"text/plain"}, + "Portable object", + REFERENCE_URL, + ""}, + {"general.rich-text", + {"general.text"}, + {".rtf", ".rtx"}, + {"text/rtf", "text/richtext"}, + "Rich text format file", + REFERENCE_URL, + ""}, + {"general.delimited-values-text", + {"general.text"}, + {}, + {}, + "Base type for delimited-values text", + REFERENCE_URL, + ""}, + {"general.comma-separated-values-text", + {"general.delimited-values-text"}, + {".csv"}, + {"text/csv"}, + "Comma-separated values file", + REFERENCE_URL, + ""}, + {"general.diff", + {"general.text"}, + {".diff"}, + {"text/plain"}, + "Patch file", + REFERENCE_URL, + ""}, + {"general.setext", + {"general.text"}, + {".etx"}, + {"text/x-setext"}, + "Structure enhanced Text", + REFERENCE_URL, + ""}, + {"general.gcd", + {"general.text"}, + {".gcd"}, + {"text/x-pcs-gcd"}, + "General content descriptor", + REFERENCE_URL, + ""}, + {"general.tab-separated-values-text", + {"general.delimited-values-text"}, + {".tsv"}, + {"text/tab-separated-values"}, + "Tab-Separated values file", + REFERENCE_URL, + ""}, + {"general.p7r", + {"general.text"}, + {".p7r"}, + {"application/x-pkcs7-certreqresp"}, + "Certificate request response file", + REFERENCE_URL, + ""}, + {"general.pem", + {"general.text"}, + {".pem"}, + {"application/x-pem-file"}, + "Privacy enhanced mail certificate", + REFERENCE_URL, + ""}, + {"general.chess-pgn", + {"general.plain-text"}, + {".pgn"}, + {"application/x-chess-pgn", "application/vnd.chess-pgn"}, + "Portable game notation file", + REFERENCE_URL, + ""}, + {"general.lha-archive", + {"general.archive"}, + {".lha"}, + {"application/x-lha"}, + "LHARC compressed archive", + REFERENCE_URL, + ""}, + {"general.lzh-archive", + {"general.archive"}, + {".lzh"}, + {"application/x-lzh"}, + "LZH compressed file", + REFERENCE_URL, + ""}, + {"general.lzx-archive", + {"general.archive"}, + {".lzx"}, + {"application/x-lzx"}, + "LZX compressed archive", + REFERENCE_URL, + ""}, + {"general.taz-archive", + {"general.tar-archive"}, + {".taz", ".tar.z", ".tz"}, + {"application/x-gtar"}, + "Tar zipped file", + REFERENCE_URL, + ""}, + {"general.shar-archive", + {"general.archive"}, + {".shar"}, + {"application/x-shar"}, + "Unix Shar archive", + REFERENCE_URL, + ""}, + {"general.cpio-archive", + {"general.archive"}, + {".cpio"}, + {"application/x-cpio"}, + "Unix CPIO archive", + REFERENCE_URL, + ""}, + {"general.web-archive", + {"general.archive"}, + {".mht", ".mhtml"}, + {"application/x-mimearchive"}, + "MHTML web archive", + REFERENCE_URL, + ""}, + {"general.ustar", + {"general.archive"}, + {".ustar"}, + {"application/x-ustar"}, + "Uniform standard tape archive format", + REFERENCE_URL, + ""}, + {"general.mathml", + {"general.xml"}, + {".mml"}, + {"text/mathml", "application/mathml+xml"}, + "Mathematical markup language file", + REFERENCE_URL, + ""}, + {"general.xhtml", + {"general.xml"}, + {".xhtml"}, + {"application/xhtml+xml"}, + "XHTML", + REFERENCE_URL, + ""}, + {"general.rss", + {"general.xml"}, + {".rss"}, + {"application/rss+xml"}, + "Rich site summary", + REFERENCE_URL, + ""}, + {"general.rdf", + {"general.xml"}, + {".rdf"}, + {"application/rdf+xml"}, + "Resource description framework file", + REFERENCE_URL, + ""}, + {"general.cad", + {"general.object"}, + {}, + {}, + "Base type for computer-aided design", + REFERENCE_URL, + ""}, + {"general.iges", + {"general.cad"}, + {".iges", ".igs"}, + {"model/iges"}, + "IGES drawing", + REFERENCE_URL, + ""}, + {"general.octet-stream", + {"general.object"}, + {}, + {"application/octet-stream"}, + "Arbitrary binary data", + REFERENCE_URL, + ""}, + {"general.iso", + {"general.disk-image"}, + {".iso"}, + {"application/x-iso9660-image"}, + "Disc image file", + REFERENCE_URL, + ""}, + {"general.mesh-model", + {"general.object"}, + {".msh", ".mesh", ".silo"}, + {"model/mesh"}, + "3D mesh model", + REFERENCE_URL, + ""}, + {"general.certificate", + {"general.object"}, + {}, + {}, + "Base type for security certificate", + REFERENCE_URL, + ""}, + {"general.c-object", + {"general.executable"}, + {".o"}, + {"application/x-object"}, + "Compiled C object file", + REFERENCE_URL, + ""}, + {"general.dvi", + {"general.tex"}, + {".dvi"}, + {"application/x-dvi"}, + "Device independent format file", + REFERENCE_URL, + ""}, + {"general.cer-certificate", + {"general.certificate"}, + {".cer"}, + {"application/pkix-cert"}, + "Internet security certificate", + REFERENCE_URL, + ""}, + {"general.crt-certificate", + {"general.certificate"}, + {".crt"}, + {"application/x-x509-ca-cert", "application/x-x509-server-cert", "application/x-x509-user-cert"}, + "Security Certificate", + REFERENCE_URL, + ""}, + {"general.crl-certificate", + {"general.certificate"}, + {".crl"}, + {"application/x-pkix-crl"}, + "Certificate revocation list file", + REFERENCE_URL, + ""}, + {"general.prn", + {"general.composite-object"}, + {".prn"}, + {}, + "Print to file", + REFERENCE_URL, + ""}, + {"org.oasis-open.opendocument.chart", + {"org.oasis.opendocument", "general.composite-object"}, + {".odc"}, + {"application/vnd.oasis.opendocument.chart"}, + "Open Document chart", + REFERENCE_URL, + ""}, + {"org.oasis-open.opendocument.text-master", + {"org.oasis.opendocument", "general.composite-object"}, + {".odm"}, + {"application/vnd.oasis.opendocument.text-master"}, + "Open Document text master", + REFERENCE_URL, + ""}, + {"org.oasis-open.opendocument.text-web", + {"org.oasis.opendocument", "general.composite-object"}, + {".oth"}, + {"application/vnd.oasis.opendocument.text-web"}, + "Open Document HTML template", + REFERENCE_URL, + ""}, + {"org.oasis-open.opendocument.database", + {"org.oasis.opendocument", "general.database"}, + {".odb"}, + {"application/vnd.oasis.opendocument.database"}, + "Open Document database", + REFERENCE_URL, + ""}, + {"org.oasis-open.opendocument.image", + {"org.oasis.opendocument", "general.image"}, + {".odi"}, + {"application/vnd.oasis.opendocument.image"}, + "Open Document image", + REFERENCE_URL, + ""}, + {"org.oasis-open.opendocument.formula-template", + {"org.oasis.opendocument", "general.composite-object"}, + {".otf"}, + {"application/vnd.oasis.opendocument.formula-template"}, + "Open Document formula template", + REFERENCE_URL, + ""}, + {"org.oasis-open.opendocument.chart-template", + {"org.oasis.opendocument", "general.composite-object"}, + {".otc"}, + {"application/vnd.oasis.opendocument.chart-template"}, + "Open Document chart template", + REFERENCE_URL, + ""}, + {"org.oasis-open.opendocument.presentation-template", + {"org.oasis.opendocument", "general.composite-object"}, + {".otp"}, + {"application/vnd.oasis.opendocument.presentation-template"}, + "Open Document presentation template", + REFERENCE_URL, + ""}, + {"org.oasis-open.opendocument.image-template", + {"org.oasis.opendocument", "general.image"}, + {".oti"}, + {"application/vnd.oasis.opendocument.image-template"}, + "Open Document image template", + REFERENCE_URL, + ""}, + {"org.oasis-open.opendocument.graphics-template", + {"org.oasis.opendocument", "general.composite-object"}, + {".otg"}, + {"application/vnd.oasis.opendocument.graphics-template"}, + "Open Document graphics template", + REFERENCE_URL, + ""}, + {"org.oasis-open.opendocument.spreadsheet-template", + {"org.oasis.opendocument", "general.composite-object"}, + {".ots"}, + {"application/vnd.oasis.opendocument.spreadsheet-template"}, + "Open Document spreadsheet template", + REFERENCE_URL, + ""}, + {"org.oasis-open.opendocument.text-template", + {"org.oasis.opendocument", "general.composite-object"}, + {".ott"}, + {"application/vnd.oasis.opendocument.text-template"}, + "Open Document text template", + REFERENCE_URL, + ""}, + {"com.microsoft.word.dot", + {"general.composite-object"}, + {".dot"}, + {"application/msword"}, + "Microsoft Word document template", + REFERENCE_URL, + ""}, + {"com.microsoft.powerpoint.pps", + {"general.composite-object"}, + {".pps"}, + {"application/vnd.ms-powerpoint"}, + "Microsoft PowerPoint slide show", + REFERENCE_URL, + ""}, + {"com.microsoft.powerpoint.pot", + {"general.composite-object"}, + {".pot"}, + {"application/vnd.ms-powerpoint"}, + "Microsoft PowerPoint Template", + REFERENCE_URL, + ""}, + {"com.microsoft.excel.xlt", + {"general.composite-object"}, + {".xlt"}, + {"application/vnd.ms-excel"}, + "Microsoft Excel spreadsheet template", + REFERENCE_URL, + ""}, + {"com.microsoft.visio.vsd", + {"general.composite-object"}, + {".vsd"}, + {"application/vnd.visio"}, + "Microsoft Office Visio 2003-2010 drawing", + REFERENCE_URL, + ""}, + {"org.openxmlformats.drawingml.visio", + {"org.openxmlformats.openxml", "general.composite-object"}, + {".vsdx"}, + {"application/vnd.openxmlformats-officedocument.drawingml.drawing"}, + "Microsoft Visio drawing", + REFERENCE_URL, + ""}, + {"org.openxmlformats.drawingml.template", + {"org.openxmlformats.openxml", "general.composite-object"}, + {".vstx"}, + {}, + "Microsoft Visio drawing template", + REFERENCE_URL, + ""}, + {"org.openxmlformats.drawingml.visio.macroenabled", + {"org.openxmlformats.openxml", "general.composite-object"}, + {".vsdm"}, + {}, + "Visio macro-enabled drawing", + REFERENCE_URL, + ""}, + {"org.openxmlformats.drawingml.template.macroenabled", + {"org.openxmlformats.openxml", "general.composite-object"}, + {".vstm"}, + {}, + "Visio macro-enabled drawing template", + REFERENCE_URL, + ""}, + {"org.openxmlformats.wordprocessingml.template", + {"org.openxmlformats.openxml", "general.composite-object"}, + {".dotx"}, + {"application/vnd.openxmlformats-officedocument.wordprocessingml.template"}, + "Office Open XML document template.", + REFERENCE_URL, + ""}, + {"org.openxmlformats.presentationml.template", + {"org.openxmlformats.openxml", "general.composite-object"}, + {".potx"}, + {"application/vnd.openxmlformats-officedocument.presentationml.template"}, + "Office Open XML presentation template", + REFERENCE_URL, + ""}, + {"org.openxmlformats.presentationml.slideshow", + {"org.openxmlformats.openxml", "general.composite-object"}, + {".ppsx"}, + {"application/vnd.openxmlformats-officedocument.presentationml.slideshow"}, + "Office Open XML slide show", + REFERENCE_URL, + ""}, + {"org.openxmlformats.spreadsheetml.template", + {"org.openxmlformats.openxml", "general.composite-object"}, + {".xltx"}, + {"application/vnd.openxmlformats-officedocument.spreadsheetml.template"}, + "Office Open XML spreadsheet template", + REFERENCE_URL, + ""}, + {"org.openxmlformats.wordprocessingml.document.macroenabled", + {"org.openxmlformats.openxml", "general.composite-object", "general.executable"}, + {".docm"}, + {"application/vnd.ms-word.document.macroEnabled.12"}, + "Office Open XML word processing document (macros enabled)", + REFERENCE_URL, + ""}, + {"org.openxmlformats.wordprocessingml.template.macroenabled", + {"org.openxmlformats.openxml", "general.composite-object", "general.executable"}, + {".dotm"}, + {"application/vnd.ms-word.template.macroEnabled.12"}, + "Office Open XML word processing template (macros enabled)", + REFERENCE_URL, + ""}, + {"org.openxmlformats.spreadsheetml.template.macroenabled", + {"org.openxmlformats.openxml", "general.composite-object", "general.executable"}, + {".xltm"}, + {"application/vnd.ms-excel.template.macroEnabled.12"}, + "Office Open XML spreadsheet template (macros enabled)", + REFERENCE_URL, + ""}, + {"org.openxmlformats.spreadsheetml.addin.macroenabled", + {"org.openxmlformats.openxml", "general.composite-object", "general.executable"}, + {".xlam"}, + {"application/vnd.ms-excel.addin.macroEnabled.12"}, + "Office Open XML spreadsheet addin (macros enabled)", + REFERENCE_URL, + ""}, + {"org.openxmlformats.spreadsheetml.binary.macroenabled", + {"org.openxmlformats.openxml", "general.composite-object", "general.executable"}, + {".xlsb"}, + {"application/vnd.ms-excel.sheet.binary.macroEnabled.12"}, + "Office Open XML spreadsheet binary (macros enabled)", + REFERENCE_URL, + ""}, + {"org.openxmlformats.spreadsheetml.sheet.macroenabled", + {"org.openxmlformats.openxml", "general.composite-object", "general.executable"}, + {".xlsm"}, + {"application/vnd.ms-excel.sheet.macroEnabled.12"}, + "Office Open XML spreadsheet (macros enabled)", + REFERENCE_URL, + ""}, + {"org.openxmlformats.presentationml.addin.macroenabled", + {"org.openxmlformats.openxml", "general.composite-object", "general.executable"}, + {".ppam"}, + {"application/vnd.ms-powerpoint.addin.macroEnabled.12"}, + "Office Open XML presentation addin (macros enabled)", + REFERENCE_URL, + ""}, + {"org.openxmlformats.presentationml.presentation.macroenabled", + {"org.openxmlformats.openxml", "general.composite-object", "general.executable"}, + {".pptm"}, + {"application/vnd.ms-powerpoint.presentation.macroEnabled.12"}, + "Office Open XML presentation (macros enabled)", + REFERENCE_URL, + ""}, + {"org.openxmlformats.presentationml.slideshow.macroenabled", + {"org.openxmlformats.openxml", "general.composite-object", "general.executable"}, + {".ppsm"}, + {"application/vnd.ms-powerpoint.slideshow.macroEnabled.12"}, + "Office Open XML slide show (macros enabled)", + REFERENCE_URL, + ""}, + {"org.openxmlformats.presentationml.template.macroenabled", + {"org.openxmlformats.openxml", "general.composite-object", "general.executable"}, + {".potm"}, + {"application/vnd.ms-powerpoint.template.macroEnabled.12"}, + "Office Open XML presentation template (macros enabled)", + REFERENCE_URL, + ""}, + {"org.openoffice", + {"general.zip-archive"}, + {}, + {}, + "OpenOffice document format for open-source office software suite", + REFERENCE_URL, + ""}, + {"org.openoffice.calc", + {"org.openoffice", "general.composite-object"}, + {".sxc"}, + {"application/vnd.sun.xml.calc"}, + "StarOffice Calc spreadsheet", + REFERENCE_URL, + ""}, + {"org.openoffice.draw", + {"org.openoffice", "general.composite-object"}, + {".sxd"}, + {"application/vnd.sun.xml.draw"}, + "StarOffice Drawing", + REFERENCE_URL, + ""}, + {"org.openoffice.writer-global", + {"org.openoffice", "general.composite-object"}, + {".sxg"}, + {"application/vnd.sun.xml.writer.global"}, + "Apache OpenOffice master document", + REFERENCE_URL, + ""}, + {"org.openoffice.impress", + {"org.openoffice", "general.composite-object"}, + {".sxi"}, + {"application/vnd.sun.xml.impress"}, + "StarOffice Impress presentation", + REFERENCE_URL, + ""}, + {"org.openoffice.math", + {"org.openoffice", "general.composite-object"}, + {".sxm"}, + {"application/vnd.sun.xml.math"}, + "StarMath Formula", + REFERENCE_URL, + ""}, + {"org.openoffice.writer", + {"org.openoffice", "general.composite-object"}, + {".sxw"}, + {"application/vnd.sun.xml.writer"}, + "StarOffice Writer document", + REFERENCE_URL, + ""}, + {"org.openoffice.calc.template", + {"org.openoffice", "general.composite-object"}, + {".stc"}, + {"application/vnd.sun.xml.calc.template"}, + "StarOffice Calc spreadsheet template", + REFERENCE_URL, + ""}, + {"org.openoffice.draw.template", + {"org.openoffice", "general.composite-object"}, + {".std"}, + {"application/vnd.sun.xml.draw.template"}, + "Apache OpenOffice Drawing template", + REFERENCE_URL, + ""}, + {"org.openoffice.impress.template", + {"org.openoffice", "general.composite-object"}, + {".sti"}, + {"application/vnd.sun.xml.impress.template"}, + "StarOffice Presentation template", + REFERENCE_URL, + ""}, + {"org.openoffice.writer.template", + {"org.openoffice", "general.composite-object"}, + {".stw"}, + {"application/vnd.sun.xml.writer.template"}, + "StarOffice Document template", + REFERENCE_URL, + ""}, + {"com.staroffice", + {"general.zip-archive"}, + {}, + {}, + "StarOffice document format", + REFERENCE_URL, + ""}, + {"com.staroffice.draw", + {"com.staroffice", "general.composite-object"}, + {".sda"}, + {"application/vnd.stardivision.draw"}, + "StarOffice Drawing", + REFERENCE_URL, + ""}, + {"com.staroffice.calc", + {"com.staroffice", "general.composite-object"}, + {".sdc"}, + {"application/vnd.stardivision.calc"}, + "StarOffice Calc spreadsheet", + REFERENCE_URL, + ""}, + {"com.staroffice.impress", + {"com.staroffice", "general.composite-object"}, + {".sdd", ".sdp"}, + {"application/vnd.stardivision.impress"}, + "StarOffice Presentation", + REFERENCE_URL, + ""}, + {"com.staroffice.writer", + {"com.staroffice", "general.composite-object"}, + {".sdw"}, + {"application/vnd.stardivision.writer"}, + "StarOffice Writer text document", + REFERENCE_URL, + ""}, + {"com.staroffice.chart", + {"com.staroffice", "general.composite-object"}, + {".sds"}, + {"application/vnd.stardivision.chart"}, + "StarOffice Chart", + REFERENCE_URL, + ""}, + {"com.staroffice.mail", + {"com.staroffice", "general.composite-object"}, + {".sdm"}, + {"application/vnd.stardivision.mail"}, + "StarOffice Mail message", + REFERENCE_URL, + ""}, + {"com.staroffice.writer-global", + {"com.staroffice", "general.composite-object"}, + {".sgl"}, + {"application/vnd.stardivision.writer-global"}, + "StarOffice Master document", + REFERENCE_URL, + ""}, + {"com.staroffice.math", + {"com.staroffice", "general.composite-object"}, + {".smf"}, + {"application/vnd.stardivision.math"}, + "StarMath Formula file", + REFERENCE_URL, + ""}, + {"com.staroffice.template", + {"com.staroffice", "general.composite-object"}, + {".vor"}, + {"application/vnd.stardivision.template"}, + "StarOffice Template", + REFERENCE_URL, + ""}, + {"org.tug.bib", + {"general.tex"}, + {".bib"}, + {"text/x-bibtex"}, + "TeX Bibliography file", + REFERENCE_URL, + ""}, + {"org.tug.cls", + {"general.tex"}, + {".cls"}, + {"text/x-tex"}, + "TeX Class file", + REFERENCE_URL, + ""}, + {"org.tug.sty", + {"general.tex"}, + {".sty"}, + {"text/x-tex"}, + "TeX Style file", + REFERENCE_URL, + ""}, + {"org.tug.tex", + {"general.tex"}, + {".tex"}, + {"text/x-tex"}, + "TeX source document file", + REFERENCE_URL, + ""}, + {"org.latex-project.latex", + {"general.tex"}, + {".ltx", ".latex"}, + {"application/x-latex"}, + "LaTeX source document file", + REFERENCE_URL, + ""}, + {"org.matroska.mkv", + {"general.video"}, + {".mkv"}, + {"video/x-matroska"}, + "Matroska video", + REFERENCE_URL, + ""}, + {"org.matroska.mka", + {"general.audio"}, + {".mka"}, + {"audio/x-matroska"}, + "Matroska audio", + REFERENCE_URL, + ""}, + {"com.sgi.movie", + {"general.video"}, + {".movie"}, + {"video/x-sgi-movie"}, + "SGI movie", + REFERENCE_URL, + ""}, + {"com.apple.m4v", + {"general.video"}, + {".m4v"}, + {"video/m4v"}, + "M4V video", + REFERENCE_URL, + ""}, + {"org.webmproject.webm", + {"general.video"}, + {".webm"}, + {"video/webm"}, + "WebM is an audiovisual media file format", + REFERENCE_URL, + ""}, + {"com.apple.quicktime-movie", + {"general.video"}, + {".mov", ".qt", ".movie"}, + {"video/quicktime"}, + "QuickTime File Format", + REFERENCE_URL, + ""}, + {"com.coreldraw.cdr", + {"general.image"}, + {".cdr"}, + {"image/x-coreldraw"}, + "CorelDRAW file", + REFERENCE_URL, + ""}, + {"com.coreldraw.cdt", + {"general.image"}, + {".cdt"}, + {"image/x-coreldrawtemplate"}, + "CorelDRAW template", + REFERENCE_URL, + ""}, + {"com.coreldraw.cpt", + {"general.image"}, + {".cpt"}, + {"image/x-corelphotopaint"}, + "Corel PHOTO-PAINT image", + REFERENCE_URL, + ""}, + {"com.coreldraw.pat", + {"general.image"}, + {".pat"}, + {"image/x-coreldrawpattern"}, + "CorelDRAW pattern file", + REFERENCE_URL, + ""}, + {"com.microsoft.cur", + {"general.image"}, + {".cur"}, + {"image/ico"}, + "Microsoft Windows cursor image", + REFERENCE_URL, + ""}, + {"com.sun.raster", + {"general.image"}, + {".ras"}, + {"image/x-cmu-raster"}, + "Sun Raster Graphic", + REFERENCE_URL, + ""}, + {"com.google.webp", + {"general.image"}, + {".webp"}, + {"image/webp"}, + "WebP image", + REFERENCE_URL, + ""}, + {"com.sseyo.koan-audio", + {"general.audio"}, + {".skd", ".skm", ".skp", ".skt"}, + {"application/x-koan"}, + "Koan music files over the internet", + REFERENCE_URL, + ""}, + {"io.qt.moc", + {"general.source-code"}, + {".moc"}, + {"text/x-moc"}, + "Qt Meta-Object compiler file", + REFERENCE_URL, + ""}, + {"com.ghostscript.font", + {"general.font"}, + {".gsf"}, + {"application/x-font"}, + "Ghostscript font", + REFERENCE_URL, + ""}, + {"org.x.pcf-font", + {"general.font"}, + {".pcf"}, + {"application/x-font", "application/x-font-pcf"}, + "Portable compiled format", + REFERENCE_URL, + ""}, + {"com.microsoft.windows-media-wmd", + {"com.microsoft.advanced-systems-format", "general.zip-archive"}, + {".wmd"}, + {"application/x-ms-wmd"}, + "Windows media download package", + REFERENCE_URL, + ""}, + {"com.microsoft.windows-media-wmz", + {"com.microsoft.advanced-systems-format", "general.zip-archive"}, + {".wmz"}, + {"application/x-ms-wmz"}, + "Windows media player skin package", + REFERENCE_URL, + ""}, + {"com.microsoft.windows-installer", + {"general.executable"}, + {".msi"}, + {"application/x-msi"}, + "Windows installer package", + REFERENCE_URL, + ""}, + {"com.microsoft.publisher.pub", + {"general.composite-object"}, + {".pub"}, + {"application/x-mspublisher"}, + "Publisher document", + REFERENCE_URL, + ""}, + {"com.microsoft.windows-media-playlist", + {"general.xml", "general.media"}, + {".wpl"}, + {"application/vnd.ms-wpl"}, + "Windows media player playlist", + REFERENCE_URL, + ""}, + {"com.microsoft.access.mdb", + {"general.database"}, + {".mdb"}, + {"application/msaccess"}, + "Microsoft Access database", + REFERENCE_URL, + ""}, + {"com.3dsystems.stereolithography", + {"general.composite-object"}, + {".stl"}, + {"application/vnd.ms-pki.stl"}, + "Stereolithography file", + REFERENCE_URL, + ""}, + {"com.apple.media.playlist", + {"general.media"}, + {".m3u8"}, + {"application/vnd.apple.mpegurl"}, + "UTF-8 M3U playlist", + REFERENCE_URL, + ""}, + {"com.abisource.word", + {"general.composite-object"}, + {".abw"}, + {"application/x-abiword"}, + "AbiWord document", + REFERENCE_URL, + ""}, + {"com.adobe.framemaker", + {"general.composite-object"}, + {".book", ".fm", ".frame", ".maker"}, + {"application/x-maker"}, + "FrameMaker book file", + REFERENCE_URL, + ""}, + {"com.wolfram.cdf", + {"general.composite-object"}, + {".cdf"}, + {"application/x-cdf"}, + "Computable document format file", + REFERENCE_URL, + ""}, + {"de.cinderella.cdy", + {"general.composite-object"}, + {".cdy"}, + {"application/vnd.cinderella"}, + "Cinderella construction file", + REFERENCE_URL, + ""}, + {"com.adobe.dcr", + {"general.video"}, + {".dcr"}, + {"application/x-director"}, + "Shockwave media file", + REFERENCE_URL, + ""}, + {"com.adobe.dir", + {"general.video"}, + {".dir"}, + {"application/x-director"}, + "Adobe Director movie", + REFERENCE_URL, + ""}, + {"com.adobe.dxr", + {"general.video"}, + {".dxr"}, + {"application/x-director"}, + "Protected macromedia director movie", + REFERENCE_URL, + ""}, + {"org.gnumeric.spreadsheet", + {"general.xml"}, + {".gnumeric"}, + {"application/x-gnumeric"}, + "Gnumeric spreadsheet", + REFERENCE_URL, + ""}, + {"org.hdfgroup.hdf", + {"general.composite-object"}, + {".hdf"}, + {"application/x-hdf"}, + "Hierarchical data format", + REFERENCE_URL, + ""}, + {"com.apple.binhex-archive", + {"general.archive"}, + {".hqx"}, + {"application/mac-binhex40"}, + "BinHex 4.0 encoded file", + REFERENCE_URL, + ""}, + {"com.microsoft.hta", + {"general.archive", "general.executable"}, + {".hta"}, + {"application/hta"}, + "HTML application", + REFERENCE_URL, + ""}, + {"com.microsoft.internet.ins", + {"general.text"}, + {".ins"}, + {"application/x-internet-signup"}, + "Internet settings file", + REFERENCE_URL, + ""}, + {"com.microsoft.internet.isp", + {"general.text"}, + {".isp"}, + {"application/x-internet-signup"}, + "IIS internet service provider settings", + REFERENCE_URL, + ""}, + {"org.troff", + {"general.text"}, + {".man", ".t", ".roff"}, + {"text/troff"}, + "Unix troff format", + REFERENCE_URL, + ""}, + {"com.adobe.framemaker.mif", + {"general.composite-object"}, + {".mif"}, + {"application/vnd.mif"}, + "FrameMaker interchange format file", + REFERENCE_URL, + ""}, + {"io.sourceforge.freemind", + {"general.composite-object"}, + {".mm"}, + {"application/x-freemind"}, + "Mind Map file", + REFERENCE_URL, + ""}, + {"com.yamaha.smaf", + {"general.audio"}, + {".mmf"}, + {"application/vnd.smaf"}, + "Synthetic music mobile application file", + REFERENCE_URL, + ""}, + {"com.wolfram.mathematica.notebook", + {"general.text"}, + {".nb"}, + {"application/mathematica"}, + "Mathematica notebook", + REFERENCE_URL, + ""}, + {"org.xiph.ogg", + {"general.audio"}, + {".oga", ".ogg"}, + {"application/ogg"}, + "Ogg vorbis audio", + REFERENCE_URL, + ""}, + {"com.netscape.proxy-autoconfig", + {"general.plain-text"}, + {".pac"}, + {"application/x-ns-proxy-autoconfig"}, + "Proxy auto-config file", + REFERENCE_URL, + ""}, + {"com.rsa.pkcs-12", + {"general.archive"}, + {".pfx", ".p12"}, + {"application/x-pkcs12"}, + "PKCS #12 certificate file", + REFERENCE_URL, + ""}, + {"org.openpgp.signature", + {"general.object"}, + {".pgp"}, + {"application/pgp-signature"}, + "PGP security key", + REFERENCE_URL, + ""}, + {"com.apple.quicktime-link", + {"general.text"}, + {".qtl"}, + {"application/x-quicktimeplayer"}, + "QuickTime link file", + REFERENCE_URL, + ""}, + {"com.rarlab.rar-archive", + {"general.archive"}, + {".rar"}, + {"application/rar", "application/vnd.rar"}, + "WinRAR compressed archive", + REFERENCE_URL, + ""}, + {"org.7-zip.7-zip-archive", + {"general.archive"}, + {".7z"}, + {"application/x-7z-compressed"}, + "7-zip compressed archive", + REFERENCE_URL, + ""}, + {"com.red-bean.sgf", + {"general.text"}, + {".sgf"}, + {"application/x-go-sgf"}, + "Smart game format file", + REFERENCE_URL, + ""}, + {"com.stuffit.sit-archive", + {"general.archive"}, + {".sit"}, + {"application/x-stuffit"}, + "Stuffit archive", + REFERENCE_URL, + ""}, + {"com.adobe.futuresplash", + {"general.video"}, + {".spl"}, + {"application/futuresplash", "application/x-futuresplash"}, + "FutureSplash animation", + REFERENCE_URL, + ""}, + {"com.adobe.flash", + {"general.video"}, + {".swf"}, + {"application/x-shockwave-flash"}, + "Shockwave flash movie", + REFERENCE_URL, + ""}, + {"org.gnu.texinfo", + {"general.source-code"}, + {".texinfo", ".texi"}, + {"application/x-texinfo"}, + "GNU Texinfo", + REFERENCE_URL, + ""}, + {"org.bittorrent.torrent", + {"general.text"}, + {".torrent"}, + {"application/x-bittorrent"}, + "BitTorrent file", + REFERENCE_URL, + ""}, + {"com.idsoftware.doom", + {"general.archive"}, + {".wad"}, + {"application/x-doom"}, + "Doom WAD file", + REFERENCE_URL, + ""}, + {"com.apple.webarchive", + {"general.archive"}, + {".webarchive"}, + {"application/x-webarchive"}, + "Safari web archive", + REFERENCE_URL, + ""}, + {"com.android.webarchive", + {"general.archive"}, + {".webarchivexml"}, + {"application/x-webarchive-xml"}, + "Android web browser archive", + REFERENCE_URL, + ""}, + {"org.gimp.xcf", + {"general.image"}, + {".xcf"}, + {"application/x-xcf", "image/x-xcf"}, + "eXperimental computing facility, GIMP image file", + REFERENCE_URL, + ""}, + {"com.edrawsoft.edrawmax", + {"general.xml"}, + {".eddx"}, + {"application/x-eddx"}, + "Edraw Max XML file", + REFERENCE_URL, + ""}, + {"com.edrawsoft.edrawmind", + {"general.xml"}, + {".emmx"}, + {"application/x-emmx"}, + "Edraw MindMaster XML file", + REFERENCE_URL, + ""}, + {"net.cnki.caj", + {"general.composite-object"}, + {".caj"}, + {"application/caj"}, + "Chinese academic journal file", + REFERENCE_URL, + ""}, + {"com.dbase.dbf", + {"general.database"}, + {".dbf"}, + {"application/dbf", "application/dbase"}, + "Database file", + REFERENCE_URL, + ""}, + {"com.autodesk.dwg", + {"general.composite-object"}, + {".dwg"}, + {"image/vnd.dwg"}, + "AutoCAD drawing", + REFERENCE_URL, + ""}, + {"com.autodesk.dxf", + {"general.composite-object"}, + {".dxf"}, + {"image/vnd.dxf"}, + "Drawing exchange format file", + REFERENCE_URL, + ""}, + {"com.autodesk.dws", + {"general.composite-object"}, + {".dws"}, + {}, + "AutoCAD drawing standards file", + REFERENCE_URL, + ""}, + {"com.autodesk.dwt", + {"general.composite-object"}, + {".dwt"}, + {}, + "AutoCAD drawing template", + REFERENCE_URL, + ""}, + {"com.autodesk.dwf", + {"general.composite-object"}, + {".dwf"}, + {"model/vnd.dwf"}, + "Design web format file", + REFERENCE_URL, + ""}, + {"com.autodesk.dwfx", + {"general.composite-object"}, + {".dwfx"}, + {}, + "Design web format XPS file", + REFERENCE_URL, + ""}, + {"com.autodesk.shp", + {"general.composite-object"}, + {".shp"}, + {}, + "3D studio shape", + REFERENCE_URL, + ""}, + {"com.autodesk.shx", + {"general.composite-object"}, + {".shx"}, + {}, + "AutoCAD compiled shape file", + REFERENCE_URL, + ""}, + {"com.autodesk.slide-library", + {"general.composite-object"}, + {".slb"}, + {}, + "AutoCAD slide library", + REFERENCE_URL, + ""}, + {"com.autodesk.line", + {"general.text"}, + {".lin"}, + {}, + "AutoCAD linetype file", + REFERENCE_URL, + ""}, + {"com.autodesk.plotter", + {"general.composite-object"}, + {".plt"}, + {}, + "AutoCAD plotter document", + REFERENCE_URL, + ""}, + {"com.hp.graphics-language", + {"general.composite-object"}, + {".hpgl"}, + {"application/vnd.hp-hpgl"}, + "HP graphics language plotter file", + REFERENCE_URL, + ""}, + {"com.microsoft.metafile", + {"general.composite-object"}, + {".wmf"}, + {}, + "Windows metafile", + REFERENCE_URL, + ""}, + {"com.spatial.acis.sat", + {"general.text"}, + {".sat"}, + {}, + "ACIS SAT 3D model", + REFERENCE_URL, + ""}, + {"org.aomedia.avif-image", + {"general.image"}, + {".avif"}, + {"image/avif"}, + "AVIF image", + REFERENCE_URL, + ""}, + {"com.microsoft.dds", + {"general.image"}, + {".dds"}, + {"image/vnd-ms.dds"}, + "DirectDraw surface image", + REFERENCE_URL, + ""}, + {"com.ea.iff-ilbm", + {"general.image"}, + {".ilbm"}, + {"image/x-ilbm"}, + "Interleaved bitmap image", + REFERENCE_URL, + ""}, + {"com.canon.cr2-raw-image", + {"general.raw-image"}, + {".cr2"}, + {"image/x-canon-cr2"}, + "Canon raw 2 image", + REFERENCE_URL, + ""}, + {"com.canon.cr3-raw-image", + {"general.raw-image"}, + {".cr3"}, + {"image/x-canon-cr3"}, + "Canon raw 3 image", + REFERENCE_URL, + ""}, + {"com.canon.crw-raw-image", + {"general.raw-image"}, + {".crw"}, + {"image/x-canon-crw"}, + "Canon raw CIFF image file", + REFERENCE_URL, + ""}, + {"com.adobe.dng-raw-image", + {"general.raw-image"}, + {".dng"}, + {"image/x-adobe-dng"}, + "Digital negative image", + REFERENCE_URL, + ""}, + {"com.sony.arw-raw-image", + {"general.raw-image"}, + {".arw"}, + {"image/x-sony-arw"}, + "Sony alpha raw digital camera image", + REFERENCE_URL, + ""}, + {"com.nikon.nef-raw-image", + {"general.raw-image"}, + {".nef"}, + {"image/x-nikon-nef"}, + "Nikon electronic format RAW image", + REFERENCE_URL, + ""}, + {"com.mindjet.mindmanager.mmap", + {"general.composite-object"}, + {".mmap"}, + {}, + "MindManager Map", + REFERENCE_URL, + ""}, + {"com.microsoft.email", + {"general.message"}, + {".eml"}, + {"message/rfc822"}, + "E-Mail message", + REFERENCE_URL, + ""}, + {"com.microsoft.message", + {"general.message"}, + {".msg"}, + {}, + "Outlook message item file", + REFERENCE_URL, + ""}, + {"com.microsoft.pst", + {"general.archive"}, + {".pst"}, + {}, + "Outlook personal information store", + REFERENCE_URL, + ""}, + {"com.kingsoft.office", + {"general.zip-archive"}, + {}, + {}, + "Kingsoft office suite", + REFERENCE_URL, + ""}, + {"com.kingsoft.office.writer.wps", + {"com.kingsoft.office", "general.composite-object"}, + {".wps"}, + {}, + "Kingsoft Writer document", + REFERENCE_URL, + ""}, + {"com.kingsoft.office.writer.wpt", + {"com.kingsoft.office", "general.composite-object"}, + {".wpt"}, + {}, + "Kingsoft Writer template", + REFERENCE_URL, + ""}, + {"com.kingsoft.office.presentation.dps", + {"com.kingsoft.office", "general.composite-object"}, + {".dps"}, + {}, + "Kingsoft Presentation file", + REFERENCE_URL, + ""}, + {"com.kingsoft.office.presentation.template", + {"com.kingsoft.office", "general.composite-object"}, + {".dpt"}, + {}, + "Kingsoft Presentation template", + REFERENCE_URL, + ""}, + {"com.kingsoft.office.spreadsheets.et", + {"com.kingsoft.office", "general.composite-object"}, + {".et"}, + {}, + "Kingsoft Spreadsheets tile", + REFERENCE_URL, + ""}, + {"com.kingsoft.office.spreadsheets.template", + {"com.kingsoft.office", "general.composite-object"}, + {".ett"}, + {}, + "Kingsoft Spreadsheets template", + REFERENCE_URL, ""} }; } diff --git a/udmf/framework/innerkitsimpl/data/preset_type_descriptors.h b/udmf/framework/innerkitsimpl/data/preset_type_descriptors.h index ab69dcaf..6278bef2 100644 --- a/udmf/framework/innerkitsimpl/data/preset_type_descriptors.h +++ b/udmf/framework/innerkitsimpl/data/preset_type_descriptors.h @@ -17,10 +17,10 @@ #include #include "error_code.h" #include "utd_common.h" - +#include "visibility.h" namespace OHOS { namespace UDMF { -class PresetTypeDescriptors { +class API_EXPORT PresetTypeDescriptors { public: static PresetTypeDescriptors &GetInstance(); std::vector &GetPresetTypes(); diff --git a/udmf/framework/innerkitsimpl/data/type_descriptor.cpp b/udmf/framework/innerkitsimpl/data/type_descriptor.cpp index 35ac0350..64f488bd 100644 --- a/udmf/framework/innerkitsimpl/data/type_descriptor.cpp +++ b/udmf/framework/innerkitsimpl/data/type_descriptor.cpp @@ -19,7 +19,7 @@ #include "flexible_type.h" namespace OHOS { namespace UDMF { -TypeDescriptor::TypeDescriptor(const std::string &typeId, const std::set &belongingToTypes, +TypeDescriptor::TypeDescriptor(const std::string &typeId, const std::vector &belongingToTypes, const std::vector &filenameExtensions, const std::vector &mimeTypes, const std::string &description, const std::string &referenceURL, const std::string &iconFile) : typeId_(typeId), belongingToTypes_(belongingToTypes), filenameExtensions_(filenameExtensions), mimeTypes_(mimeTypes), @@ -138,7 +138,7 @@ const std::string& TypeDescriptor::GetTypeId() const return typeId_; } -std::set TypeDescriptor::GetBelongingToTypes() +std::vector TypeDescriptor::GetBelongingToTypes() { return belongingToTypes_; } diff --git a/udmf/framework/innerkitsimpl/data/unified_data.cpp b/udmf/framework/innerkitsimpl/data/unified_data.cpp index 1878340e..1d31e218 100644 --- a/udmf/framework/innerkitsimpl/data/unified_data.cpp +++ b/udmf/framework/innerkitsimpl/data/unified_data.cpp @@ -23,12 +23,15 @@ namespace UDMF { UnifiedData::UnifiedData() { properties_ = std::make_shared(); - properties_->timestamp = std::chrono::steady_clock::now().time_since_epoch().count(); + auto duration = std::chrono::system_clock::now().time_since_epoch(); + properties_->timestamp = std::chrono::duration_cast(duration).count(); } UnifiedData::UnifiedData(std::shared_ptr properties) { properties_ = properties; + auto duration = std::chrono::system_clock::now().time_since_epoch(); + properties_->timestamp = std::chrono::duration_cast(duration).count(); } int64_t UnifiedData::GetSize() @@ -104,7 +107,7 @@ std::string UnifiedData::GetTypes() { std::string types; for (const std::shared_ptr &record : records_) { - types.append("-").append(UD_TYPE_MAP.at(record->GetType())); + types.append("-").append(UtdUtils::GetUtdIdFromUtdEnum(record->GetType())); } return types; } @@ -113,7 +116,7 @@ std::vector UnifiedData::GetTypesLabels() const { std::vector types; for (const std::shared_ptr &record : records_) { - types.push_back(UD_TYPE_MAP.at(record->GetType())); + types.push_back(UtdUtils::GetUtdIdFromUtdEnum(record->GetType())); } return types; } @@ -121,7 +124,7 @@ std::vector UnifiedData::GetTypesLabels() const bool UnifiedData::HasType(const std::string &type) const { for (const std::shared_ptr &record : records_) { - if (UD_TYPE_MAP.at(record->GetType()) == type) { + if (UtdUtils::GetUtdIdFromUtdEnum(record->GetType()) == type) { return true; } } @@ -163,6 +166,7 @@ bool UnifiedData::IsComplete() void UnifiedData::SetProperties(std::shared_ptr properties) { + properties->timestamp = properties_->timestamp; properties_ = properties; } diff --git a/udmf/framework/innerkitsimpl/data/unified_data_helper.cpp b/udmf/framework/innerkitsimpl/data/unified_data_helper.cpp index 778bdab5..80e34e35 100644 --- a/udmf/framework/innerkitsimpl/data/unified_data_helper.cpp +++ b/udmf/framework/innerkitsimpl/data/unified_data_helper.cpp @@ -107,7 +107,7 @@ void UnifiedDataHelper::GetSummary(const UnifiedData &data, Summary &summary) { for (const auto &record : data.GetRecords()) { int64_t recordSize = record->GetSize(); - auto udType = UD_TYPE_MAP.at(record->GetType()); + auto udType = UtdUtils::GetUtdIdFromUtdEnum(record->GetType()); auto it = summary.summary.find(udType); if (it == summary.summary.end()) { summary.summary[udType] = recordSize; @@ -195,7 +195,10 @@ bool UnifiedDataHelper::LoadUDataFromFile(const std::string &dataFile, UnifiedDa std::string path = fileUri.GetRealPath(); std::FILE *file = fopen(path.c_str(), "r"); if (file == nullptr) { - LOG_ERROR(UDMF_FRAMEWORK, "failed to open file"); + LOG_ERROR(UDMF_FRAMEWORK, "failed to open file, error:%{public}s, srcdir:%{public}s, relPath:%{public}s", + std::strerror(errno), + dataFile.c_str(), + path.c_str()); return false; } recordTlv.SetFile(file); diff --git a/udmf/framework/innerkitsimpl/service/distributeddata_udmf_ipc_interface_code.h b/udmf/framework/innerkitsimpl/service/distributeddata_udmf_ipc_interface_code.h index 3d7aa342..5ea9fbee 100644 --- a/udmf/framework/innerkitsimpl/service/distributeddata_udmf_ipc_interface_code.h +++ b/udmf/framework/innerkitsimpl/service/distributeddata_udmf_ipc_interface_code.h @@ -29,6 +29,9 @@ enum class UdmfServiceInterfaceCode : uint32_t { ADD_PRIVILEGE, SYNC, IS_REMOTE_DATA, + SET_APP_SHARE_OPTION, + GET_APP_SHARE_OPTION, + REMOVE_APP_SHARE_OPTION, CODE_BUTT }; } // namespace OHOS::UDMF diff --git a/udmf/framework/innerkitsimpl/service/udmf_service.h b/udmf/framework/innerkitsimpl/service/udmf_service.h index 1f8f2478..22c367a1 100644 --- a/udmf/framework/innerkitsimpl/service/udmf_service.h +++ b/udmf/framework/innerkitsimpl/service/udmf_service.h @@ -46,6 +46,9 @@ public: virtual int32_t AddPrivilege(const QueryOption &query, Privilege &privilege) = 0; virtual int32_t Sync(const QueryOption &query, const std::vector &devices) = 0; virtual int32_t IsRemoteData(const QueryOption &query, bool &result) = 0; + virtual int32_t SetAppShareOption(const std::string &intention, int32_t shareOption) = 0; + virtual int32_t GetAppShareOption(const std::string &intention, int32_t &shareOption) = 0; + virtual int32_t RemoveAppShareOption(const std::string &intention) = 0; }; } // namespace UDMF } // namespace OHOS diff --git a/udmf/framework/innerkitsimpl/service/udmf_service_client.cpp b/udmf/framework/innerkitsimpl/service/udmf_service_client.cpp index 1031c11f..395763d3 100644 --- a/udmf/framework/innerkitsimpl/service/udmf_service_client.cpp +++ b/udmf/framework/innerkitsimpl/service/udmf_service_client.cpp @@ -248,5 +248,36 @@ int32_t UdmfServiceClient::IsRemoteData(const QueryOption &query, bool &result) } return udmfProxy_->IsRemoteData(query, result); } + +int32_t UdmfServiceClient::SetAppShareOption(const std::string &intention, int32_t shareOption) +{ + LOG_DEBUG(UDMF_SERVICE, "start, intention: %{public}s, shareOption: %{public}d", + intention.c_str(), shareOption); + if (intention.empty() || shareOption < IN_APP || shareOption > CROSS_APP) { + LOG_ERROR(UDMF_SERVICE, "invalid parameters"); + return E_INVALID_PARAMETERS; + } + return udmfProxy_->SetAppShareOption(intention, shareOption); +} + +int32_t UdmfServiceClient::GetAppShareOption(const std::string &intention, int32_t &shareOption) +{ + LOG_DEBUG(UDMF_SERVICE, "start, intention: %{public}s", intention.c_str()); + if (intention.empty()) { + LOG_ERROR(UDMF_SERVICE, "invalid parameters"); + return E_INVALID_PARAMETERS; + } + return udmfProxy_->GetAppShareOption(intention, shareOption); +} + +int32_t UdmfServiceClient::RemoveAppShareOption(const std::string &intention) +{ + LOG_DEBUG(UDMF_SERVICE, "start, intention: %{public}s", intention.c_str()); + if (intention.empty()) { + LOG_ERROR(UDMF_SERVICE, "invalid parameters"); + return E_INVALID_PARAMETERS; + } + return udmfProxy_->RemoveAppShareOption(intention); +} } // namespace UDMF } // namespace OHOS \ No newline at end of file diff --git a/udmf/framework/innerkitsimpl/service/udmf_service_client.h b/udmf/framework/innerkitsimpl/service/udmf_service_client.h index d2c12151..c16f1bca 100644 --- a/udmf/framework/innerkitsimpl/service/udmf_service_client.h +++ b/udmf/framework/innerkitsimpl/service/udmf_service_client.h @@ -41,6 +41,9 @@ public: int32_t AddPrivilege(const QueryOption &query, Privilege &privilege) override; int32_t Sync(const QueryOption &query, const std::vector &devices) override; int32_t IsRemoteData(const QueryOption &query, bool &result) override; + int32_t SetAppShareOption(const std::string &intention, int32_t shareOption) override; + int32_t GetAppShareOption(const std::string &intention, int32_t &shareOption) override; + int32_t RemoveAppShareOption(const std::string &intention) override; private: class ServiceDeathRecipient : public IRemoteObject::DeathRecipient { diff --git a/udmf/framework/innerkitsimpl/service/udmf_service_proxy.cpp b/udmf/framework/innerkitsimpl/service/udmf_service_proxy.cpp index 40cc5f2e..f75db09d 100644 --- a/udmf/framework/innerkitsimpl/service/udmf_service_proxy.cpp +++ b/udmf/framework/innerkitsimpl/service/udmf_service_proxy.cpp @@ -180,6 +180,47 @@ int32_t UdmfServiceProxy::IsRemoteData(const QueryOption &query, bool &result) return status; } +int32_t UdmfServiceProxy::SetAppShareOption(const std::string &intention, int32_t shareOption) +{ + MessageParcel reply; + int32_t status = IPC_SEND(UdmfServiceInterfaceCode::SET_APP_SHARE_OPTION, reply, intention, shareOption); + if (status != E_OK) { + LOG_ERROR(UDMF_SERVICE, "status:0x%{public}x!", status); + return status; + } + LOG_DEBUG(UDMF_SERVICE, "end."); + return status; +} + +int32_t UdmfServiceProxy::GetAppShareOption(const std::string &intention, int32_t &shareOption) +{ + MessageParcel reply; + int32_t status = IPC_SEND(UdmfServiceInterfaceCode::GET_APP_SHARE_OPTION, reply, intention); + if (status != E_OK) { + LOG_ERROR(UDMF_SERVICE, "status:0x%{public}x!", status); + return status; + } + + if (!ITypesUtil::Unmarshal(reply, shareOption)) { + LOG_ERROR(UDMF_SERVICE, "Unmarshal shareOption failed!"); + return E_READ_PARCEL_ERROR; + } + LOG_DEBUG(UDMF_SERVICE, "end."); + return status; +} + +int32_t UdmfServiceProxy::RemoveAppShareOption(const std::string &intention) +{ + MessageParcel reply; + int32_t status = IPC_SEND(UdmfServiceInterfaceCode::REMOVE_APP_SHARE_OPTION, reply, intention); + if (status != E_OK) { + LOG_ERROR(UDMF_SERVICE, "status:0x%{public}x!", status); + return status; + } + LOG_DEBUG(UDMF_SERVICE, "end."); + return status; +} + int32_t UdmfServiceProxy::SendRequest(UdmfServiceInterfaceCode code, MessageParcel &data, MessageParcel &reply, MessageOption &option) { diff --git a/udmf/framework/innerkitsimpl/service/udmf_service_proxy.h b/udmf/framework/innerkitsimpl/service/udmf_service_proxy.h index 64d38bac..7f86f0ce 100644 --- a/udmf/framework/innerkitsimpl/service/udmf_service_proxy.h +++ b/udmf/framework/innerkitsimpl/service/udmf_service_proxy.h @@ -44,7 +44,9 @@ public: int32_t AddPrivilege(const QueryOption &query, Privilege &privilege) override; int32_t Sync(const QueryOption &query, const std::vector &devices) override; int32_t IsRemoteData(const QueryOption &query, bool &result) override; - + int32_t SetAppShareOption(const std::string &intention, int32_t shareOption) override; + int32_t GetAppShareOption(const std::string &intention, int32_t &shareOption) override; + int32_t RemoveAppShareOption(const std::string &intention) override; private: static inline BrokerDelegator delegator_; int32_t SendRequest(UdmfServiceInterfaceCode code, MessageParcel &data, diff --git a/udmf/framework/innerkitsimpl/test/unittest/BUILD.gn b/udmf/framework/innerkitsimpl/test/unittest/BUILD.gn index 09d53bff..68bf79b5 100644 --- a/udmf/framework/innerkitsimpl/test/unittest/BUILD.gn +++ b/udmf/framework/innerkitsimpl/test/unittest/BUILD.gn @@ -46,16 +46,43 @@ ohos_unittest("UdmfClientTest") { module_out_path = module_output_path sources = [ + "${udmf_framework_path}/common/graph.cpp", + "udmf_client_test.cpp", + ] + + configs = [ ":module_private_config" ] + + deps = common_deps + + external_deps = common_external_deps +} + +ohos_unittest("UdmfClientSystemHapTest") { + module_out_path = module_output_path + + sources = [ "udmf_client_system_hap_test.cpp" ] + + configs = [ ":module_private_config" ] + + deps = common_deps + + external_deps = common_external_deps +} + +ohos_unittest("UtdClientTest") { + module_out_path = module_output_path + + sources = [ + "${udmf_framework_path}/common/graph.cpp", "custom_utd_json_parser_test.cpp", "custom_utd_store_test.cpp", "graph_test.cpp", - "udmf_client_test.cpp", "utd_client_test.cpp", ] configs = [ ":module_private_config" ] - deps = common_deps + deps = [ "${udmf_interfaces_path}/innerkits:utd_client" ] external_deps = common_external_deps } @@ -64,6 +91,10 @@ ohos_unittest("UdmfClientTest") { group("unittest") { testonly = true - deps = [ ":UdmfClientTest" ] + deps = [ + ":UdmfClientSystemHapTest", + ":UdmfClientTest", + ":UtdClientTest", + ] } ############################################################################### diff --git a/udmf/framework/innerkitsimpl/test/unittest/graph_test.cpp b/udmf/framework/innerkitsimpl/test/unittest/graph_test.cpp index bfba120a..9db905ba 100644 --- a/udmf/framework/innerkitsimpl/test/unittest/graph_test.cpp +++ b/udmf/framework/innerkitsimpl/test/unittest/graph_test.cpp @@ -61,16 +61,14 @@ void GraphTest::TearDown() /** * @tc.name: DfsUnconnectedGraph001 -* @tc.desc: DfsUnconnectedGraph +* @tc.desc: is connectedGraph: A -> A * @tc.type: FUNC */ HWTEST_F(GraphTest, DfsUnconnectedGraph001, TestSize.Level1) { LOG_INFO(UDMF_TEST, "DfsUnconnectedGraph001 begin."); - uint32_t vextexNum = 3; // total point - vector> edges={{TestNodes::POINT_A, TestNodes::POINT_B}, - {TestNodes::POINT_B, TestNodes::POINT_C}, - {TestNodes::POINT_C, TestNodes::POINT_A} + uint32_t vextexNum = 1; + vector> edges={{TestNodes::POINT_A, TestNodes::POINT_A}, }; Graph graph(vextexNum); for (uint32_t i = 0; i < edges.size(); i++) { @@ -82,6 +80,11 @@ HWTEST_F(GraphTest, DfsUnconnectedGraph001, TestSize.Level1) LOG_INFO(UDMF_TEST, "DfsUnconnectedGraph001 end."); } +/** +* @tc.name: DfsUnconnectedGraph002 +* @tc.desc: is connectedGraph: A -> B -> A +* @tc.type: FUNC +*/ HWTEST_F(GraphTest, DfsUnconnectedGraph002, TestSize.Level1) { LOG_INFO(UDMF_TEST, "DfsUnconnectedGraph002 begin."); @@ -99,28 +102,259 @@ HWTEST_F(GraphTest, DfsUnconnectedGraph002, TestSize.Level1) LOG_INFO(UDMF_TEST, "DfsUnconnectedGraph002 end."); } +/** +* @tc.name: DfsUnconnectedGraph003 +* @tc.desc: is connectedGraph: A -> B -> C -> A +* @tc.type: FUNC +*/ HWTEST_F(GraphTest, DfsUnconnectedGraph003, TestSize.Level1) { LOG_INFO(UDMF_TEST, "DfsUnconnectedGraph003 begin."); - uint32_t vextexNum =8; - vector> edges = { - {TestNodes::POINT_A, TestNodes::POINT_B}, - {TestNodes::POINT_B, TestNodes::POINT_C}, - {TestNodes::POINT_C, TestNodes::POINT_D}, - {TestNodes::POINT_D, TestNodes::POINT_E}, - {TestNodes::POINT_D, TestNodes::POINT_E}, - {TestNodes::POINT_E, TestNodes::POINT_F}, - {TestNodes::POINT_E, TestNodes::POINT_G}, - {TestNodes::POINT_G, TestNodes::POINT_H}, - {TestNodes::POINT_H, TestNodes::POINT_E}, - }; + uint32_t vextexNum = 3; // total point + vector> edges={{TestNodes::POINT_A, TestNodes::POINT_B}, + {TestNodes::POINT_B, TestNodes::POINT_C}, + {TestNodes::POINT_C, TestNodes::POINT_A} + }; Graph graph(vextexNum); for (uint32_t i = 0; i < edges.size(); i++) { graph.AddEdge(edges[i][0], edges[i][1]); } bool isDAGFlag = graph.DfsUnconnectedGraph([&](uint32_t currNode) -> bool { return false; }); - EXPECT_EQ(isDAGFlag, true); + EXPECT_EQ(isDAGFlag, false); LOG_INFO(UDMF_TEST, "DfsUnconnectedGraph003 end."); } + +/** +* @tc.name: DfsUnconnectedGraph004 +* @tc.desc: is connectedGraph: A -> B -> C -> B +* @tc.type: FUNC +*/ +HWTEST_F(GraphTest, DfsUnconnectedGraph004, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "DfsUnconnectedGraph004 begin."); + uint32_t vextexNum = 3; + vector> edges={{TestNodes::POINT_A, TestNodes::POINT_B}, + {TestNodes::POINT_B, TestNodes::POINT_C}, + {TestNodes::POINT_C, TestNodes::POINT_B}, + }; + Graph graph(vextexNum); + for (uint32_t i = 0; i < edges.size(); i++) { + graph.AddEdge(edges[i][0], edges[i][1]); + } + bool isDAGFlag = graph.DfsUnconnectedGraph([&](uint32_t currNode) -> bool + { return false; }); + EXPECT_EQ(isDAGFlag, false); + LOG_INFO(UDMF_TEST, "DfsUnconnectedGraph004 end."); +} + +/** +* @tc.name: DfsUnconnectedGraph005 +* @tc.desc: is connectedGraph: A -> B -> C -> D -> E -> F D -> E -> G -> H -> E +* @tc.type: FUNC +*/ +HWTEST_F(GraphTest, DfsUnconnectedGraph005, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "DfsUnconnectedGraph005 begin."); + uint32_t vextexNum = 8; + vector> edges = { + {TestNodes::POINT_A, TestNodes::POINT_B}, + {TestNodes::POINT_B, TestNodes::POINT_C}, + {TestNodes::POINT_C, TestNodes::POINT_D}, + {TestNodes::POINT_D, TestNodes::POINT_E}, + {TestNodes::POINT_D, TestNodes::POINT_E}, + {TestNodes::POINT_E, TestNodes::POINT_F}, + {TestNodes::POINT_E, TestNodes::POINT_G}, + {TestNodes::POINT_G, TestNodes::POINT_H}, + {TestNodes::POINT_H, TestNodes::POINT_E}, + }; + Graph graph(vextexNum); + for (uint32_t i = 0; i < edges.size(); i++) { + graph.AddEdge(edges[i][0], edges[i][1]); + } + bool isDAGFlag = graph.DfsUnconnectedGraph([&](uint32_t currNode) -> bool + { return false; }); + EXPECT_EQ(isDAGFlag, false); + LOG_INFO(UDMF_TEST, "DfsUnconnectedGraph005 end."); +} + +/** +* @tc.name: DfsUnconnectedGraph006 +* @tc.desc: is not connectedGraph: A -> B -> C -> D -> E -> F D -> E -> G -> H +* @tc.type: FUNC +*/ +HWTEST_F(GraphTest, DfsUnconnectedGraph006, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "DfsUnconnectedGraph006 begin."); + uint32_t vextexNum = 8; + vector> edges = { + {TestNodes::POINT_A, TestNodes::POINT_B}, + {TestNodes::POINT_B, TestNodes::POINT_C}, + {TestNodes::POINT_C, TestNodes::POINT_D}, + {TestNodes::POINT_D, TestNodes::POINT_E}, + {TestNodes::POINT_D, TestNodes::POINT_E}, + {TestNodes::POINT_E, TestNodes::POINT_F}, + {TestNodes::POINT_E, TestNodes::POINT_G}, + {TestNodes::POINT_G, TestNodes::POINT_H}, + }; + Graph graph(vextexNum); + for (uint32_t i = 0; i < edges.size(); i++) { + graph.AddEdge(edges[i][0], edges[i][1]); + } + bool isDAGFlag = graph.DfsUnconnectedGraph([&](uint32_t currNode) -> bool + { return false; }); + EXPECT_EQ(isDAGFlag, true); + LOG_INFO(UDMF_TEST, "DfsUnconnectedGraph006 end."); +} + +/** +* @tc.name: DfsUnconnectedGraph007 +* @tc.desc: is not connectedGraph: A -> B A -> C B -> D C -> D B -> C +* @tc.type: FUNC +*/ +HWTEST_F(GraphTest, DfsUnconnectedGraph007, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "DfsUnconnectedGraph007 begin."); + uint32_t vextexNum = 4; + vector> edges = { + {TestNodes::POINT_A, TestNodes::POINT_B}, + {TestNodes::POINT_A, TestNodes::POINT_C}, + {TestNodes::POINT_B, TestNodes::POINT_D}, + {TestNodes::POINT_C, TestNodes::POINT_D}, + {TestNodes::POINT_B, TestNodes::POINT_C}, + }; + Graph graph(vextexNum); + for (uint32_t i = 0; i < edges.size(); i++) { + graph.AddEdge(edges[i][0], edges[i][1]); + } + bool isDAGFlag = graph.DfsUnconnectedGraph([&](uint32_t currNode) -> bool + { return false; }); + EXPECT_EQ(isDAGFlag, true); + LOG_INFO(UDMF_TEST, "DfsUnconnectedGraph007 end."); +} + +/** +* @tc.name: DfsUnconnectedGraph008 +* @tc.desc: is not connectedGraph: A -> B -> C D -> E F -> G -> H +* @tc.type: FUNC +*/ +HWTEST_F(GraphTest, DfsUnconnectedGraph008, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "DfsUnconnectedGraph008 begin."); + uint32_t vextexNum = 8; + vector> edges = { + {TestNodes::POINT_A, TestNodes::POINT_B}, + {TestNodes::POINT_B, TestNodes::POINT_C}, + {TestNodes::POINT_D, TestNodes::POINT_E}, + {TestNodes::POINT_F, TestNodes::POINT_G}, + {TestNodes::POINT_G, TestNodes::POINT_H}, + }; + Graph graph(vextexNum); + for (uint32_t i = 0; i < edges.size(); i++) { + graph.AddEdge(edges[i][0], edges[i][1]); + } + bool isDAGFlag = graph.DfsUnconnectedGraph([&](uint32_t currNode) -> bool + { return false; }); + EXPECT_EQ(isDAGFlag, true); + LOG_INFO(UDMF_TEST, "DfsUnconnectedGraph008 end."); +} + +/** +* @tc.name: DfsHasData001 +* @tc.desc: is not connectedGraph: A -> B -> C -> D -> E -> F D -> E -> G -> H +* @tc.type: FUNC +*/ +HWTEST_F(GraphTest, DfsHasData001, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "DfsHasData001 begin."); + uint32_t vextexNum = 8; + vector> edges = { + {TestNodes::POINT_A, TestNodes::POINT_B}, + {TestNodes::POINT_B, TestNodes::POINT_C}, + {TestNodes::POINT_C, TestNodes::POINT_D}, + {TestNodes::POINT_D, TestNodes::POINT_E}, + {TestNodes::POINT_D, TestNodes::POINT_E}, + {TestNodes::POINT_E, TestNodes::POINT_F}, + {TestNodes::POINT_E, TestNodes::POINT_G}, + {TestNodes::POINT_G, TestNodes::POINT_H}, + }; + Graph graph(vextexNum); + for (uint32_t i = 0; i < edges.size(); i++) { + graph.AddEdge(edges[i][0], edges[i][1]); + } + + bool isFind = false; + graph.Dfs(TestNodes::POINT_A, [&](uint32_t currNode) -> bool { + if (currNode == TestNodes::POINT_H) { + isFind = true; + return true; + } + return false; + }); + EXPECT_EQ(isFind, true); + + isFind = false; + graph.Dfs(TestNodes::POINT_A, [&](uint32_t currNode) -> bool { + if (currNode == TestNodes::POINT_F) { + isFind = true; + return true; + } + return false; + }); + EXPECT_EQ(isFind, true); + + isFind = false; + graph.Dfs(TestNodes::POINT_E, [&](uint32_t currNode) -> bool { + if (currNode == TestNodes::POINT_D) { + isFind = true; + return true; + } + return false; + }); + EXPECT_EQ(isFind, false); + LOG_INFO(UDMF_TEST, "DfsHasData001 end."); +} + +/** +* @tc.name: DfsHasData002 +* @tc.desc: is not connectedGraph: A -> B -> C D -> E F -> G -> H +* @tc.type: FUNC +*/ +HWTEST_F(GraphTest, DfsHasData002, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "DfsHasData002 begin."); + uint32_t vextexNum = 8; + vector> edges = { + {TestNodes::POINT_A, TestNodes::POINT_B}, + {TestNodes::POINT_B, TestNodes::POINT_C}, + {TestNodes::POINT_D, TestNodes::POINT_E}, + {TestNodes::POINT_F, TestNodes::POINT_G}, + {TestNodes::POINT_G, TestNodes::POINT_H}, + }; + Graph graph(vextexNum); + for (uint32_t i = 0; i < edges.size(); i++) { + graph.AddEdge(edges[i][0], edges[i][1]); + } + + bool isFind = false; + graph.Dfs(TestNodes::POINT_F, [&](uint32_t currNode) -> bool { + if (currNode == TestNodes::POINT_H) { + isFind = true; + return true; + } + return false; + }); + EXPECT_EQ(isFind, true); + + isFind = false; + graph.Dfs(TestNodes::POINT_A, [&](uint32_t currNode) -> bool { + if (currNode == TestNodes::POINT_H) { + isFind = true; + return true; + } + return false; + }); + EXPECT_EQ(isFind, false); + LOG_INFO(UDMF_TEST, "DfsHasData002 end."); +} } // OHOS::Test \ No newline at end of file diff --git a/udmf/framework/innerkitsimpl/test/unittest/udmf_client_system_hap_test.cpp b/udmf/framework/innerkitsimpl/test/unittest/udmf_client_system_hap_test.cpp new file mode 100644 index 00000000..84532d17 --- /dev/null +++ b/udmf/framework/innerkitsimpl/test/unittest/udmf_client_system_hap_test.cpp @@ -0,0 +1,325 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define LOG_TAG "UdmfClientSystemHapTest" +#include + +#include +#include +#include + +#include "token_setproc.h" +#include "accesstoken_kit.h" +#include "directory_ex.h" +#include "nativetoken_kit.h" + +#include "logger.h" +#include "udmf_client.h" +#include "application_defined_record.h" +#include "audio.h" +#include "file.h" +#include "folder.h" +#include "html.h" +#include "image.h" +#include "link.h" +#include "plain_text.h" +#include "system_defined_appitem.h" +#include "system_defined_form.h" +#include "system_defined_pixelmap.h" +#include "system_defined_record.h" +#include "text.h" +#include "unified_data_helper.h" +#include "video.h" + +using namespace testing::ext; +using namespace OHOS::Security::AccessToken; +using namespace OHOS::UDMF; +using namespace OHOS; +namespace OHOS::Test { +static constexpr int USER_ID = 100; +static constexpr int INST_INDEX = 0; +class UdmfClientSystemHapTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp() override; + void TearDown() override; + + void SetNativeToken(const std::string &processName); + static void AllocHapToken1(); + static void AllocHapToken2(); + void SetHapToken1(); + void SetHapToken2(); + void AddPrivilege(QueryOption &option); +}; + +void UdmfClientSystemHapTest::SetUpTestCase() +{ + AllocHapToken1(); + AllocHapToken2(); +} + +void UdmfClientSystemHapTest::TearDownTestCase() +{ + auto tokenId = AccessTokenKit::GetHapTokenID(USER_ID, "ohos.test.demo1", INST_INDEX); + AccessTokenKit::DeleteToken(tokenId); + tokenId = AccessTokenKit::GetHapTokenID(USER_ID, "ohos.test.demo2", INST_INDEX); + AccessTokenKit::DeleteToken(tokenId); +} + +void UdmfClientSystemHapTest::SetUp() +{ + SetHapToken1(); +} + +void UdmfClientSystemHapTest::TearDown() +{ +} + +void UdmfClientSystemHapTest::SetNativeToken(const std::string &processName) +{ + auto tokenId = AccessTokenKit::GetNativeTokenId(processName); + SetSelfTokenID(tokenId); +} + +void UdmfClientSystemHapTest::AllocHapToken1() +{ + HapInfoParams info = { + .userID = USER_ID, + .bundleName = "ohos.test.demo1", + .instIndex = INST_INDEX, + .appIDDesc = "ohos.test.demo1", + .isSystemApp = true, + }; + + HapPolicyParams policy = { + .apl = APL_SYSTEM_BASIC, + .domain = "test.domain", + .permList = { + { + .permissionName = "ohos.permission.test", + .bundleName = "ohos.test.demo1", + .grantMode = 1, + .availableLevel = APL_SYSTEM_BASIC, + .label = "label", + .labelId = 1, + .description = "test1", + .descriptionId = 1 + } + }, + .permStateList = { + { + .permissionName = "ohos.permission.test", + .isGeneral = true, + .resDeviceID = { "local" }, + .grantStatus = { PermissionState::PERMISSION_GRANTED }, + .grantFlags = { 1 } + } + } + }; + auto tokenID = AccessTokenKit::AllocHapToken(info, policy); + SetSelfTokenID(tokenID.tokenIDEx); +} + +void UdmfClientSystemHapTest::AllocHapToken2() +{ + HapInfoParams info = { + .userID = USER_ID, + .bundleName = "ohos.test.demo2", + .instIndex = INST_INDEX, + .appIDDesc = "ohos.test.demo2", + .isSystemApp = true, + }; + + HapPolicyParams policy = { + .apl = APL_SYSTEM_BASIC, + .domain = "test.domain", + .permList = { + { + .permissionName = "ohos.permission.test", + .bundleName = "ohos.test.demo2", + .grantMode = 1, + .availableLevel = APL_SYSTEM_BASIC, + .label = "label", + .labelId = 1, + .description = "test2", + .descriptionId = 1 + } + }, + .permStateList = { + { + .permissionName = "ohos.permission.test", + .isGeneral = true, + .resDeviceID = { "local" }, + .grantStatus = { PermissionState::PERMISSION_GRANTED }, + .grantFlags = { 1 } + } + } + }; + auto tokenID = AccessTokenKit::AllocHapToken(info, policy); + SetSelfTokenID(tokenID.tokenIDEx); +} + +void UdmfClientSystemHapTest::SetHapToken1() +{ + auto tokenId = AccessTokenKit::GetHapTokenID(USER_ID, "ohos.test.demo1", INST_INDEX); + SetSelfTokenID(tokenId); +} + +void UdmfClientSystemHapTest::SetHapToken2() +{ + auto tokenId = AccessTokenKit::GetHapTokenID(USER_ID, "ohos.test.demo2", INST_INDEX); + SetSelfTokenID(tokenId); +} + +void UdmfClientSystemHapTest::AddPrivilege(QueryOption &option) +{ + Privilege privilege; + privilege.tokenId = AccessTokenKit::GetHapTokenID(USER_ID, "ohos.test.demo2", INST_INDEX); + privilege.readPermission = "readPermission"; + privilege.writePermission = "writePermission"; + SetNativeToken("msdp_sa"); + auto status = UdmfClient::GetInstance().AddPrivilege(option, privilege); + ASSERT_EQ(status, E_OK); +} + +/** +* @tc.name: SetAppShareOption001 +* @tc.desc: SetAppShareOption +* @tc.type: FUNC +*/ +HWTEST_F(UdmfClientSystemHapTest, SetAppShareOption001, TestSize.Level1) +{ + AllocHapToken1(); + auto status = UdmfClient::GetInstance().RemoveAppShareOption("drag"); + LOG_INFO(UDMF_TEST, "SetAppShareOption001 begin."); + status = UdmfClient::GetInstance().SetAppShareOption("drag", ShareOptions::IN_APP); + EXPECT_EQ(status, E_OK); + status = UdmfClient::GetInstance().RemoveAppShareOption("drag"); + EXPECT_EQ(status, E_OK); + LOG_INFO(UDMF_TEST, "SetAppShareOption001 end."); +} + +/** +* @tc.name: SetAppShareOption002 +* @tc.desc: SetAppShareOption +* @tc.type: FUNC +*/ +HWTEST_F(UdmfClientSystemHapTest, SetAppShareOption002, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "SetAppShareOption002 begin."); + AllocHapToken1(); + auto status = UdmfClient::GetInstance().RemoveAppShareOption("drag"); + status = UdmfClient::GetInstance().SetAppShareOption("drag", ShareOptions::IN_APP); + EXPECT_EQ(status, E_OK); + ShareOptions appShareOptions; + status = UdmfClient::GetInstance().GetAppShareOption("drag", appShareOptions); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(appShareOptions, ShareOptions::IN_APP); + status = UdmfClient::GetInstance().SetAppShareOption("drag", ShareOptions::IN_APP); + EXPECT_EQ(status, E_SETTINGS_EXISTED); + status = UdmfClient::GetInstance().RemoveAppShareOption("drag"); + EXPECT_EQ(status, E_OK); + LOG_INFO(UDMF_TEST, "SetAppShareOption002 end."); +} + +/** +* @tc.name: RemoveAppShareOption001 +* @tc.desc: RemoveAppShareOption +* @tc.type: FUNC +*/ +HWTEST_F(UdmfClientSystemHapTest, RemoveAppShareOption001, TestSize.Level1) +{ + AllocHapToken1(); + LOG_INFO(UDMF_TEST, "RemoveAppShareOption001 begin."); + auto status = UdmfClient::GetInstance().RemoveAppShareOption("drag"); + EXPECT_EQ(status, E_OK); + LOG_INFO(UDMF_TEST, "RemoveAppShareOption001 end."); +} + +/** +* @tc.name: DeleteData002 +* @tc.desc: Delete data with valid params +* @tc.type: FUNC +*/ +HWTEST_F(UdmfClientSystemHapTest, systemAppSetData001, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "systemAppSetData001 begin."); + AllocHapToken1(); + auto status = UdmfClient::GetInstance().RemoveAppShareOption("drag"); + status = UdmfClient::GetInstance().SetAppShareOption("drag", ShareOptions::IN_APP); + EXPECT_EQ(status, E_OK); + LOG_INFO(UDMF_TEST, "systemAppSetData001 SetAppShareOption success."); + + CustomOption customOption = { .intention = UD_INTENTION_DRAG }; + UnifiedData data; + PlainText plainText; + plainText.SetContent("systemApptestcontent1"); + std::shared_ptr record = std::make_shared

(plainText); + data.AddRecord(record); + std::string key; + status = UdmfClient::GetInstance().SetData(customOption, data, key); + ASSERT_EQ(status, E_OK); + + QueryOption queryOption = { .key = key }; + LOG_INFO(UDMF_TEST, "systemAppSetData001 SetData success, key:%{public}s.", key.c_str()); + + UnifiedData outputData; + status = UdmfClient::GetInstance().GetData(queryOption, outputData); + ASSERT_EQ(status, E_OK); + std::shared_ptr<UnifiedRecord> record2 = outputData.GetRecordAt(0); + ASSERT_NE(record2, nullptr); + auto type = record2->GetType(); + ASSERT_EQ(type, UDType::PLAIN_TEXT); + auto text2 = static_cast<Text *>(record2.get()); + ASSERT_NE(text2, nullptr); + auto plainText2 = static_cast<PlainText *>(record2.get()); + ASSERT_EQ(plainText2->GetContent(), "systemApptestcontent1"); + + LOG_INFO(UDMF_TEST, "systemAppSetData001 end."); +} + +/** +* @tc.name: systemAppSetData002 +* @tc.desc: systemAppSetData CROSS_APP +* @tc.type: FUNC +*/ +HWTEST_F(UdmfClientSystemHapTest, systemAppSetData002, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "systemAppSetData002 begin."); + AllocHapToken1(); + auto status = UdmfClient::GetInstance().RemoveAppShareOption("drag"); + status = UdmfClient::GetInstance().SetAppShareOption("drag", ShareOptions::IN_APP); + EXPECT_EQ(status, E_OK); + LOG_INFO(UDMF_TEST, "systemAppSetData002 SetAppShareOption success."); + CustomOption customOption = { .intention = UD_INTENTION_DRAG }; + UnifiedData data; + PlainText plainText; + plainText.SetContent("systemApptestcontent1"); + std::shared_ptr<UnifiedRecord> record = std::make_shared<PlainText>(plainText); + data.AddRecord(record); + std::string key; + status = UdmfClient::GetInstance().SetData(customOption, data, key); + ASSERT_EQ(status, E_OK); + + SetHapToken2(); + + QueryOption queryOption = { .key = key }; + UnifiedData outputData; + status = UdmfClient::GetInstance().GetData(queryOption, outputData); + ASSERT_EQ(status, E_OK); + + LOG_INFO(UDMF_TEST, "systemAppSetData002 end."); +} +} // OHOS::Test \ No newline at end of file diff --git a/udmf/framework/innerkitsimpl/test/unittest/udmf_client_test.cpp b/udmf/framework/innerkitsimpl/test/unittest/udmf_client_test.cpp index c3ff004c..fd7eb24f 100644 --- a/udmf/framework/innerkitsimpl/test/unittest/udmf_client_test.cpp +++ b/udmf/framework/innerkitsimpl/test/unittest/udmf_client_test.cpp @@ -16,6 +16,8 @@ #include <gtest/gtest.h> #include <unistd.h> +#include <thread> +#include <chrono> #include "token_setproc.h" #include "accesstoken_kit.h" @@ -45,6 +47,7 @@ using namespace OHOS::Security::AccessToken; using namespace OHOS::UDMF; using namespace OHOS; namespace OHOS::Test { +constexpr int SLEEP_TIME = 50; // 50 ms class UdmfClientTest : public testing::Test { public: static void SetUpTestCase(); @@ -208,6 +211,7 @@ void UdmfClientTest::CompareDetails(const UDDetails &details) void UdmfClientTest::GetEmptyData(QueryOption &option) { UnifiedData data; + std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME)); auto status = UdmfClient::GetInstance().GetData(option, data); EXPECT_EQ(status, E_NOT_FOUND); } @@ -1441,6 +1445,56 @@ HWTEST_F(UdmfClientTest, AddPrivilege004, TestSize.Level1) LOG_INFO(UDMF_TEST, "AddPrivilege004 end."); } +/** +* @tc.name: AddPrivilege005 +* @tc.desc: Add privilege with valid params +* @tc.type: FUNC +*/ +HWTEST_F(UdmfClientTest, AddPrivilege005, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "AddPrivilege005 begin."); + + CustomOption option1 = { .intention = Intention::UD_INTENTION_DRAG }; + UnifiedData data; + Text text; + UDDetails details; + details.insert({ "udmf_key", "udmf_value" }); + text.SetDetails(details); + std::shared_ptr<UnifiedRecord> record = std::make_shared<Text>(text); + data.AddRecord(record); + std::string key; + auto status = UdmfClient::GetInstance().SetData(option1, data, key); + ASSERT_EQ(status, E_OK); + + QueryOption option2 = { .key = key }; + Privilege privilege; + SetHapToken2(); + privilege.tokenId = AccessTokenKit::GetHapTokenID(100, "ohos.test.demo2", 0); + privilege.readPermission = "readAndKeep"; + privilege.writePermission = "writePermission"; + SetNativeToken("msdp_sa"); + status = UdmfClient::GetInstance().AddPrivilege(option2, privilege); + ASSERT_EQ(status, E_OK); + + SetHapToken2(); + UnifiedData data1; + status = UdmfClient::GetInstance().GetData(option2, data1); + ASSERT_EQ(status, E_OK); + + std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME)); + UnifiedData data2; + status = UdmfClient::GetInstance().GetData(option2, data2); + ASSERT_EQ(status, E_OK); + std::shared_ptr<UnifiedRecord> record2 = data2.GetRecordAt(0); + ASSERT_NE(record2, nullptr); + auto type = record2->GetType(); + ASSERT_EQ(type, UDType::TEXT); + auto text2 = static_cast<Text *>(record2.get()); + ASSERT_NE(text2, nullptr); + CompareDetails(text2->GetDetails()); // Can be read repeatedly. + LOG_INFO(UDMF_TEST, "AddPrivilege005 end."); +} + /** * @tc.name: GetSelfData001 * @tc.desc: Set File record with valid params and no add privilege and get data by self diff --git a/udmf/framework/innerkitsimpl/test/unittest/utd_client_test.cpp b/udmf/framework/innerkitsimpl/test/unittest/utd_client_test.cpp index f0c2b301..20e50fd5 100644 --- a/udmf/framework/innerkitsimpl/test/unittest/utd_client_test.cpp +++ b/udmf/framework/innerkitsimpl/test/unittest/utd_client_test.cpp @@ -24,7 +24,7 @@ #include "logger.h" #include "utd_client.h" #include "type_descriptor.h" - +#include "preset_type_descriptors.h" using namespace testing::ext; using namespace OHOS::Security::AccessToken; @@ -346,7 +346,7 @@ HWTEST_F(UtdClientTest, GetUniformDataTypeByMIMEType001, TestSize.Level1) HWTEST_F(UtdClientTest, GetUniformDataTypeByMIMEType002, TestSize.Level1) { LOG_INFO(UDMF_TEST, "GetUniformDataTypeByMIMEType002 begin."); - std::string mimeType = "application/mspowerpoint"; + std::string mimeType = "application/vnd.ms-powerpoint"; std::string blongsToType = "general.composite-object"; std::string currType; auto status = UtdClient::GetInstance().GetUniformDataTypeByMIMEType(mimeType, currType, blongsToType); @@ -1225,4 +1225,166 @@ HWTEST_F(UtdClientTest, FlexibleType024, TestSize.Level1) EXPECT_EQ(status, E_INVALID_PARAMETERS); LOG_INFO(UDMF_TEST, "FlexibleType024 end."); } + +/** +* @tc.name: IsUtd001 +* @tc.desc: IsUtd +* @tc.type: FUNC +*/ +HWTEST_F(UtdClientTest, IsUtd001, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "IsUtd001 begin."); + bool result = false; + auto status = UtdClient::GetInstance().IsUtd("general.mp3", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, true); + status = UtdClient::GetInstance().IsUtd("com.amazon.azw3", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, true); + status = UtdClient::GetInstance().IsUtd("general.cer-certificate", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, true); + status = UtdClient::GetInstance().IsUtd("general.system", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, true); + status = UtdClient::GetInstance().IsUtd("com.example.demo.mytype-azw3", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, true); + status = UtdClient::GetInstance().IsUtd("com.example.demo.mytype", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, true); + status = UtdClient::GetInstance().IsUtd("com.example.demo.mytype3", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, true); + status = UtdClient::GetInstance().IsUtd("com.example.demo2.mytype3", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, true); + status = UtdClient::GetInstance().IsUtd("system.haha", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, false); + status = UtdClient::GetInstance().IsUtd("hello.text", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, false); + std::vector<TypeDescriptorCfg> allUTD = PresetTypeDescriptors::GetInstance().GetPresetTypes(); + for (auto item : allUTD) { + status = UtdClient::GetInstance().IsUtd(item.typeId, result); + EXPECT_EQ(status, E_OK); + if (!result) { + LOG_ERROR(UDMF_TEST, "IsUtd001 item is %{public}s is check fail. ", item.typeId.c_str()); + } + EXPECT_EQ(result, true); + } + LOG_INFO(UDMF_TEST, "IsUtd001 end."); +} + +/** +* @tc.name: IsUtd002 +* @tc.desc: IsUtd +* @tc.type: FUNC +*/ +HWTEST_F(UtdClientTest, IsUtd002, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "IsUtd002 begin."); + bool result = false; + auto status = UtdClient::GetInstance().IsUtd("BROWSER", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, false); + status = UtdClient::GetInstance().IsUtd("IMAGE", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, false); + status = UtdClient::GetInstance().IsUtd("AUDIO", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, false); + status = UtdClient::GetInstance().IsUtd("VIDEO", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, false); + status = UtdClient::GetInstance().IsUtd("PDF", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, false); + status = UtdClient::GetInstance().IsUtd("WORD", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, false); + status = UtdClient::GetInstance().IsUtd("EXCEL", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, false); + status = UtdClient::GetInstance().IsUtd("PPT", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, false); + status = UtdClient::GetInstance().IsUtd("EMAIL", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, false); + status = UtdClient::GetInstance().IsUtd("txt", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, false); + status = UtdClient::GetInstance().IsUtd("abcdef", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, false); + LOG_INFO(UDMF_TEST, "IsUtd002 end."); +} + +/** +* @tc.name: IsUtd003 +* @tc.desc: IsUtd +* @tc.type: FUNC +*/ +HWTEST_F(UtdClientTest, IsUtd003, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "IsUtd003 begin."); + bool result = false; + auto status = UtdClient::GetInstance().IsUtd("*/*", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, false); + status = UtdClient::GetInstance().IsUtd("text/*", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, false); + status = UtdClient::GetInstance().IsUtd("image/*", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, false); + status = UtdClient::GetInstance().IsUtd("video/*", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, false); + status = UtdClient::GetInstance().IsUtd("audio/*", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, false); + status = UtdClient::GetInstance().IsUtd("audio/aiff", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, false); + LOG_INFO(UDMF_TEST, "IsUtd001 end."); +} + +/** +* @tc.name: IsUtd004 +* @tc.desc: IsUtd +* @tc.type: FUNC +*/ +HWTEST_F(UtdClientTest, IsUtd004, TestSize.Level1) +{ + LOG_INFO(UDMF_TEST, "IsUtd004 begin."); + bool result = false; + auto status = UtdClient::GetInstance().IsUtd(".TXT", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, false); + status = UtdClient::GetInstance().IsUtd(".MP3", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, false); + status = UtdClient::GetInstance().IsUtd(".3gp", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, false); + status = UtdClient::GetInstance().IsUtd(".txt", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, false); + status = UtdClient::GetInstance().IsUtd(".TXT", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, false); + status = UtdClient::GetInstance().IsUtd(".MP3", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, false); + status = UtdClient::GetInstance().IsUtd(".3gp", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, false); + status = UtdClient::GetInstance().IsUtd("abcdef", result); + EXPECT_EQ(status, E_OK); + EXPECT_EQ(result, false); + LOG_INFO(UDMF_TEST, "IsUtd004 end."); +} } // OHOS::Test \ No newline at end of file diff --git a/udmf/framework/jskitsimpl/common/napi_error_utils.cpp b/udmf/framework/jskitsimpl/common/napi_error_utils.cpp index 8a879b1f..bec7603e 100644 --- a/udmf/framework/jskitsimpl/common/napi_error_utils.cpp +++ b/udmf/framework/jskitsimpl/common/napi_error_utils.cpp @@ -24,6 +24,9 @@ using NapiErrorCode = OHOS::UDMF::NapiErrorCode; static const NapiErrorCode JS_ERROR_CODE_MSGS[] = { { Status::E_NO_PERMISSION, 201, "Permission denied!" }, { Status::E_INVALID_PARAMETERS, 401, "Parameter error." }, + { Status::E_SETTINGS_EXISTED, 20400001, "Settings already exist." }, + { Status::E_NO_SYSTEM_PERMISSION, 202, + "Permission denied, application which is not a system application uses system API." }, }; const std::optional<NapiErrorCode> GetErrorCode(int32_t errorCode) @@ -62,7 +65,6 @@ Status GenerateNapiError(Status error, int32_t &errCode, std::string &errMessage void ThrowNapiError(napi_env env, int32_t status, const std::string &errMessage, bool isParamsCheck) { - LOG_INFO(UDMF_KITS_NAPI, "ThrowNapiError message: %{public}s", errMessage.c_str()); if (status == Status::E_OK) { return; } @@ -88,6 +90,8 @@ void ThrowNapiError(napi_env env, int32_t status, const std::string &errMessage, } else { jsCode = std::to_string(napiError.jsCode); } + LOG_INFO(UDMF_KITS_NAPI, "ThrowNapiError, status:%{public}d, jsCode: %{public}s, message: %{public}s", + status, jsCode.c_str(), errMessage.c_str()); napi_throw_error(env, jsCode.c_str(), message.c_str()); } } // namespace UDMF diff --git a/udmf/framework/jskitsimpl/data/type_descriptor_napi.cpp b/udmf/framework/jskitsimpl/data/type_descriptor_napi.cpp index 5b6657d6..044b0e25 100644 --- a/udmf/framework/jskitsimpl/data/type_descriptor_napi.cpp +++ b/udmf/framework/jskitsimpl/data/type_descriptor_napi.cpp @@ -191,8 +191,7 @@ napi_value TypeDescriptorNapi::GetBelongingToTypes(napi_env env, napi_callback_i auto descriptorNapi = GetDescriptorNapi(env, info, ctxt); ASSERT_ERR(ctxt->env, (descriptorNapi != nullptr && descriptorNapi->value_ != nullptr), Status::E_ERROR, "invalid object!"); - std::set<std::string> upTypes = descriptorNapi->value_->GetBelongingToTypes(); - std::vector<std::string> belongingTypes(upTypes.begin(), upTypes.end()); + std::vector<std::string> belongingTypes = descriptorNapi->value_->GetBelongingToTypes(); ctxt->status = NapiDataUtils::SetValue(env, belongingTypes, ctxt->output); return ctxt->output; } diff --git a/udmf/framework/jskitsimpl/data/unified_data_channel_napi.cpp b/udmf/framework/jskitsimpl/data/unified_data_channel_napi.cpp index b3d32de2..3d91f11c 100644 --- a/udmf/framework/jskitsimpl/data/unified_data_channel_napi.cpp +++ b/udmf/framework/jskitsimpl/data/unified_data_channel_napi.cpp @@ -24,6 +24,7 @@ namespace OHOS { namespace UDMF { +using namespace OHOS::AppExecFwk; napi_value UnifiedDataChannelNapi::UnifiedDataChannelInit(napi_env env, napi_value exports) { LOG_DEBUG(UDMF_KITS_NAPI, "UnifiedDataChannelNapi"); @@ -35,6 +36,8 @@ napi_value UnifiedDataChannelNapi::UnifiedDataChannelInit(napi_env env, napi_val DECLARE_NAPI_FUNCTION("queryData", QueryData), DECLARE_NAPI_FUNCTION("deleteData", DeleteData), DECLARE_NAPI_GETTER("ShareOptions", CreateShareOptions), + DECLARE_NAPI_FUNCTION("setAppShareOptions", SetAppShareOptions), + DECLARE_NAPI_FUNCTION("removeAppShareOptions", RemoveAppShareOptions), }; NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); @@ -47,6 +50,8 @@ napi_value UnifiedDataChannelNapi::CreateIntention(napi_env env) napi_create_object(env, &intention); SetNamedProperty(env, intention, JS_UD_INTENTION_NAME_MAP.at(UD_INTENTION_DATA_HUB), UD_INTENTION_MAP.at(UD_INTENTION_DATA_HUB)); + SetNamedProperty(env, intention, JS_UD_INTENTION_NAME_MAP.at(UD_INTENTION_DRAG), + UD_SYSTEM_INTENTION_MAP.at(UD_INTENTION_DRAG)); napi_object_freeze(env, intention); return intention; } @@ -288,5 +293,64 @@ napi_value UnifiedDataChannelNapi::CreateShareOptions(napi_env env, napi_callbac NAPI_CALL(env, napi_set_named_property(env, jsShareOptions, "CROSS_APP", jsCrossDevice)); return jsShareOptions; } + +napi_value UnifiedDataChannelNapi::SetAppShareOptions(napi_env env, napi_callback_info info) +{ + LOG_DEBUG(UDMF_KITS_NAPI, "SetAppShareOption is called!"); + std::string intention; + int32_t shareOptionValue = ShareOptions::CROSS_APP; + auto ctxt = std::make_shared<ContextBase>(); + auto input = [env, ctxt, &intention, &shareOptionValue](size_t argc, napi_value* argv) { + LOG_DEBUG(UDMF_KITS_NAPI, "set appShareOption, argc = %{public}zu !", argc); + // required 2 arguments : intention, shareOption + ASSERT_BUSINESS_ERR(ctxt, argc > 1, + Status::E_INVALID_PARAMETERS, "Parameter error: Mandatory parameters are left unspecified"); + ctxt->status = NapiDataUtils::GetValue(env, argv[0], intention); + ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, E_INVALID_PARAMETERS, + "Parameter error:The parameter intention must be within the scope of the Intention enumeration."); + ctxt->status = NapiDataUtils::GetValue(env, argv[1], shareOptionValue); + ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, E_INVALID_PARAMETERS, + "Parameter error:The parameter shareOption must be within the scope of the ShareOptions enumeration."); + }; + ctxt->GetCbInfoSync(env, info, input); + ASSERT_NULL(!ctxt->isThrowError, "SetAppShareOption Exit"); + auto status = E_OK; + ASSERT_ERR(ctxt->env, intention == "Drag", + E_INVALID_PARAMETERS, "Parameter error: The intention parameter is invalid!"); + ASSERT_ERR(ctxt->env, (shareOptionValue >= IN_APP && shareOptionValue < SHARE_OPTIONS_BUTT), + E_INVALID_PARAMETERS, "Parameter error: The shareOptions parameter is invalid!"); + std::transform(intention.begin(), intention.end(), intention.begin(), ::tolower); // js : Drag --> drag + status = UdmfClient::GetInstance().SetAppShareOption(intention, static_cast<ShareOptions>(shareOptionValue)); + ASSERT_BUSINESS_ERR_VOID(ctxt, !(status == E_SETTINGS_EXISTED), E_SETTINGS_EXISTED, "Settings already exist!"); + ASSERT_BUSINESS_ERR_VOID(ctxt, !(status == E_NO_PERMISSION), E_NO_SYSTEM_PERMISSION, "Permission denied!"); + ASSERT_ERR(ctxt->env, status == E_OK, status, "invalid arguments!"); + return nullptr; +} + +napi_value UnifiedDataChannelNapi::RemoveAppShareOptions(napi_env env, napi_callback_info info) +{ + LOG_DEBUG(UDMF_KITS_NAPI, "RemoveAppShareOption is called!"); + std::string intention; + auto ctxt = std::make_shared<ContextBase>(); + auto input = [env, ctxt, &intention](size_t argc, napi_value* argv) { + LOG_DEBUG(UDMF_KITS_NAPI, "RemoveAppShareOption, argc = %{public}zu !", argc); + // required 2 arguments : typeId + ASSERT_BUSINESS_ERR(ctxt, argc > 0, + Status::E_INVALID_PARAMETERS, "Parameter error: Mandatory parameters are left unspecified"); + ctxt->status = NapiDataUtils::GetValue(env, argv[0], intention); + ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, E_INVALID_PARAMETERS, + "Parameter error:The parameter intention must be within the scope of the Intention enumeration."); + }; + ctxt->GetCbInfoSync(env, info, input); + ASSERT_NULL(!ctxt->isThrowError, "RemoveAppShareOption Exit"); + ASSERT_ERR(ctxt->env, intention == "Drag", + E_INVALID_PARAMETERS, "Parameter error: The intention parameter is invalid!"); + std::transform(intention.begin(), intention.end(), intention.begin(), ::tolower); // js : Drag --> drag + auto status = E_OK; + status = UdmfClient::GetInstance().RemoveAppShareOption(intention); + ASSERT_BUSINESS_ERR_VOID(ctxt, !(status == E_NO_PERMISSION), E_NO_SYSTEM_PERMISSION, "Permission denied!"); + ASSERT_ERR(ctxt->env, status == E_OK, status, "invalid arguments!"); + return nullptr; +} } // namespace UDMF } // namespace OHOS \ No newline at end of file diff --git a/udmf/framework/jskitsimpl/data/unified_data_properties_napi.cpp b/udmf/framework/jskitsimpl/data/unified_data_properties_napi.cpp index a8ed2cad..81296217 100644 --- a/udmf/framework/jskitsimpl/data/unified_data_properties_napi.cpp +++ b/udmf/framework/jskitsimpl/data/unified_data_properties_napi.cpp @@ -18,6 +18,7 @@ #include "napi_data_utils.h" #include "napi_error_utils.h" #include "unified_data.h" +#include "unified_meta.h" namespace OHOS { namespace UDMF { diff --git a/udmf/framework/jskitsimpl/data/unified_record_napi.cpp b/udmf/framework/jskitsimpl/data/unified_record_napi.cpp index 03cbfca8..4d1aa123 100644 --- a/udmf/framework/jskitsimpl/data/unified_record_napi.cpp +++ b/udmf/framework/jskitsimpl/data/unified_record_napi.cpp @@ -82,12 +82,9 @@ std::shared_ptr<UnifiedRecord> UnifiedRecordNapi::GenerateNativeRecord(napi_env ValueType value; GetNativeValue(env, type, valueNapi, value); - auto it = std::find_if(UD_TYPE_MAP.begin(), UD_TYPE_MAP.end(), [&](const auto& pair) { - return pair.second == type; - }); UDType utdType = APPLICATION_DEFINED_RECORD; - if (it != UD_TYPE_MAP.end()) { - utdType = static_cast<UDType>(it->first); + if (UtdUtils::IsValidUtdId(type)) { + utdType = static_cast<UDType>(UtdUtils::GetUtdEnumFromUtdId(type)); } std::map<UDType, std::function<std::shared_ptr<UnifiedRecord>(UDType, ValueType)>> constructors = { @@ -195,7 +192,8 @@ napi_value UnifiedRecordNapi::GetType(napi_env env, napi_callback_info info) auto ctxt = std::make_shared<ContextBase>(); auto uRecord = GetUnifiedRecord(env, info, ctxt); ASSERT_ERR(ctxt->env, (uRecord != nullptr && uRecord->value_ != nullptr), Status::E_ERROR, "invalid object!"); - ctxt->status = NapiDataUtils::SetValue(env, UD_TYPE_MAP.at(uRecord->value_->GetType()), ctxt->output); + ctxt->status = NapiDataUtils::SetValue(env, UtdUtils::GetUtdIdFromUtdEnum(uRecord->value_->GetType()), + ctxt->output); ASSERT_ERR(ctxt->env, ctxt->status == napi_ok, Status::E_ERROR, "set type failed!"); return ctxt->output; } diff --git a/udmf/framework/jskitsimpl/data/uniform_type_descriptor_napi.cpp b/udmf/framework/jskitsimpl/data/uniform_type_descriptor_napi.cpp index 67845234..ea934002 100644 --- a/udmf/framework/jskitsimpl/data/uniform_type_descriptor_napi.cpp +++ b/udmf/framework/jskitsimpl/data/uniform_type_descriptor_napi.cpp @@ -24,6 +24,7 @@ namespace OHOS { namespace UDMF { + napi_value UniformTypeDescriptorNapi::UniformTypeDescriptorInit(napi_env env, napi_value exports) { LOG_DEBUG(UDMF_KITS_NAPI, "UniformTypeDescriptorNapi"); @@ -43,8 +44,9 @@ napi_value UniformTypeDescriptorNapi::CreateUniformDataType(napi_env env) { napi_value uniformDataType = nullptr; napi_create_object(env, &uniformDataType); - for (auto &[utdTypeKey, utdTypeValue] : JS_UD_TYPE_NAME_MAP) { - SetNamedProperty(env, uniformDataType, utdTypeValue, UD_TYPE_MAP.at(utdTypeKey)); + auto allUtdTypes = UtdUtils::GetUtdTypes(); + for (auto utdType : allUtdTypes) { + SetNamedProperty(env, uniformDataType, utdType.UtdEnumName, utdType.UtdId); } napi_object_freeze(env, uniformDataType); return uniformDataType; diff --git a/udmf/interfaces/innerkits/BUILD.gn b/udmf/interfaces/innerkits/BUILD.gn index ce3767c3..182d20c3 100644 --- a/udmf/interfaces/innerkits/BUILD.gn +++ b/udmf/interfaces/innerkits/BUILD.gn @@ -36,6 +36,8 @@ config("udmf_client_config") { ohos_shared_library("udmf_client") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false @@ -87,8 +89,10 @@ ohos_shared_library("udmf_client") { "access_token:libaccesstoken_sdk", "app_file_service:fileuri_native", "bundle_framework:appexecfwk_core", + "cJSON:cjson", "c_utils:utils", "hilog:libhilog", + "hisysevent:libhisysevent", "hitrace:hitrace_meter", "hitrace:libhitracechain", "image_framework:image", @@ -98,16 +102,73 @@ ohos_shared_library("udmf_client") { "samgr:samgr_proxy", ] - public_configs += [ "//third_party/cJSON:cJSON_config" ] - deps = [ "//third_party/cJSON:cjson" ] + public_external_deps = [ "cJSON:cjson" ] innerapi_tags = [ "platformsdk" ] subsystem_name = "distributeddatamgr" part_name = "udmf" - + use_exceptions = true + cflags_cc = [ "-fvisibility=hidden" ] if (build_selinux) { cflags = [ "-DWITH_SELINUX" ] external_deps += [ "selinux_adapter:librestorecon" ] } } + +config("utd_client_config") { + include_dirs = [ + "${udmf_interfaces_path}/innerkits/client", + "${udmf_interfaces_path}/innerkits/common", + "${udmf_interfaces_path}/innerkits/data", + "${udmf_framework_path}/common", + "${udmf_framework_path}/innerkitsimpl/data", + "${udmf_framework_path}/innerkitsimpl/service", + ] +} + +ohos_shared_library("utd_client") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + include_dirs = [ + "${udmf_interfaces_path}/innerkits/client", + "${udmf_interfaces_path}/innerkits/common", + "${udmf_interfaces_path}/innerkits/data", + "${udmf_framework_path}/common", + "${udmf_framework_path}/innerkitsimpl/data", + ] + + sources = [ + "${udmf_framework_path}/common/base32_utils.cpp", + "${udmf_framework_path}/common/custom_utd_json_parser.cpp", + "${udmf_framework_path}/common/custom_utd_store.cpp", + "${udmf_framework_path}/common/graph.cpp", + "${udmf_framework_path}/common/udmf_utils.cpp", + "${udmf_framework_path}/common/utd_cfgs_checker.cpp", + "${udmf_framework_path}/common/utd_graph.cpp", + "${udmf_framework_path}/innerkitsimpl/client/utd_client.cpp", + "${udmf_framework_path}/innerkitsimpl/data/flexible_type.cpp", + "${udmf_framework_path}/innerkitsimpl/data/preset_type_descriptors.cpp", + "${udmf_framework_path}/innerkitsimpl/data/type_descriptor.cpp", + ] + + public_configs = [ ":utd_client_config" ] + + external_deps = [ + "cJSON:cjson", + "c_utils:utils", + "hilog:libhilog", + ] + + public_external_deps = [ "cJSON:cjson" ] + use_exceptions = true + innerapi_tags = [ "platformsdk" ] + subsystem_name = "distributeddatamgr" + + part_name = "udmf" + cflags_cc = [ "-fvisibility=hidden" ] +} diff --git a/udmf/interfaces/innerkits/client/udmf_client.h b/udmf/interfaces/innerkits/client/udmf_client.h index 39191120..a865169c 100644 --- a/udmf/interfaces/innerkits/client/udmf_client.h +++ b/udmf/interfaces/innerkits/client/udmf_client.h @@ -18,15 +18,19 @@ #include <string> #include <vector> +#include <map> +#include <shared_mutex> + +#include "concurrent_map.h" #include "unified_data.h" #include "error_code.h" #include "unified_meta.h" #include "unified_types.h" - +#include "visibility.h" namespace OHOS { namespace UDMF { -class UdmfClient { +class API_EXPORT UdmfClient { public: static UdmfClient &GetInstance(); @@ -39,6 +43,18 @@ public: Status AddPrivilege(const QueryOption &query, Privilege &privilege); Status Sync(const QueryOption &query, const std::vector<std::string> &devices); Status IsRemoteData(const QueryOption &query, bool &result); + Status SetAppShareOption(const std::string &intention, enum ShareOptions shareOption); + Status RemoveAppShareOption(const std::string &intention); + Status GetAppShareOption(const std::string &intention, enum ShareOptions &shareOption); + +private: + UdmfClient() = default; + ~UdmfClient() = default; + UdmfClient(const UdmfClient &obj) = delete; + UdmfClient &operator=(const UdmfClient &obj) = delete; + std::string GetSelfBundleName(); + + ConcurrentMap<std::string, UnifiedData> dataCache_; }; } // namespace UDMF } // namespace OHOS diff --git a/udmf/interfaces/innerkits/client/utd_client.h b/udmf/interfaces/innerkits/client/utd_client.h index d0d8641b..2b979025 100644 --- a/udmf/interfaces/innerkits/client/utd_client.h +++ b/udmf/interfaces/innerkits/client/utd_client.h @@ -25,11 +25,11 @@ #include "flexible_type.h" #include "type_descriptor.h" #include "error_code.h" - +#include "visibility.h" namespace OHOS { namespace UDMF { class TypeDescriptor; -class UtdClient { +class API_EXPORT UtdClient { public: static UtdClient &GetInstance(); Status GetTypeDescriptor(const std::string &typeId, std::shared_ptr<TypeDescriptor> &descriptor); @@ -37,6 +37,7 @@ public: std::string belongsTo = DEFAULT_TYPE_ID); Status GetUniformDataTypeByMIMEType(const std::string &mimeType, std::string &typeId, std::string belongsTo = DEFAULT_TYPE_ID); + Status IsUtd(std::string typeId, bool &result); private: UtdClient(); diff --git a/udmf/interfaces/innerkits/common/error_code.h b/udmf/interfaces/innerkits/common/error_code.h index 75c6eff6..22929142 100644 --- a/udmf/interfaces/innerkits/common/error_code.h +++ b/udmf/interfaces/innerkits/common/error_code.h @@ -41,6 +41,8 @@ enum Status : int32_t { E_DB_ERROR, E_FS_ERROR, E_NOT_FOUND, + E_SETTINGS_EXISTED, + E_NO_SYSTEM_PERMISSION, E_BUTT, }; @@ -54,7 +56,9 @@ static const std::unordered_map<int32_t, std::string> ERROR_MAP { { Status::E_INVALID_PARAMETERS, "E_INVALID_PARAMETERS" }, { Status::E_DB_ERROR, "E_DB_ERROR" }, { Status::E_FS_ERROR, "E_FS_ERROR" }, - { Status::E_NOT_FOUND, "E_NOT_FOUND" } + { Status::E_NOT_FOUND, "E_NOT_FOUND" }, + { Status::E_SETTINGS_EXISTED, "E_SETTINGS_EXISTED" }, + { Status::E_NO_SYSTEM_PERMISSION, "E_NO_SYSTEM_PERMISSION" } }; } // namespace UDMF } // namespace OHOS diff --git a/udmf/interfaces/innerkits/common/unified_key.h b/udmf/interfaces/innerkits/common/unified_key.h index c39ed841..3cc724aa 100644 --- a/udmf/interfaces/innerkits/common/unified_key.h +++ b/udmf/interfaces/innerkits/common/unified_key.h @@ -18,11 +18,11 @@ #include <bitset> #include <string> - +#include "visibility.h" namespace OHOS { namespace UDMF { constexpr int MAX_BIT_SIZE = 128; -struct UnifiedKey { +struct API_EXPORT UnifiedKey { UnifiedKey() = default; explicit UnifiedKey(std::string key); UnifiedKey(std::string intention, std::string bundle, std::string groupId); diff --git a/udmf/interfaces/innerkits/common/unified_meta.h b/udmf/interfaces/innerkits/common/unified_meta.h index baed5c48..07825b2f 100644 --- a/udmf/interfaces/innerkits/common/unified_meta.h +++ b/udmf/interfaces/innerkits/common/unified_meta.h @@ -24,7 +24,7 @@ #include <unordered_map> #include <variant> #include <vector> - +#include "visibility.h" #include "string_ex.h" namespace OHOS { @@ -167,289 +167,269 @@ enum UDType : int32_t { OPENHARMONY_HINOTE, OPENHARMONY_STYLED_STRING, OPENHARMONY_WANT, + OFD, + OPG, + TEX, + CSS, + VOB, + DIF_VIDEO, + DV_VIDEO, + FLC_ANIMATION, + MNG, + MPEGURL_VIDEO, + TS, + AMR, + AMR_WB, + GMS, + IMY, + KAR, + MPEGURL_AUDIO, + MPEG_4_AUDIO, + MIDI_AUDIO, + MP2, + MPEG_AUDIO, + MXMF, + OTA, + PLS, + RTTTL, + PSID, + ULAW_AUDIO, + XMF, + GIF, + DJVU_IMAGE, + JNG_IMAGE, + PCX_IMAGE, + PBM_IMAGE, + PGM_IMAGE, + PNM_IMAGE, + PPM_IMAGE, + RGB_IMAGE, + SVG_IMAGE, + WBMP_IMAGE, + XPIXMP_IMAGE, + XWINDOWDUMP_IMAGE, + HEIF, + HEIC, + VIRTUAL_CD, + BOO_SOURCE, + D_SOURCE, + HTML_COMPONENT, + PASCAL_SOURCE, + HASKELL_SCRIPT, + LITERATE_HASKELL_SCRIPT, + TCL_SCRIPT, + ASC_TEXT, + PORTABLE_OBJECT, + RICH_TEXT, + DELIMITED_VALUES_TEXT, + COMMA_SEPARATED_VALUES_TEXT, + DIFF, + SETEXT, + GCD, + TAB_SEPARATED_VALUES_TEXT, + P7R, + PEM, + CHESS_PGN, + LHA_ARCHIVE, + LZH_ARCHIVE, + LZX_ARCHIVE, + TAZ_ARCHIVE, + SHAR_ARCHIVE, + CPIO_ARCHIVE, + WEB_ARCHIVE, + USTAR, + MATHML, + XHTML, + RSS, + RDF, + IGES, + CAD, + OCTET_STREAM, + ISO, + MESH_MODEL, + CERTIFICATE, + C_OBJECT, + DVI, + CER_CERTIFICATE, + CRT_CERTIFICATE, + CRL_CERTIFICATE, + PRN, + OPENDOCUMENT_CHART, + OPENDOCUMENT_TEXT_MASTER, + OPENDOCUMENT_TEXT_WEB, + OPENDOCUMENT_DATABASE, + OPENDOCUMENT_IMAGE, + OPENDOCUMENT_FORMULA_TEMPLATE, + OPENDOCUMENT_CHART_TEMPLATE, + OPENDOCUMENT_PRESENTATION_TEMPLATE, + OPENDOCUMENT_IMAGE_TEMPLATE, + OPENDOCUMENT_GRAPHICS_TEMPLATE, + OPENDOCUMENT_SPREADSHEET_TEMPLATE, + OPENDOCUMENT_TEXT_TEMPLATE, + WORD_DOT, + POWERPOINT_PPS, + POWERPOINT_POT, + EXCEL_XLT, + VISIO_VSD, + DRAWINGML_VISIO, + DRAWINGML_TEMPLATE, + DRAWINGML_VISIO_MACROENABLED, + DRAWINGML_TEMPLATE_MACROENABLED, + WORDPROCESSINGML_TEMPLATE, + PRESENTATIONML_TEMPLATE, + PRESENTATIONML_SLIDESHOW, + SPREADSHEETML_TEMPLATE, + WORDPROCESSINGML_DOCUMENT_MACROENABLED, + WORDPROCESSINGML_TEMPLATE_MACROENABLED, + SPREADSHEETML_TEMPLATE_MACROENABLED, + SPREADSHEETML_ADDIN_MACROENABLED, + SPREADSHEETML_BINARY_MACROENABLED, + SPREADSHEETML_SHEET_MACROENABLED, + PRESENTATIONALML_ADDIN_MACROENABLED, + PRESENTATIONALML_PRESENTATION_MACROENABLED, + PRESENTATIONALML_SLIDESHOW_MACROENABLED, + PRESENTATIONALML_TEMPLATE_MACROENABLED, + OPENOFFICE, + OPENOFFICE_CALC, + OPENOFFICE_DRAW, + OPENOFFICE_WRITER_GLOBAL, + OPENOFFICE_IMPRESS, + OPENOFFICE_MATH, + OPENOFFICE_WRITER, + OPENOFFICE_CALC_TEMPLATE, + OPENOFFICE_DRAW_TEMPLATE, + OPENOFFICE_IMPRESS_TEMPLATE, + OPENOFFICE_WRITER_TEMPLATE, + STAROFFICE, + STAROFFICE_DRAW, + STAROFFICE_CALC, + STAROFFICE_IMPRESS, + STAROFFICE_WRITER, + STAROFFICE_CHART, + STAROFFICE_MAIL, + STAROFFICE_WRITER_GLOBAL, + STAROFFICE_MATH, + STAROFFICE_TEMPLATE, + TUG_BIB, + TUG_CLS, + TUG_STY, + TUG_TEX, + LATEX, + ADVANCED_SYSTEMS_FORMAT, + ADVANCED_STREAM_REDIRECTOR, + MATROSKA_VIDEO, + MATROSKA_AUDIO, + SGI_MOVIE, + APPLE_M4V, + WEBM, + QUICKTIME_MOVIE, + CORELDRAW_CDR, + CORELDRAW_CDT, + CORELDRAW_CPT, + CORELDRAW_PAT, + MICROSOFT_CUR, + SUN_RASTER, + GOOGLE_WEBP, + KOAN_AUDIO, + QT_MOC, + GHOSTSCRIPT_FONT, + X_PCF_FONT, + WINDOWS_MEDIA_WMD, + WINDOWS_MEDIA_WMZ, + WINDOWS_INSTALLER, + PUBLISHER_PUB, + WINDOWS_MEDIA_PLAYLIST, + ACCESS_MDB, + STEREOLITHOGRAPHY, + APPLE_MEDIA_PLAYLIST, + ABISOURCE_WORD, + ADOBE_FRAMEMAKER, + WOLFRAM_CDF, + CINDERELLA_CDY, + ADOBE_DCR, + ADOBE_DIR, + ADOBE_DXR, + GNUMERIC_SPREADSHEET, + HDFGROUP_HDF, + BINHEX_ARCHIVE, + MICROSOFT_HTA, + INTERNET_INS, + INTERNET_ISP, + TROFF, + ADOBE_MIF, + FREEMIND, + YAMAHA_SMAF, + MATHEMATICA_NOTEBOOK, + XIPH_OGG, + PROXY_AUTOCONFIG, + PKCS_12, + PGP_SIGNATURE, + QUICKTIME_LINK, + RAR_ARCHIVE, + SEVEN_ZIP_ARCHIVE, + RED_BEAN_SGF, + SIT_ARCHIVE, + FUTURESPLASH, + FLASH, + TEXINFO, + TORRENT, + DOOM, + APPLE_WEBARCHIVE, + ANDROID_WEBARCHIVE, + GIMP_XCF, + EDRWMAX, + EDRWMIND, + CNKI_CAJ, + DBASE_DBF, + AUTODESK_DWG, + AUTODESK_DXF, + AUTODESK_DWS, + AUTODESK_DWT, + AUTODESK_DWF, + AUTODESK_DWFX, + AUTODESK_SHP, + AUTODESK_SHX, + AUTODESK_SLIDE_LIB, + AUTODESK_LINE, + AUTODESK_PLOTTER, + HP_GRAPHICS_LANG, + MICROSOFT_METAFILE, + ACIS_SAT, + AVIF_IMAGE, + MICROSOFT_DDS, + IFF_ILBM, + CR2_RAW_IMAGE, + CR3_RAW_IMAGE, + CRW_RAW_IMAGE, + DNG_RAW_IMAGE, + ARW_RAW_IMAGE, + NEF_RAW_IMAGE, + MINDMANAGER_MMAP, + MICROSOFT_EMAIL, + MICROSOFT_MESSAGE, + MICROSOFT_PST, + KINSOFT_OFFICE, + KINSOFT_WRITER_WPS, + KINSOFT_WRITER_WPT, + KINSOFT_PRESENTATION_DPS, + KINSOFT_PRESENTATION_TEMPLATE, + KINSOFT_SPREADSHEETS_ET, + KINSOFT_SPREADSHEETS_TEMPLATE, UD_BUTT }; -static const std::unordered_map<int32_t, std::string> UD_TYPE_MAP { - { ENTITY, "general.entity" }, - { OBJECT, "general.object" }, - { COMPOSITE_OBJECT, "general.composite-object" }, - { TEXT, "general.text" }, - { PLAIN_TEXT, "general.plain-text" }, - { HTML, "general.html" }, - { HYPERLINK, "general.hyperlink" }, - { XML, "general.xml" }, - { SMIL, "com.real.smil" }, - { SOURCE_CODE, "general.source-code" }, - { SCRIPT, "general.script" }, - { SHELL_SCRIPT, "general.shell-script" }, - { CSH_SCRIPT, "general.csh-script" }, - { PERL_SCRIPT, "general.perl-script" }, - { PHP_SCRIPT, "general.php-script" }, - { PYTHON_SCRIPT, "general.python-script" }, - { RUBY_SCRIPT, "general.ruby-script" }, - { TYPE_SCRIPT, "general.type-script" }, - { JAVA_SCRIPT, "general.java-script" }, - { C_HEADER, "general.c-header" }, - { C_SOURCE, "general.c-source" }, - { C_PLUS_PLUS_HEADER, "general.c-plus-plus-header" }, - { C_PLUS_PLUS_SOURCE, "general.c-plus-plus-source" }, - { JAVA_SOURCE, "general.java-source" }, - { MARKDOWN, "general.markdown" }, - { EBOOK, "general.ebook" }, - { EPUB, "general.epub" }, - { AZW, "com.amazon.azw" }, - { AZW3, "com.amazon.azw3" }, - { KFX, "com.amazon.kfx" }, - { MOBI, "com.amazon.mobi" }, - { MEDIA, "general.media" }, - { IMAGE, "general.image" }, - { JPEG, "general.jpeg" }, - { PNG, "general.png" }, - { RAW_IMAGE, "general.raw-image" }, - { TIFF, "general.tiff" }, - { BMP, "com.microsoft.bmp" }, - { ICO, "com.microsoft.ico" }, - { PHOTOSHOP_IMAGE, "com.adobe.photoshop-image" }, - { AI_IMAGE, "com.adobe.illustrator.ai-image" }, - { FAX, "general.fax" }, - { JFX_FAX, "com.j2.jfx-fax" }, - { EFX_FAX, "com.js.efx-fax" }, - { XBITMAP_IMAGE, "general.xbitmap-image" }, - { TGA_IMAGE, "com.truevision.tga-image" }, - { SGI_IMAGE, "com.sgi.sgi-image" }, - { OPENEXR_IMAGE, "com.ilm.openexr-image" }, - { FLASHPIX_IMAGE, "com.kodak.flashpix.image" }, - { WORD_DOC, "com.microsoft.word.doc" }, - { EXCEL, "com.microsoft.excel.xls" }, - { PPT, "com.microsoft.powerpoint.ppt" }, - { PDF, "com.adobe.pdf" }, - { POSTSCRIPT, "com.adobe.postscript" }, - { ENCAPSULATED_POSTSCRIPT, "com.adobe.encapsulated-postscript" }, - { VIDEO, "general.video" }, - { AVI, "general.avi" }, - { MPEG, "general.mpeg" }, - { MPEG4, "general.mpeg-4" }, - { VIDEO_3GPP, "general.3gpp" }, - { VIDEO_3GPP2, "general.3gpp2" }, - { WINDOWS_MEDIA_WM, "com.microsoft.windows-media-wm" }, - { WINDOWS_MEDIA_WMV, "com.microsoft.windows-media-wmv" }, - { WINDOWS_MEDIA_WMP, "com.microsoft.windows-media-wmp" }, - { WINDOWS_MEDIA_WVX, "com.microsoft.windows-media-wvx" }, - { WINDOWS_MEDIA_WMX, "com.microsoft.windows-media-wmx" }, - { REALMEDIA, "com.real.realmedia" }, - { AUDIO, "general.audio" }, - { AAC, "general.aac" }, - { AIFF, "general.aiff" }, - { ALAC, "general.alac" }, - { FLAC, "general.flac" }, - { MP3, "general.mp3" }, - { OGG, "general.ogg" }, - { PCM, "general.pcm" }, - { WINDOWS_MEDIA_WMA, "com.microsoft.windows-media-wma" }, - { WAVEFORM_AUDIO, "com.microsoft.waveform-audio" }, - { WINDOWS_MEDIA_WAX, "com.microsoft.windows-media-wax" }, - { AU_AUDIO, "general.au-audio" }, - { AIFC_AUDIO, "general.aifc-audio" }, - { SD2_AUDIO, "com.digidesign.sd2-audio" }, - { REALAUDIO, "com.real.realaudio" }, - { FILE, "general.file" }, - { DIRECTORY, "general.directory" }, - { FOLDER, "general.folder" }, - { SYMLINK, "general.symlink" }, - { ARCHIVE, "general.archive" }, - { BZ2_ARCHIVE, "general.bz2-archive" }, - { DISK_IMAGE, "general.disk-image" }, - { TAR_ARCHIVE, "general.tar-archive" }, - { ZIP_ARCHIVE, "general.zip-archive" }, - { JAVA_ARCHIVE, "com.sun.java-archive" }, - { GNU_TAR_ARCHIVE, "org.gnu.gnu-tar-archive" }, - { GNU_ZIP_ARCHIVE, "org.gnu.gnu-zip-archive" }, - { GNU_ZIP_TAR_ARCHIVE, "org.gnu.gnu-zip-tar-archive" }, - { OPENXML, "org.openxmlformats.openxml" }, - { WORDPROCESSINGML_DOCUMENT, "org.openxmlformats.wordprocessingml.document" }, - { SPREADSHEETML_SHEET, "org.openxmlformats.spreadsheetml.sheet" }, - { PRESENTATIONML_PRESENTATION, "org.openxmlformats.presentationml.presentation" }, - { OPENDOCUMENT, "org.oasis.opendocument" }, - { OPENDOCUMENT_TEXT, "org.oasis.opendocument.text" }, - { OPENDOCUMENT_SPREADSHEET, "org.oasis.opendocument.spreadsheet" }, - { OPENDOCUMENT_PRESENTATION, "org.oasis.opendocument.presentation" }, - { OPENDOCUMENT_GRAPHICS, "org.oasis.opendocument.graphics" }, - { OPENDOCUMENT_FORMULA, "org.oasis.opendocument.formula" }, - { STUFFIT_ARCHIVE, "com.allume.stuffit-archive" }, - { CALENDAR, "general.calendar" }, - { VCS, "general.vcs" }, - { ICS, "general.ics" }, - { CONTACT, "general.contact" }, - { DATABASE, "general.database" }, - { MESSAGE, "general.message" }, - { EXECUTABLE, "general.executable" }, - { PORTABLE_EXECUTABLE, "com.microsoft.portable-executable" }, - { SUN_JAVA_CLASS, "com.sun.java-class" }, - { VCARD, "general.vcard" }, - { NAVIGATION, "general.navigation" }, - { LOCATION, "general.location" }, - { FONT, "general.font" }, - { TRUETYPE_FONT, "general.truetype-font" }, - { TRUETYPE_COLLECTION_FONT, "general.truetype-collection-font" }, - { OPENTYPE_FONT, "general.opentype-font" }, - { POSTSCRIPT_FONT, "com.adobe.postscript-font" }, - { POSTSCRIPT_PFB_FONT, "com.adobe.postscript-pfb-font" }, - { POSTSCRIPT_PFA_FONT, "com.adobe.postscript-pfa-font" }, - { SYSTEM_DEFINED_RECORD, "SystemDefinedType" }, - { SYSTEM_DEFINED_FORM, "openharmony.form" }, - { SYSTEM_DEFINED_APP_ITEM, "openharmony.app-item" }, - { SYSTEM_DEFINED_PIXEL_MAP, "openharmony.pixel-map" }, - { OPENHARMONY_ATOMIC_SERVICE, "openharmony.atomic-service" }, - { APPLICATION_DEFINED_RECORD, "ApplicationDefinedType" }, - { OPENHARMONY_PACKAGE, "openharmony.package" }, - { OPENHARMONY_HAP, "openharmony.hap" }, - { OPENHARMONY_HDOC, "openharmony.hdoc" }, - { OPENHARMONY_HINOTE, "openharmony.hinote" }, - { OPENHARMONY_STYLED_STRING, "openharmony.styled-string" }, - { OPENHARMONY_WANT, "openharmony.want" }, - { UD_BUTT, "INVALID"} +struct UtdType { + int32_t UtdEnum; + const char *UtdEnumName; + const char *UtdId; }; -static const std::unordered_map<int32_t, std::string> JS_UD_TYPE_NAME_MAP { - { ENTITY, "ENTITY" }, - { OBJECT, "OBJECT" }, - { COMPOSITE_OBJECT, "COMPOSITE_OBJECT" }, - { TEXT, "TEXT" }, - { PLAIN_TEXT, "PLAIN_TEXT" }, - { HTML, "HTML" }, - { HYPERLINK, "HYPERLINK" }, - { XML, "XML" }, - { SMIL, "SMIL" }, - { SOURCE_CODE, "SOURCE_CODE" }, - { SCRIPT, "SCRIPT" }, - { SHELL_SCRIPT, "SHELL_SCRIPT" }, - { CSH_SCRIPT, "CSH_SCRIPT" }, - { PERL_SCRIPT, "PERL_SCRIPT" }, - { PHP_SCRIPT, "PHP_SCRIPT" }, - { PYTHON_SCRIPT, "PYTHON_SCRIPT" }, - { RUBY_SCRIPT, "RUBY_SCRIPT" }, - { TYPE_SCRIPT, "TYPE_SCRIPT" }, - { JAVA_SCRIPT, "JAVA_SCRIPT" }, - { C_HEADER, "C_HEADER" }, - { C_SOURCE, "C_SOURCE" }, - { C_PLUS_PLUS_HEADER, "C_PLUS_PLUS_HEADER" }, - { C_PLUS_PLUS_SOURCE, "C_PLUS_PLUS_SOURCE" }, - { JAVA_SOURCE, "JAVA_SOURCE" }, - { MARKDOWN, "MARKDOWN" }, - { EBOOK, "EBOOK" }, - { EPUB, "EPUB" }, - { AZW, "AZW" }, - { AZW3, "AZW3" }, - { KFX, "KFX" }, - { MOBI, "MOBI" }, - { MEDIA, "MEDIA" }, - { IMAGE, "IMAGE" }, - { JPEG, "JPEG" }, - { PNG, "PNG" }, - { RAW_IMAGE, "RAW_IMAGE" }, - { TIFF, "TIFF" }, - { BMP, "BMP" }, - { ICO, "ICO" }, - { PHOTOSHOP_IMAGE, "PHOTOSHOP_IMAGE" }, - { AI_IMAGE, "AI_IMAGE" }, - { FAX, "FAX" }, - { JFX_FAX, "JFX_FAX" }, - { EFX_FAX, "EFX_FAX" }, - { XBITMAP_IMAGE, "XBITMAP_IMAGE" }, - { TGA_IMAGE, "TGA_IMAGE" }, - { SGI_IMAGE, "SGI_IMAGE" }, - { OPENEXR_IMAGE, "OPENEXR_IMAGE" }, - { FLASHPIX_IMAGE, "FLASHPIX_IMAGE" }, - { WORD_DOC, "WORD_DOC" }, - { EXCEL, "EXCEL" }, - { PPT, "PPT" }, - { PDF, "PDF" }, - { POSTSCRIPT, "POSTSCRIPT" }, - { ENCAPSULATED_POSTSCRIPT, "ENCAPSULATED_POSTSCRIPT" }, - { VIDEO, "VIDEO" }, - { AVI, "AVI" }, - { MPEG, "MPEG" }, - { MPEG4, "MPEG4" }, - { VIDEO_3GPP, "VIDEO_3GPP" }, - { VIDEO_3GPP2, "VIDEO_3GPP2" }, - { WINDOWS_MEDIA_WM, "WINDOWS_MEDIA_WM" }, - { WINDOWS_MEDIA_WMV, "WINDOWS_MEDIA_WMV" }, - { WINDOWS_MEDIA_WMP, "WINDOWS_MEDIA_WMP" }, - { WINDOWS_MEDIA_WVX, "WINDOWS_MEDIA_WVX" }, - { WINDOWS_MEDIA_WMX, "WINDOWS_MEDIA_WMX" }, - { REALMEDIA, "REALMEDIA" }, - { AUDIO, "AUDIO" }, - { AAC, "AAC" }, - { AIFF, "AIFF" }, - { ALAC, "ALAC" }, - { FLAC, "FLAC" }, - { MP3, "MP3" }, - { OGG, "OGG" }, - { PCM, "PCM" }, - { WINDOWS_MEDIA_WMA, "WINDOWS_MEDIA_WMA" }, - { WAVEFORM_AUDIO, "WAVEFORM_AUDIO" }, - { WINDOWS_MEDIA_WAX, "WINDOWS_MEDIA_WAX" }, - { AU_AUDIO, "AU_AUDIO" }, - { AIFC_AUDIO, "AIFC_AUDIO" }, - { SD2_AUDIO, "SD2_AUDIO" }, - { REALAUDIO, "REALAUDIO" }, - { FILE, "FILE" }, - { DIRECTORY, "DIRECTORY" }, - { FOLDER, "FOLDER" }, - { SYMLINK, "SYMLINK" }, - { ARCHIVE, "ARCHIVE" }, - { BZ2_ARCHIVE, "BZ2_ARCHIVE" }, - { DISK_IMAGE, "DISK_IMAGE" }, - { TAR_ARCHIVE, "TAR_ARCHIVE" }, - { ZIP_ARCHIVE, "ZIP_ARCHIVE" }, - { JAVA_ARCHIVE, "JAVA_ARCHIVE" }, - { GNU_TAR_ARCHIVE, "GNU_TAR_ARCHIVE" }, - { GNU_ZIP_ARCHIVE, "GNU_ZIP_ARCHIVE" }, - { GNU_ZIP_TAR_ARCHIVE, "GNU_ZIP_TAR_ARCHIVE" }, - { OPENXML, "OPENXML" }, - { WORDPROCESSINGML_DOCUMENT, "WORDPROCESSINGML_DOCUMENT" }, - { SPREADSHEETML_SHEET, "SPREADSHEETML_SHEET" }, - { PRESENTATIONML_PRESENTATION, "PRESENTATIONML_PRESENTATION" }, - { OPENDOCUMENT, "OPENDOCUMENT" }, - { OPENDOCUMENT_TEXT, "OPENDOCUMENT_TEXT" }, - { OPENDOCUMENT_SPREADSHEET, "OPENDOCUMENT_SPREADSHEET" }, - { OPENDOCUMENT_PRESENTATION, "OPENDOCUMENT_PRESENTATION" }, - { OPENDOCUMENT_GRAPHICS, "OPENDOCUMENT_GRAPHICS" }, - { OPENDOCUMENT_FORMULA, "OPENDOCUMENT_FORMULA" }, - { STUFFIT_ARCHIVE, "STUFFIT_ARCHIVE" }, - { CALENDAR, "CALENDAR" }, - { VCS, "VCS" }, - { ICS, "ICS" }, - { CONTACT, "CONTACT" }, - { DATABASE, "DATABASE" }, - { MESSAGE, "MESSAGE" }, - { EXECUTABLE, "EXECUTABLE" }, - { PORTABLE_EXECUTABLE, "PORTABLE_EXECUTABLE" }, - { SUN_JAVA_CLASS, "SUN_JAVA_CLASS" }, - { VCARD, "VCARD" }, - { NAVIGATION, "NAVIGATION" }, - { LOCATION, "LOCATION" }, - { FONT, "FONT" }, - { TRUETYPE_FONT, "TRUETYPE_FONT" }, - { TRUETYPE_COLLECTION_FONT, "TRUETYPE_COLLECTION_FONT" }, - { OPENTYPE_FONT, "OPENTYPE_FONT" }, - { POSTSCRIPT_FONT, "POSTSCRIPT_FONT" }, - { POSTSCRIPT_PFB_FONT, "POSTSCRIPT_PFB_FONT" }, - { POSTSCRIPT_PFA_FONT, "POSTSCRIPT_PFA_FONT" }, - { SYSTEM_DEFINED_RECORD, "SYSTEM_DEFINED_RECORD" }, - { SYSTEM_DEFINED_FORM, "OPENHARMONY_FORM" }, - { SYSTEM_DEFINED_APP_ITEM, "OPENHARMONY_APP_ITEM" }, - { SYSTEM_DEFINED_PIXEL_MAP, "OPENHARMONY_PIXEL_MAP" }, - { OPENHARMONY_ATOMIC_SERVICE, "OPENHARMONY_ATOMIC_SERVICE" }, - { APPLICATION_DEFINED_RECORD, "APPLICATION_DEFINED_RECORD" }, - { OPENHARMONY_PACKAGE, "OPENHARMONY_PACKAGE" }, - { OPENHARMONY_HAP, "OPENHARMONY_HAP" }, - { OPENHARMONY_HDOC, "OPENHARMONY_HDOC" }, - { OPENHARMONY_HINOTE, "OPENHARMONY_HINOTE" }, - { OPENHARMONY_STYLED_STRING, "OPENHARMONY_STYLED_STRING" }, - { OPENHARMONY_WANT, "OPENHARMONY_WANT" } -}; +namespace UtdUtils { + bool API_EXPORT IsValidUtdId(const std::string &utdId); + int32_t API_EXPORT GetUtdEnumFromUtdId(const std::string &utdId); + std::string API_EXPORT GetUtdIdFromUtdEnum(int32_t utdType); + std::vector<UtdType> API_EXPORT GetUtdTypes(); +} // namespace UtdUtils /* * UnifiedData variant definitions. @@ -471,11 +451,33 @@ static const std::unordered_map<int32_t, std::string> UD_INTENTION_MAP { { UD_INTENTION_DATA_HUB, "DataHub" }, }; +static const std::unordered_map<int32_t, std::string> UD_SYSTEM_INTENTION_MAP { + { UD_INTENTION_DRAG, "Drag" }, +}; + static const std::unordered_map<int32_t, std::string> JS_UD_INTENTION_NAME_MAP { { UD_INTENTION_DATA_HUB, "DATA_HUB" }, + { UD_INTENTION_DRAG, "DRAG" }, }; -class UnifiedDataUtils { +enum ShareOptions : int32_t { + IN_APP, + CROSS_APP, + SHARE_OPTIONS_BUTT, +}; + +struct AppShareOption { + int32_t enumNum; + const char *enumStr; +}; + +namespace ShareOptionsUtil { + bool API_EXPORT IsValid(int32_t shareOption); + int32_t API_EXPORT GetEnumNum(const std::string &shareOption); + std::string API_EXPORT GetEnumStr(int32_t shareOption); +} // namespace ShareOptionsUtil + +class API_EXPORT UnifiedDataUtils { public: static bool IsValidType(int32_t value); static bool IsValidIntention(int32_t value); diff --git a/udmf/interfaces/innerkits/common/unified_types.h b/udmf/interfaces/innerkits/common/unified_types.h index 63a63020..397872e6 100644 --- a/udmf/interfaces/innerkits/common/unified_types.h +++ b/udmf/interfaces/innerkits/common/unified_types.h @@ -61,6 +61,7 @@ struct Runtime { // device ID of the data source std::string deviceId; std::uint32_t recordTotalNum {}; + uint32_t tokenId; }; /* diff --git a/udmf/interfaces/innerkits/data/application_defined_record.h b/udmf/interfaces/innerkits/data/application_defined_record.h index 85100cb5..cb32d456 100644 --- a/udmf/interfaces/innerkits/data/application_defined_record.h +++ b/udmf/interfaces/innerkits/data/application_defined_record.h @@ -17,10 +17,10 @@ #define UDMF_APPLICATION_DEFINED_RECORD_H #include "unified_record.h" - +#include "visibility.h" namespace OHOS { namespace UDMF { -class ApplicationDefinedRecord : public UnifiedRecord { +class API_EXPORT ApplicationDefinedRecord : public UnifiedRecord { public: ApplicationDefinedRecord(); explicit ApplicationDefinedRecord(std::string type); diff --git a/udmf/interfaces/innerkits/data/audio.h b/udmf/interfaces/innerkits/data/audio.h index 99710e2c..c6eb27b2 100644 --- a/udmf/interfaces/innerkits/data/audio.h +++ b/udmf/interfaces/innerkits/data/audio.h @@ -17,10 +17,10 @@ #define UDMF_AUDIO_H #include "file.h" - +#include "visibility.h" namespace OHOS { namespace UDMF { -class Audio : public File { +class API_EXPORT Audio : public File { public: Audio(); explicit Audio(const std::string &uri); diff --git a/udmf/interfaces/innerkits/data/file.h b/udmf/interfaces/innerkits/data/file.h index 01717523..57ae3b39 100644 --- a/udmf/interfaces/innerkits/data/file.h +++ b/udmf/interfaces/innerkits/data/file.h @@ -17,10 +17,10 @@ #define UDMF_FILE_H #include "unified_record.h" - +#include "visibility.h" namespace OHOS { namespace UDMF { -class File : public UnifiedRecord { +class API_EXPORT File : public UnifiedRecord { public: File(); explicit File(const std::string &uri); diff --git a/udmf/interfaces/innerkits/data/flexible_type.h b/udmf/interfaces/innerkits/data/flexible_type.h index 962ed88e..bebbd09f 100644 --- a/udmf/interfaces/innerkits/data/flexible_type.h +++ b/udmf/interfaces/innerkits/data/flexible_type.h @@ -19,6 +19,7 @@ #include <vector> #include "error_code.h" #include "utd_common.h" +#include "visibility.h" namespace OHOS { namespace UDMF { constexpr const char* FLEXIBLE_TYPE_FLAG = "flex.z"; @@ -28,7 +29,7 @@ enum FlexibleTypeAttr : int32_t { FILE_EXTENTSION, INVALID_BUT }; -class FlexibleType { +class API_EXPORT FlexibleType { public: static std::string EscapeStr(const std::string &chs); static bool ParseFlexibleUtd(const std::string &typeId, TypeDescriptorCfg &flexibleTypeDescriptorCfg); diff --git a/udmf/interfaces/innerkits/data/folder.h b/udmf/interfaces/innerkits/data/folder.h index 4a3e9161..ab927e8a 100644 --- a/udmf/interfaces/innerkits/data/folder.h +++ b/udmf/interfaces/innerkits/data/folder.h @@ -17,10 +17,10 @@ #define UDMF_FOLDER_H #include "file.h" - +#include "visibility.h" namespace OHOS { namespace UDMF { -class Folder : public File { +class API_EXPORT Folder : public File { public: Folder(); explicit Folder(const std::string &uri); diff --git a/udmf/interfaces/innerkits/data/html.h b/udmf/interfaces/innerkits/data/html.h index 07c7fa7c..5eada149 100644 --- a/udmf/interfaces/innerkits/data/html.h +++ b/udmf/interfaces/innerkits/data/html.h @@ -17,10 +17,11 @@ #define UDMF_HTML_H #include "text.h" +#include "visibility.h" namespace OHOS { namespace UDMF { -class Html : public Text { +class API_EXPORT Html : public Text { public: Html(); explicit Html(const std::string &htmlContent, const std::string &plainContent); diff --git a/udmf/interfaces/innerkits/data/image.h b/udmf/interfaces/innerkits/data/image.h index 75853af5..1b8431e7 100644 --- a/udmf/interfaces/innerkits/data/image.h +++ b/udmf/interfaces/innerkits/data/image.h @@ -17,10 +17,11 @@ #define UDMF_IMAGE_H #include "file.h" +#include "visibility.h" namespace OHOS { namespace UDMF { -class Image : public File { +class API_EXPORT Image : public File { public: Image(); explicit Image(const std::string &uri); diff --git a/udmf/interfaces/innerkits/data/link.h b/udmf/interfaces/innerkits/data/link.h index 768c3577..5b600a78 100644 --- a/udmf/interfaces/innerkits/data/link.h +++ b/udmf/interfaces/innerkits/data/link.h @@ -17,10 +17,11 @@ #define UDMF_LINK_H #include "text.h" +#include "visibility.h" namespace OHOS { namespace UDMF { -class Link : public Text { +class API_EXPORT Link : public Text { public: Link(); explicit Link(const std::string &url); diff --git a/udmf/interfaces/innerkits/data/plain_text.h b/udmf/interfaces/innerkits/data/plain_text.h index a6859323..274c295e 100644 --- a/udmf/interfaces/innerkits/data/plain_text.h +++ b/udmf/interfaces/innerkits/data/plain_text.h @@ -17,10 +17,10 @@ #define UDMF_PLAIN_TEXT_H #include "text.h" - +#include "visibility.h" namespace OHOS { namespace UDMF { -class PlainText : public Text { +class API_EXPORT PlainText : public Text { public: PlainText(); explicit PlainText(const std::string &content, const std::string &abstract); diff --git a/udmf/interfaces/innerkits/data/system_defined_appitem.h b/udmf/interfaces/innerkits/data/system_defined_appitem.h index 4d62463f..3e1f66c0 100644 --- a/udmf/interfaces/innerkits/data/system_defined_appitem.h +++ b/udmf/interfaces/innerkits/data/system_defined_appitem.h @@ -17,10 +17,11 @@ #define UDMF_SYSTEM_DEFINED_APPITEM_H #include "system_defined_record.h" +#include "visibility.h" namespace OHOS { namespace UDMF { -class SystemDefinedAppItem : public SystemDefinedRecord { +class API_EXPORT SystemDefinedAppItem : public SystemDefinedRecord { public: SystemDefinedAppItem(); SystemDefinedAppItem(UDType type, ValueType value); diff --git a/udmf/interfaces/innerkits/data/system_defined_form.h b/udmf/interfaces/innerkits/data/system_defined_form.h index ae82350c..9f634c76 100644 --- a/udmf/interfaces/innerkits/data/system_defined_form.h +++ b/udmf/interfaces/innerkits/data/system_defined_form.h @@ -17,10 +17,10 @@ #define UDMF_SYSTEM_DEFINED_FORM_H #include "system_defined_record.h" - +#include "visibility.h" namespace OHOS { namespace UDMF { -class SystemDefinedForm : public SystemDefinedRecord { +class API_EXPORT SystemDefinedForm : public SystemDefinedRecord { public: SystemDefinedForm(); SystemDefinedForm(UDType type, ValueType value); diff --git a/udmf/interfaces/innerkits/data/system_defined_pixelmap.h b/udmf/interfaces/innerkits/data/system_defined_pixelmap.h index 546377fa..8120c943 100644 --- a/udmf/interfaces/innerkits/data/system_defined_pixelmap.h +++ b/udmf/interfaces/innerkits/data/system_defined_pixelmap.h @@ -17,10 +17,10 @@ #define UDMF_SYSTEM_DEFINED_PIXELMAP_H #include "system_defined_record.h" - +#include "visibility.h" namespace OHOS { namespace UDMF { -class SystemDefinedPixelMap : public SystemDefinedRecord { +class API_EXPORT SystemDefinedPixelMap : public SystemDefinedRecord { public: SystemDefinedPixelMap(); explicit SystemDefinedPixelMap(std::vector<uint8_t> &data); diff --git a/udmf/interfaces/innerkits/data/system_defined_record.h b/udmf/interfaces/innerkits/data/system_defined_record.h index c7ad8ddb..bc0af326 100644 --- a/udmf/interfaces/innerkits/data/system_defined_record.h +++ b/udmf/interfaces/innerkits/data/system_defined_record.h @@ -17,10 +17,10 @@ #define UDMF_SYSTEM_DEFINED_RECORD_H #include "unified_record.h" - +#include "visibility.h" namespace OHOS { namespace UDMF { -class SystemDefinedRecord : public UnifiedRecord { +class API_EXPORT SystemDefinedRecord : public UnifiedRecord { public: explicit SystemDefinedRecord(); SystemDefinedRecord(UDType type, ValueType value); diff --git a/udmf/interfaces/innerkits/data/text.h b/udmf/interfaces/innerkits/data/text.h index 2a8fd093..b7bd9446 100644 --- a/udmf/interfaces/innerkits/data/text.h +++ b/udmf/interfaces/innerkits/data/text.h @@ -17,11 +17,11 @@ #define UDMF_TEXT_H #include "unified_record.h" - +#include "visibility.h" namespace OHOS { namespace UDMF { constexpr int MAX_TEXT_LEN = 20 * 1024 * 1024; -class Text : public UnifiedRecord { +class API_EXPORT Text : public UnifiedRecord { public: Text(); explicit Text(UDDetails &variantMap); diff --git a/udmf/interfaces/innerkits/data/type_descriptor.h b/udmf/interfaces/innerkits/data/type_descriptor.h index 44ac32ae..b9332ad7 100644 --- a/udmf/interfaces/innerkits/data/type_descriptor.h +++ b/udmf/interfaces/innerkits/data/type_descriptor.h @@ -23,11 +23,12 @@ #include <map> #include "error_code.h" #include "utd_common.h" +#include "visibility.h" namespace OHOS { namespace UDMF { -class TypeDescriptor { +class API_EXPORT TypeDescriptor { public: - TypeDescriptor(const std::string &typeId, const std::set<std::string> &belongingToTypes, + TypeDescriptor(const std::string &typeId, const std::vector<std::string> &belongingToTypes, const std::vector<std::string> &filenameExtensions, const std::vector<std::string> &mimeTypes, const std::string &description, const std::string &referenceURL, const std::string &iconFile); TypeDescriptor(const TypeDescriptorCfg& typeDescriptorCfg); @@ -38,7 +39,7 @@ public: bool Equals(std::shared_ptr<TypeDescriptor> descriptor); const std::string& GetTypeId() const; - std::set<std::string> GetBelongingToTypes(); + std::vector<std::string> GetBelongingToTypes(); std::string GetIconFile(); std::string GetDescription(); std::string GetReferenceURL(); @@ -49,7 +50,7 @@ private: bool CmpFlexibleTypeLevel(const std::string higherLevelTypeId, bool isFlexibleType); std::string typeId_; - std::set<std::string> belongingToTypes_; + std::vector<std::string> belongingToTypes_; std::vector<std::string> filenameExtensions_; std::vector<std::string> mimeTypes_; std::string description_; diff --git a/udmf/interfaces/innerkits/data/unified_data.h b/udmf/interfaces/innerkits/data/unified_data.h index 9c71adc5..ad8cf2bd 100644 --- a/udmf/interfaces/innerkits/data/unified_data.h +++ b/udmf/interfaces/innerkits/data/unified_data.h @@ -18,10 +18,10 @@ #include "unified_data_properties.h" #include "unified_record.h" - +#include "visibility.h" namespace OHOS { namespace UDMF { -class UnifiedData { +class API_EXPORT UnifiedData { public: UnifiedData(); explicit UnifiedData(std::shared_ptr<UnifiedDataProperties> properties); diff --git a/udmf/interfaces/innerkits/data/unified_data_helper.h b/udmf/interfaces/innerkits/data/unified_data_helper.h index 1ec30266..e057df4d 100644 --- a/udmf/interfaces/innerkits/data/unified_data_helper.h +++ b/udmf/interfaces/innerkits/data/unified_data_helper.h @@ -18,23 +18,23 @@ #include <sys/stat.h> #include "unified_data.h" - +#include "visibility.h" namespace OHOS { namespace UDMF { -class UnifiedDataHelper { +class API_EXPORT UnifiedDataHelper { public: static void SetRootPath(const std::string &rootPath); static bool ExceedKVSizeLimit(UnifiedData &data); static bool IsTempUData(UnifiedData &data); static bool Pack(UnifiedData &data); static bool Unpack(UnifiedData &data); + static void GetSummary(const UnifiedData &data, Summary &summary); private: static void CreateDirIfNotExist(const std::string& dirPath, const mode_t& mode); static bool SaveUDataToFile(const std::string &dataFile, UnifiedData &data); static bool LoadUDataFromFile(const std::string &dataFile, UnifiedData &data); static std::string GetRootPath(); - static void GetSummary(const UnifiedData &data, Summary &summary); private: static std::string rootPath_; diff --git a/udmf/interfaces/innerkits/data/unified_data_properties.h b/udmf/interfaces/innerkits/data/unified_data_properties.h index c46f34df..2cfad4fb 100644 --- a/udmf/interfaces/innerkits/data/unified_data_properties.h +++ b/udmf/interfaces/innerkits/data/unified_data_properties.h @@ -16,11 +16,11 @@ #define UDMF_UNIFIED_DATA_PROPERTIES_H #include "want_params.h" - +#include "unified_meta.h" +#include "visibility.h" namespace OHOS { namespace UDMF { -enum ShareOptions { IN_APP, CROSS_APP }; -class UnifiedDataProperties { +class API_EXPORT UnifiedDataProperties { public: std::string tag; AAFwk::WantParams extras; diff --git a/udmf/interfaces/innerkits/data/unified_record.h b/udmf/interfaces/innerkits/data/unified_record.h index 2ae059e5..706a77cc 100644 --- a/udmf/interfaces/innerkits/data/unified_record.h +++ b/udmf/interfaces/innerkits/data/unified_record.h @@ -20,7 +20,7 @@ #include <string> #include <variant> #include <vector> - +#include "visibility.h" #include "pixel_map.h" #include "unified_types.h" #include "want.h" @@ -29,7 +29,7 @@ namespace OHOS { namespace UDMF { using ValueType = std::variant<int32_t, int64_t, double, bool, std::string, std::vector<uint8_t>, std::shared_ptr<OHOS::AAFwk::Want>, std::shared_ptr<OHOS::Media::PixelMap>>; -class UnifiedRecord { +class API_EXPORT UnifiedRecord { public: UnifiedRecord(); explicit UnifiedRecord(UDType type); diff --git a/udmf/interfaces/innerkits/data/video.h b/udmf/interfaces/innerkits/data/video.h index 95e4007d..a6d623a5 100644 --- a/udmf/interfaces/innerkits/data/video.h +++ b/udmf/interfaces/innerkits/data/video.h @@ -17,10 +17,10 @@ #define UDMF_VIDEO_H #include "file.h" - +#include "visibility.h" namespace OHOS { namespace UDMF { -class Video : public File { +class API_EXPORT Video : public File { public: Video(); explicit Video(const std::string &uri); diff --git a/udmf/interfaces/jskits/BUILD.gn b/udmf/interfaces/jskits/BUILD.gn index 2a9dd62a..c4029457 100644 --- a/udmf/interfaces/jskits/BUILD.gn +++ b/udmf/interfaces/jskits/BUILD.gn @@ -39,6 +39,8 @@ config("udmf_napi_config") { ohos_shared_library("unifieddatachannel_napi") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false @@ -79,6 +81,7 @@ ohos_shared_library("unifieddatachannel_napi") { external_deps = [ "ability_base:want", "ability_runtime:abilitykit_native", + "ability_runtime:napi_common", "c_utils:utils", "hilog:libhilog", "ipc:ipc_core", @@ -87,7 +90,7 @@ ohos_shared_library("unifieddatachannel_napi") { ] public_external_deps = [ "image_framework:image" ] - + cflags = [ "-fvisibility=hidden" ] relative_install_dir = "module/data" subsystem_name = "distributeddatamgr" part_name = "udmf" @@ -96,6 +99,8 @@ ohos_shared_library("unifieddatachannel_napi") { ohos_shared_library("uniformtypedescriptor_napi") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false @@ -124,7 +129,7 @@ ohos_shared_library("uniformtypedescriptor_napi") { ] public_external_deps = [ "image_framework:image" ] - + cflags = [ "-fvisibility=hidden" ] relative_install_dir = "module/data" subsystem_name = "distributeddatamgr" part_name = "udmf" @@ -133,6 +138,8 @@ ohos_shared_library("uniformtypedescriptor_napi") { ohos_shared_library("udmf_data_napi") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false @@ -173,6 +180,7 @@ ohos_shared_library("udmf_data_napi") { external_deps = [ "ability_base:want", "ability_runtime:abilitykit_native", + "ability_runtime:napi_common", "c_utils:utils", "hilog:libhilog", "ipc:ipc_core", @@ -181,7 +189,7 @@ ohos_shared_library("udmf_data_napi") { ] public_external_deps = [ "image_framework:image" ] - + cflags = [ "-fvisibility=hidden" ] subsystem_name = "distributeddatamgr" part_name = "udmf" } @@ -189,6 +197,8 @@ ohos_shared_library("udmf_data_napi") { ohos_static_library("udmf_js_common") { branch_protector_ret = "pac_ret" sanitize = { + ubsan = true + boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false @@ -201,7 +211,6 @@ ohos_static_library("udmf_js_common") { ldflags = [ "-Wl,--exclude-libs=ALL" ] cflags = [ "-fvisibility=hidden" ] - include_dirs = [ "${udmf_interfaces_path}/jskits/common" ] public_configs = [ ":udmf_napi_config" ] diff --git a/udmf/interfaces/jskits/common/napi_data_utils.h b/udmf/interfaces/jskits/common/napi_data_utils.h index 55189159..db354fab 100644 --- a/udmf/interfaces/jskits/common/napi_data_utils.h +++ b/udmf/interfaces/jskits/common/napi_data_utils.h @@ -37,7 +37,7 @@ namespace OHOS { namespace UDMF { -class NapiDataUtils { +class API_EXPORT NapiDataUtils { public: /* napi_value <-> bool */ static napi_status GetValue(napi_env env, napi_value in, bool &out); @@ -98,7 +98,7 @@ public: static bool IsTypeForNapiValue(napi_env env, napi_value param, napi_valuetype expectType); static bool IsNull(napi_env env, napi_value value); - /* napi_define_class wrapper */ + /* napi_define_class wrapper */ static napi_value DefineClass(napi_env env, const std::string &name, const napi_property_descriptor *properties, size_t count, napi_callback newcb); diff --git a/udmf/interfaces/jskits/common/napi_error_utils.h b/udmf/interfaces/jskits/common/napi_error_utils.h index 0221d711..e5ed8311 100644 --- a/udmf/interfaces/jskits/common/napi_error_utils.h +++ b/udmf/interfaces/jskits/common/napi_error_utils.h @@ -73,13 +73,13 @@ napi_value GenerateErrorMsg(napi_env env, NapiErrorCode jsInfo); } \ } while (0) -#define ASSERT_PERMISSION_ERR(ctxt, assertion, errorCode, message) \ - do { \ - if (!(assertion)) { \ - (ctxt)->isThrowError = true; \ - ThrowNapiError((ctxt)->env, errorCode, message, false); \ - return; \ - } \ +#define ASSERT_BUSINESS_ERR_VOID(ctxt, assertion, errorCode, message) \ + do { \ + if (!(assertion)) { \ + (ctxt)->isThrowError = true; \ + ThrowNapiError((ctxt)->env, errorCode, message, false); \ + return nullptr; \ + } \ } while (0) } // namespace UDMF } // namespace OHOS diff --git a/udmf/interfaces/jskits/data/summary_napi.h b/udmf/interfaces/jskits/data/summary_napi.h index 069cabf8..29d5473d 100644 --- a/udmf/interfaces/jskits/data/summary_napi.h +++ b/udmf/interfaces/jskits/data/summary_napi.h @@ -20,12 +20,13 @@ #include "napi/native_api.h" #include "napi/native_node_api.h" +#include "visibility.h" namespace OHOS { namespace UDMF { struct ContextBase; struct Summary; -class SummaryNapi { +class API_EXPORT SummaryNapi { public: static napi_value Constructor(napi_env env); static void NewInstance(napi_env env, std::shared_ptr<Summary> in, napi_value &out); diff --git a/udmf/interfaces/jskits/data/unified_data_channel_napi.h b/udmf/interfaces/jskits/data/unified_data_channel_napi.h index 2850cd07..9077bacc 100644 --- a/udmf/interfaces/jskits/data/unified_data_channel_napi.h +++ b/udmf/interfaces/jskits/data/unified_data_channel_napi.h @@ -37,6 +37,8 @@ private: static napi_value DeleteData(napi_env env, napi_callback_info info); static napi_status GetNamedProperty(napi_env env, napi_value &obj, const std::string &key, std::string &value); static napi_value CreateShareOptions(napi_env env, napi_callback_info info); + static napi_value SetAppShareOptions(napi_env env, napi_callback_info info); + static napi_value RemoveAppShareOptions(napi_env env, napi_callback_info info); }; } // namespace UDMF } // namespace OHOS diff --git a/udmf/interfaces/jskits/data/unified_data_napi.h b/udmf/interfaces/jskits/data/unified_data_napi.h index b9afa8cb..a3e2d2c4 100644 --- a/udmf/interfaces/jskits/data/unified_data_napi.h +++ b/udmf/interfaces/jskits/data/unified_data_napi.h @@ -17,12 +17,12 @@ #define UDMF_UNIFIED_DATA_NAPI_H #include "unified_data_properties_napi.h" - +#include "visibility.h" namespace OHOS { namespace UDMF { class UnifiedData; class UnifiedRecord; -class UnifiedDataNapi { +class API_EXPORT UnifiedDataNapi { public: static napi_value Constructor(napi_env env); static napi_status NewInstance(napi_env env, std::shared_ptr<UnifiedData> in, napi_value &out); diff --git a/utils_native/safwk/native/include/system_ability_definition.h b/utils_native/safwk/native/include/system_ability_definition.h index 20fc65a2..54c09bc4 100644 --- a/utils_native/safwk/native/include/system_ability_definition.h +++ b/utils_native/safwk/native/include/system_ability_definition.h @@ -1,17 +1,17 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +* Copyright (c) 2022-2023 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ #ifndef UTILS_SYSTEM_ABILITY_DEFINITION_H #define UTILS_SYSTEM_ABILITY_DEFINITION_H @@ -20,32 +20,55 @@ #include<string> namespace OHOS { -// system ability definition should be a number between FIRST_SYS_ABILITY_ID and LAST_SYS_ABILITY_ID +/* +System ability definition should be a number between FIRST_SYS_ABILITY_ID and LAST_SYS_ABILITY_ID. +And for vendor, should be a number between VENDOR_SYS_ABILITY_ID_BEGIN and VENDOR_SYS_ABILITY_ID_END. + +If a new SA definition is added, it is necessary to synchronously add a mapping in the hidumper and +synchronously add a mapping in the rust definition. +The path of hidumper is "\base\hiviewdfx\hidumper\frameworks\native\dump_utils.cpp", and map name is "saNameMap_" +The path of definition.rs is "\foundation\systemabilitymgr\samgr\interfaces\innerkits\rust\src\cxx\definition.rs" +*/ enum { + SAMGR_DUMP_SAID = 0, FIRST_SYS_ABILITY_ID = 0x00000001, SUBSYS_COMMON_SYS_ABILITY_ID_BEGIN = 1, + RENDER_SERVICE = 10, SUBSYS_AAFWK_SYS_ABILITY_ID_BEGIN = 100, ABILITY_TOOLS_SERVICE_ID = 116, ABILITY_TEST_SERVICE_ID = 179, ABILITY_MGR_SERVICE_ID = 180, ABILITY_MST_SERVICE_ID = 181, DATAOBS_MGR_SERVICE_SA_ID = 182, + URI_PERMISSION_MGR_SERVICE_ID = 183, + QUICK_FIX_MGR_SERVICE_ID = 184, SUBSYS_AAFWK_SYS_ABILITY_ID_END = 199, SUBSYS_ACCOUNT_SYS_ABILITY_ID_BEGIN = 200, SUBSYS_AI_SYS_ABILITY_ID_BEGIN = 300, + SUBSYS_AI_DS_SYS_ABILITY_ID = 310, + AIDISPATCHER_ENGINE_SERVICE = 311, + INTELL_VOICE_SERVICE_ID = 312, SUBSYS_APPEXECFWK_SYS_ABILITY_ID_BEGIN = 400, BUNDLE_MGR_SERVICE_SYS_ABILITY_ID = 401, + DISTRIBUTED_BUNDLE_MGR_SERVICE_SYS_ABILITY_ID = 402, FORM_MGR_SERVICE_ID = 403, + SERVICE_ROUTER_MGR_SERVICE_ID = 404, SUBSYS_APPLICATIONS_SYS_ABILITY_ID_BEGIN = 500, APP_MGR_SERVICE_ID = 501, INSTALLD_SERVICE_ID = 511, SUBSYS_ARVR_SYS_ABILITY_ID_BEGIN = 600, SUBSYS_ARVRHARDWARE_SYS_ABILITY_ID_BEGIN = 700, SUBSYS_BARRIERFREE_SYS_ABILITY_ID_BEGIN = 800, - SUBSYS_BIOMETRICS_SYS_ABILITY_ID_BEGIN = 900, - SUBSYS_BIOMETRICS_SYS_ABILITY_FACERECOGNIZE = 901, - SUBSYS_BIOMETRICS_SYS_ABILITY_FINGERPRINT = 902, - SUBSYS_BIOMETRICS_SYS_ABILITY_VOICEID = 903, + ACCESSIBILITY_MANAGER_SERVICE_ID = 801, + SUBSYS_BARRIERFREE_SYS_ABILITY_ID_END = 899, + SUBSYS_USERIAM_SYS_ABILITY_ID_BEGIN = 900, + SUBSYS_USERIAM_SYS_ABILITY_USERIDM = 901, + SUBSYS_USERIAM_SYS_ABILITY_USERAUTH = 921, + SUBSYS_USERIAM_SYS_ABILITY_AUTHEXECUTORMGR = 931, + SUBSYS_USERIAM_SYS_ABILITY_PINAUTH = 941, + SUBSYS_USERIAM_SYS_ABILITY_FACEAUTH = 942, + SUBSYS_USERIAM_SYS_ABILITY_FINGERPRINTAUTH = 943, + SUBSYS_USERIAM_SYS_ABILITY_FINGERPRINTAUTH_EX = 944, SUBSYS_CCRUNTIME_SYS_ABILITY_ID_BEGIN = 1000, SUBSYS_COMMUNICATION_SYS_ABILITY_ID_BEGIN = 1100, RPC_UNREGISTERED_TEST_SERVICE = 1108, @@ -61,8 +84,10 @@ enum { WIFI_HOTSPOT_SYS_ABILITY_ID = 1121, WIFI_ENHANCER_SYS_ABILITY_ID = 1122, WIFI_P2P_SYS_ABILITY_ID = 1123, + WIFI_SCAN_SYS_ABILITY_ID = 1124, BLUETOOTH_HOST_SYS_ABILITY_ID = 1130, NFC_MANAGER_SYS_ABILITY_ID = 1140, + SE_MANAGER_SYS_ABILITY_ID = 1141, DISCOVER_SYS_ABILITY_ID = 1160, DNET_SYS_ABILITY_ID = 1170, NET_MANAGER_SYS_ABILITY_ID = 1150, @@ -73,9 +98,24 @@ enum { COMM_VPN_MANAGER_SYS_ABILITY_ID = 1155, COMM_DNS_MANAGER_SYS_ABILITY_ID = 1156, COMM_ETHERNET_MANAGER_SYS_ABILITY_ID = 1157, + COMM_NETSYS_NATIVE_SYS_ABILITY_ID = 1158, + COMM_MDNS_MANAGER_SYS_ABILITY_ID = 1161, + COMM_NETSYS_EXT_SYS_ABILITY_ID = 1162, + COMM_DISTRIBUTED_NET_ABILITY_ID = 1163, SMART_COMM_SYS_ABILITY_ID = 1180, + NEARLINK_HOST_SYS_ABILITY_ID = 1190, SUBSYS_DFX_SYS_ABILITY_ID_BEGIN = 1200, DFX_SYS_HIVIEW_ABILITY_ID = 1201, + DFX_FAULT_LOGGER_ABILITY_ID = 1202, + DFX_SYS_EVENT_SERVICE_ABILITY_ID = 1203, + DFX_SYS_NATIVE_MEMORY_PROFILER_SERVICE_ABILITY_ID = 1205, + XPERF_SYS_TRACE_SERVICE_ABILITY_ID = 1208, + XPERF_SYS_IO_SERVICE_ABILITY_ID = 1209, + XPERF_BIGDATA_MANAGER_SERVICE_ABILITY_ID = 1210, + DFX_HI_DUMPER_SERVICE_ABILITY_ID = 1212, + XPOWER_MANAGER_SYSTEM_ABILITY_ID = 1213, + DFX_HI_PERF_SERVICE_ABILITY_ID = 1214, + DFX_HI_DUMPER_CPU_SERVICE_ABILITY_ID = 1215, SUBSYS_DISTRIBUTEDDATAMNG_SYS_ABILITY_ID_BEGIN = 1300, DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID = 1301, DISTRIBUTED_FS_DAEMON_SERVICE_ID = 1302, @@ -85,6 +125,7 @@ enum { DISTRIBUTED_SCHED_SA_ID = 1401, DISTRIBUTED_SCHED_ADAPTER_SA_ID = 1402, DISTRIBUTED_SCENARIO_MGR_SA_ID = 1403, + CONTINUATION_MANAGER_SA_ID = 1404, DISTRIBUTED_SCHED_TEST_SO_ID = 1490, DISTRIBUTED_SCHED_TEST_OS_ID = 1491, DISTRIBUTED_SCHED_TEST_OOS_ID = 1492, @@ -97,6 +138,8 @@ enum { DISTRIBUTED_SCHED_TEST_MEDIA_ID = 1499, SUBSYS_DRIVERS_SYS_ABILITY_ID_BEGIN = 1500, SUBSYS_GLOBAL_SYS_ABILITY_ID_BEGIN = 1600, + ENTERPRISE_DEVICE_MANAGER_SA_ID = 1601, + I18N_SA_ID = 1602, SUBSYS_GRAPHIC_SYS_ABILITY_ID_BEGIN = 1700, SUBSYS_HBS_SYS_ABILITY_ID_BEGIN = 1800, SUBSYS_IAWARE_SYS_ABILITY_ID_BEGIN = 1900, @@ -104,6 +147,18 @@ enum { RESSCHEDD_SA_ID = 1902, BACKGROUND_TASK_MANAGER_SERVICE_ID = 1903, WORK_SCHEDULE_SERVICE_ID = 1904, + COMPONENT_SCHEDULE_SERVICE_ID = 1905, + SOC_PERF_SERVICE_SA_ID = 1906, + DEVICE_USAGE_STATISTICS_SYS_ABILITY_ID = 1907, + MEMORY_MANAGER_SA_ID = 1909, + SUSPEND_MANAGER_SYSTEM_ABILITY_ID = 1910, + ABNORMAL_EFFICIENCY_MGR_SYSTEM_ABILITY_ID = 1911, + CONCURRENT_TASK_SERVICE_ID = 1912, + RESOURCE_QUOTA_CONTROL_SYSTEM_ABILITY_ID = 1913, + DEVICE_STANDBY_SERVICE_SYSTEM_ABILITY_ID = 1914, + TASK_HEARTBEAT_MGR_SYSTEM_ABILITY_ID = 1915, + APP_NAP_SYSTEM_ABILITY_ID = 1916, + RES_SCHED_EXE_ABILITY_ID = 1918, SUBSYS_IDE_SYS_ABILITY_ID_BEGIN = 2000, SUBSYS_INTELLIACCESSORIES_SYS_ABILITY_ID_BEGIN = 2100, SUBSYS_INTELLISPEAKER_SYS_ABILITY_ID_BEGIN = 2200, @@ -124,7 +179,14 @@ enum { LOCATION_NOPOWER_LOCATING_SA_ID = 2805, LOCATION_NOTIFICATION_SA_ID = 2806, SUBSYS_MSDP_SYS_ABILITY_ID_BEGIN = 2900, - MSDP_PROXY_SERVICE_ID = 2901, + MSDP_MOTION_SERVICE_ID = 2901, + MSDP_DEVICESTATUS_SERVICE_ID = 2902, + MSDP_MOVEMENT_SERVICE_ID = 2903, + MSDP_SPATIAL_AWARENESS_SERVICE_ID = 2904, + MSDP_GEOFENCE_SERVICE_ID = 2905, + MSDP_TIMELINE_SERVICE_ID = 2906, + MSDP_USER_STATUS_SERVICE_ID = 2907, + MSDP_MULTIMODAL_AWARENESS_SERVICE_ID = 2908, SUBSYS_MULTIMEDIA_SYS_ABILITY_ID_BEGIN = 3000, AUDIO_DISTRIBUTED_SERVICE_ID = 3001, PLAYER_DISTRIBUTED_SERVICE_ID = 3002, @@ -134,6 +196,10 @@ enum { MEDIA_LIBRARY_SERVICE_ID = 3007, CAMERA_SERVICE_ID = 3008, AUDIO_POLICY_SERVICE_ID = 3009, + AVSESSION_SERVICE_ID = 3010, + AV_CODEC_SERVICE_ID = 3011, + MEDIA_KEY_SYSTEM_SERVICE_ID = 3012, + MEDIA_MONITOR_SERVICE_ID = 3013, SUBSYS_MULTIMODAINPUT_SYS_ABILITY_ID_BEGIN = 3100, MULTIMODAL_INPUT_SERVICE_ID = 3101, MULTIMODAL_CHANNEL_SERVICE_ID = 3102, @@ -145,21 +211,43 @@ enum { SUBSYS_POWERMNG_SYS_ABILITY_ID_BEGIN = 3300, POWER_MANAGER_SERVICE_ID = 3301, POWER_MANAGER_BATT_SERVICE_ID = 3302, + POWER_MANAGER_THERMAL_SERVICE_ID = 3303, + POWER_MANAGER_BATT_STATS_SERVICE_ID = 3304, DISPLAY_MANAGER_SERVICE_ID = 3308, IVIPOWER_ENHANCED_SERVICE_ID = 3309, SUBSYS_ROUTER_SYS_ABILITY_ID_BEGIN = 3400, SUBSYS_SECURITY_SYS_ABILITY_ID_BEGIN = 3500, + ACCESS_TOKEN_MANAGER_SERVICE_ID = 3503, + TOKEN_SYNC_MANAGER_SERVICE_ID = 3504, + PRIVACY_MANAGER_SERVICE_ID = 3505, + SECURITY_COMPONENT_SERVICE_ID = 3506, + LOCAL_CODE_SIGN_SERVICE_ID = 3507, + SANDBOX_MANAGER_SERVICE_ID = 3508, + DEVICE_SECURITY_LEVEL_MANAGER_SA_ID = 3511, + CERT_MANAGER_SERVICE_SA_ID = 3512, + DEVICE_THREAT_DETECTION_SERVICE_SA_ID = 3513, + DLP_PERMISSION_SERVICE_ID = 3521, + RISK_ANALYSIS_MANAGER_SA_ID = 3523, + DATA_COLLECT_MANAGER_SA_ID = 3524, + DLP_CREDENTIAL_SERVICE_ID = 3553, SUBSYS_SENSORS_SYS_ABILITY_ID_BEGIN = 3600, SENSOR_SERVICE_ABILITY_ID = 3601, MISCDEVICE_SERVICE_ABILITY_ID = 3602, EXTSHB_SERVICE_ABILITY_ID = 3603, + MEDICAL_SENSOR_SERVICE_ABILITY_ID = 3605, SUBSYS_SMALLSERVICES_SYS_ABILITY_ID_BEGIN = 3700, PASTEBOARD_SERVICE_ID = 3701, TIME_SERVICE_ID = 3702, INPUT_METHOD_SYSTEM_ABILITY_ID = 3703, + SCREENLOCK_SERVICE_ID = 3704, + WALLPAPER_MANAGER_SERVICE_ID = 3705, + DOWNLOAD_SERVICE_ID = 3706, + PRINT_SERVICE_ID = 3707, + SCAN_SERVICE_ID = 3708, SUBSYS_SOURCECODETRANSFORMER_SYS_ABILITY_ID_BEGIN = 3800, SUBSYS_STARTUP_SYS_ABILITY_ID_BEGIN = 3900, PARAM_WATCHER_DISTRIBUTED_SERVICE_ID = 3901, + SYSPARAM_DEVICE_SERVICE_ID = 3902, SUBSYS_TELEPONY_SYS_ABILITY_ID_BEGIN = 4000, TELEPHONY_SYS_ABILITY_ID = 4001, DCALL_SYS_ABILITY_ID = 4002, @@ -170,8 +258,13 @@ enum { TELEPHONY_STATE_REGISTRY_SYS_ABILITY_ID = 4009, TELEPHONY_CORE_SERVICE_SYS_ABILITY_ID = 4010, TELEPHONY_DATA_STORAGE_SYS_ABILITY_ID = 4012, + TELEPHONY_IMS_SYS_ABILITY_ID = 4014, SUBSYS_UPDATE_SYS_ABILITY_ID_BEGIN = 4100, + SYS_INSTALLER_DISTRIBUTED_SERVICE_ID = 4101, + QUICKFIX_ENGINE_SERVICE_ID = 4102, + MODULE_UPDATE_SERVICE_ID = 4103, SUBSYS_USB_SYS_ABILITY_ID_BEGIN = 4200, + USB_SYSTEM_ABILITY_ID = 4201, SUBSYS_WEARABLE_SYS_ABILITY_ID_BEGIN = 4300, SUBSYS_WEARABLEHARDWARE_SYS_ABILITY_ID_BEGIN = 4400, SUBSYS_IVI_SYS_ABILITY_ID_BEGIN = 4500, @@ -183,59 +276,56 @@ enum { VSYNC_MANAGER_TEST_ID = 4602, GRAPHIC_DUMPER_SERVICE_SA_ID = 4603, GRAPHIC_DUMPER_COMMAND_SA_ID = 4604, + ANIMATION_SERVER_SA_ID = 4605, + WINDOW_MANAGER_SERVICE_ID = 4606, + DISPLAY_MANAGER_SERVICE_SA_ID = 4607, SOFTBUS_SERVER_SA_ID = 4700, DEVICE_AUTH_SERVICE_ID = 4701, SUBSYS_DISTRIBUTED_HARDWARE_SYS_ABILITY_ID_BEGIN = 4800, DISTRIBUTED_HARDWARE_SA_ID = 4801, DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID = 4802, - SUBSYS_STORAGE_SYS_ABILITY_ID_BEGIN = 4900, - STORAGE_DISTRIBUTED_FILE_DEAMON_SA_ID = 4901, - STORAGE_DISTRIBUTED_FILE_SERVICE_SA_ID = 4902, + DISTRIBUTED_HARDWARE_CAMERA_SOURCE_SA_ID = 4803, + DISTRIBUTED_HARDWARE_CAMERA_SINK_SA_ID = 4804, + DISTRIBUTED_HARDWARE_AUDIO_SOURCE_SA_ID = 4805, + DISTRIBUTED_HARDWARE_AUDIO_SINK_SA_ID = 4806, + DISTRIBUTED_HARDWARE_SCREEN_SOURCE_SA_ID = 4807, + DISTRIBUTED_HARDWARE_SCREEN_SINK_SA_ID = 4808, + DISTRIBUTED_HARDWARE_INPUT_SOURCE_SA_ID = 4809, + DISTRIBUTED_HARDWARE_INPUT_SINK_SA_ID = 4810, DEVICE_STORAGE_MANAGER_SERVICE_ID = 5000, STORAGE_SERVICE_ID = 5001, + STORAGE_MANAGER_DAEMON_ID = 5002, + STORAGE_MANAGER_MANAGER_ID = 5003, + FILE_ACCESS_SERVICE_ID = 5010, DEVICE_SERVICE_MANAGER_SA_ID = 5100, - LAST_SYS_ABILITY_ID = 0x00ffffff, // 16777215 -}; + HDF_EXTERNAL_DEVICE_MANAGER_SA_ID = 5110, + SUBSYS_FILEMANAGEMENT_SYS_ABILITY_ID_BEGIN = 5200, + FILEMANAGEMENT_DISTRIBUTED_FILE_DAEMON_SA_ID = 5201, + FILEMANAGEMENT_DISTRIBUTED_FILE_SERVICE_SA_ID = 5202, + FILEMANAGEMENT_BACKUP_SERVICE_SA_ID = 5203, + FILEMANAGEMENT_CLOUD_SYNC_SERVICE_SA_ID = 5204, + FILEMANAGEMENT_CLOUD_DAEMON_SERVICE_SA_ID = 5205, + FILEMANAGEMENT_CLOUD_BACKUP_SERVICE_SA_ID = 5206, + AOT_COMPILER_SERVICE_ID = 5300, + SUBSYS_TESTPLATFORM_SYS_ABILITY_ID_BEGIN = 5500, + DEVICE_ATTEST_PROFILE_SA_ID = 5501, + TEST_SERVER_SA_ID = 5502, + DISTRIBUTED_DEVICE_PROFILE_SA_ID = 6001, + ADVERTISING_SA_ID = 6104, + ECOLOGICAL_RULE_MANAGER_SA_ID = 6105, + APP_DOMAIN_VERIFY_MANAGER_SA_ID = 6200, + APP_DOMAIN_VERIFY_AGENT_SA_ID = 6201, + SUBSYS_ACE_SYS_ABILITY_ID_BEGIN = 7001, + ARKUI_UI_APPEARANCE_SERVICE_ID = 7002, + CA_DAEMON_ID = 8001, + ASSET_SERVICE_ID = 8100, + EL5_FILEKEY_MANAGER_SERVICE_ID = 8250, + COMM_FIREWALL_MANAGER_SYS_ABILITY_ID = 8300, -static const std::map<int, std::string> saNameMap_ = { - { 200, "AccountMgr" }, - { 301, "AIEngine" }, - { BUNDLE_MGR_SERVICE_SYS_ABILITY_ID, "BundleMgr" }, - { FORM_MGR_SERVICE_ID, "FormMgr" }, - { WIFI_DEVICE_SYS_ABILITY_ID, "WifiDevice" }, - { WIFI_HOTSPOT_SYS_ABILITY_ID, "WifiHotspot" }, - { WIFI_ENHANCER_SYS_ABILITY_ID, "WifiEnhancer" }, - { WIFI_P2P_SYS_ABILITY_ID, "WifiP2p" }, - { BLUETOOTH_HOST_SYS_ABILITY_ID, "BluetoothHost" }, - { NFC_MANAGER_SYS_ABILITY_ID, "NfcManager" }, - { NET_MANAGER_SYS_ABILITY_ID, "NetManager" }, - { DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID, "DistributedKvData" }, - { DISTRIBUTED_SCHED_SA_ID, "DistributedSched" }, - { DISTRIBUTED_SCHED_ADAPTER_SA_ID, "DistributedSchedAdapter" }, - { DISTRIBUTED_SCENARIO_MGR_SA_ID, "DistributedScenarioMgr" }, - { RES_SCHED_SYS_ABILITY_ID, "ResourceSched" }, - { RESSCHEDD_SA_ID, "ResourceSchedDamon" }, - { BACKGROUND_TASK_MANAGER_SERVICE_ID, "BackgroundTaskManager" }, - { WORK_SCHEDULE_SERVICE_ID, "WorkSchedule" }, - { LOCATION_GEO_CONVERT_SA_ID, "LocationGeoConvert" }, - { LOCATION_LOCATOR_SA_ID, "LocationLocator" }, - { LOCATION_GNSS_SA_ID, "LocationGnss" }, - { LOCATION_NETWORK_LOCATING_SA_ID, "LocationNetworkLocating" }, - { LOCATION_NOPOWER_LOCATING_SA_ID, "LocationNopowerLocating" }, - { AUDIO_DISTRIBUTED_SERVICE_ID, "AudioDistributed" }, - { COMMON_EVENT_SERVICE_ABILITY_ID, "CommonEventService" }, - { ADVANCED_NOTIFICATION_SERVICE_ABILITY_ID, "AdvancedNotificationService" }, - { POWER_MANAGER_SERVICE_ID, "PowerManagerService" }, - { POWER_MANAGER_BATT_SERVICE_ID, "PowerManagerBatt" }, - { 3502, "DpmsService" }, - { 3510, "KeystoreService" }, - { SENSOR_SERVICE_ABILITY_ID, "SensorService" }, - { MISCDEVICE_SERVICE_ABILITY_ID, "MiscDeviceService" }, - { PASTEBOARD_SERVICE_ID, "DPasteboardService" }, - { TELEPHONY_SYS_ABILITY_ID, "Telephony" }, - { DCALL_SYS_ABILITY_ID, "DistributedCallMgr" }, - { DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID, "DeviceManagerService" }, - { DEVICE_SERVICE_MANAGER_SA_ID, "HdfDeviceServiceManager" }, + // reserved for vendor + VENDOR_SYS_ABILITY_ID_BEGIN = 0x00010000, // 65536 + VENDOR_SYS_ABILITY_ID_END = 0x00020000, // 131072 + LAST_SYS_ABILITY_ID = 0x00ffffff, // 16777215 }; } // namespace OHOS -- Gitee