From 4450d0fceab406c49d31f82d955bd2debb7cfdec Mon Sep 17 00:00:00 2001 From: htt1997 Date: Sat, 23 Nov 2024 16:23:31 +0800 Subject: [PATCH] update Signed-off-by: htt1997 --- .../innerkitsimpl/test/unittest/BUILD.gn | 247 ++- .../unittest/src/app_device_handler_test.cpp | 103 + .../unittest/src/asset_change_timer_test.cpp | 184 ++ .../test/unittest/src/client_adaptor_test.cpp | 111 + .../src/distributed_object_impl_test.cpp | 89 + .../distributed_object_store_impl_test.cpp | 99 + .../unittest/src/flat_object_store_test.cpp | 122 + .../src/object_callback_stub_test.cpp | 78 + .../src/object_service_proxy_test.cpp | 120 + .../unittest/src/object_types_util_test.cpp | 148 ++ data_share/bundle.json | 14 +- data_share/datashare.gni | 2 + data_share/frameworks/cj/ffi/BUILD.gn | 19 + .../cj/ffi/data_share_predicates/BUILD.gn | 59 + .../include/data_share_predicates_ffi.h | 58 + .../include/data_share_predicates_impl.h | 59 + .../include/data_share_predicates_utils.h | 50 +- .../src/data_share_predicates_ffi.cpp | 133 ++ .../src/data_share_predicates_impl.cpp | 83 + .../src/data_share_predicates_utils.cpp | 84 + .../js/napi/common/src/datashare_js_utils.cpp | 8 +- .../common/src/datashare_itypes_utils.cpp | 28 +- .../include/js_datashare_ext_ability.h | 14 +- .../proxy/include/data_proxy_observer_stub.h | 5 +- .../proxy/src/data_proxy_observer_stub.cpp | 90 +- .../proxy/src/data_share_service_proxy.cpp | 7 +- .../common/include/datashare_template.h | 28 + .../include/datashare_shared_result_set.h | 2 +- data_share/test/native/BUILD.gn | 15 +- .../src/mediadatashare_unit_test.cpp | 270 +++ .../src/account_delegate_normal_impl.cpp | 8 + .../communicator/src/app_pipe_handler.cpp | 4 +- .../communicator/src/app_pipe_handler.h | 2 +- .../adapter/communicator/src/app_pipe_mgr.cpp | 8 +- .../adapter/communicator/src/app_pipe_mgr.h | 2 +- .../src/communication_provider_impl.cpp | 4 +- .../src/communication_provider_impl.h | 2 +- .../communicator/src/communicator_context.cpp | 17 +- .../src/device_manager_adapter.cpp | 42 +- .../src/process_communicator_impl.cpp | 16 +- .../communicator/src/softbus_adapter.h | 6 +- .../src/softbus_adapter_standard.cpp | 36 +- .../communicator/src/softbus_client.cpp | 25 +- .../adapter/communicator/src/softbus_client.h | 4 +- .../communication_provider_impl_test.cpp | 20 +- .../softbus_adapter_standard_test.cpp | 4 +- .../communicator/app_device_change_listener.h | 2 +- .../include/communicator/commu_types.h | 19 + .../communicator/communication_provider.h | 5 +- .../communicator/communicator_context.h | 2 +- .../communicator/device_manager_adapter.h | 4 + .../communicator/process_communicator_impl.h | 2 +- .../app/src/checker/bundle_checker.cpp | 59 +- .../app/src/checker/bundle_checker.h | 1 + .../app/src/kvstore_data_service.cpp | 177 +- .../app/src/kvstore_data_service.h | 12 +- .../app/src/kvstore_device_listener.cpp | 3 +- .../app/src/kvstore_device_listener.h | 2 +- .../app/src/kvstore_meta_manager.cpp | 10 - .../route_head_handler_impl.cpp | 13 +- .../src/session_manager/session_manager.cpp | 88 +- .../app/src/session_manager/session_manager.h | 10 +- .../src/session_manager/upgrade_manager.cpp | 53 - .../app/src/session_manager/upgrade_manager.h | 5 - .../unittest/kvstore_data_service_test.cpp | 53 - .../framework/directory/directory_manager.cpp | 3 + .../include/account/account_delegate.h | 2 + .../framework/include/store/general_store.h | 2 +- .../framework/metadata/store_meta_data.cpp | 3 +- .../framework/test/checker_manager_test.cpp | 19 - .../service/cloud/cloud_service_impl.cpp | 1 + .../service/data_share/common/db_delegate.h | 2 + .../service/data_share/common/kv_delegate.cpp | 2 +- .../service/data_share/common/kv_delegate.h | 2 +- .../data_share/common/rdb_delegate.cpp | 27 +- .../service/data_share/common/rdb_delegate.h | 1 + .../data_share/common/scheduler_manager.cpp | 2 +- .../service/data_share/data/template_data.cpp | 10 +- .../service/data_share/data/template_data.h | 1 + .../data_share/data_share_obs_proxy.cpp | 116 + .../service/data_share/data_share_obs_proxy.h | 4 + .../data_share/data_share_service_impl.cpp | 2 +- .../data_share/data_share_service_stub.cpp | 2 +- .../data_share/data_share_types_util.cpp | 16 +- .../rdb_subscriber_manager.cpp | 15 +- .../rdb_subscriber_manager.h | 3 +- .../service/kvdb/auth_delegate.cpp | 47 +- .../service/kvdb/auth_delegate.h | 6 +- .../service/kvdb/kvdb_general_store.cpp | 8 +- .../service/kvdb/kvdb_general_store.h | 2 +- .../service/kvdb/kvdb_service_impl.cpp | 78 +- .../service/kvdb/kvdb_service_impl.h | 5 +- .../service/matrix/include/device_matrix.h | 1 - .../service/matrix/src/device_matrix.cpp | 22 - .../service/rdb/rdb_asset_loader.cpp | 1 + .../service/rdb/rdb_general_store.cpp | 8 +- .../service/test/cloud_data_test.cpp | 32 + .../test/data_share_obs_proxy_test.cpp | 318 +++ .../data_share_subscriber_managers_test.cpp | 2 +- .../fuzztest/cloudservicestub_fuzzer/BUILD.gn | 2 + .../datashareservicestub_fuzzer/BUILD.gn | 1 + .../fuzztest/kvdbservicestub_fuzzer/BUILD.gn | 2 + .../service/test/kvdb_service_test.cpp | 37 +- .../service/test/rdb_asset_loader_test.cpp | 53 +- .../service/test/rdb_cloud_test.cpp | 67 + .../udmf/preprocess/preprocess_utils.cpp | 1 - .../service/udmf/udmf_service_impl.cpp | 32 +- .../service/udmf/udmf_service_impl.h | 2 +- .../unittest/single_kvstore_client_test.cpp | 31 - .../kvdb/src/single_store_impl.cpp | 12 +- .../innerkitsimpl/kvdb/test/BUILD.gn | 57 + .../kvdb/test/dev_manager_mock_test.cpp | 14 - .../kvdb/test/device_manager_mock.cpp | 9 - .../kvdb/test/single_store_perf_pc_test.cpp | 250 +++ .../test/single_store_perf_phone_test.cpp | 333 +++ .../distributeddata/src/napi_queue.cpp | 3 +- .../distributedkvstore/src/js_error_utils.cpp | 7 +- .../distributedkvstore/src/js_kv_manager.cpp | 1 + .../distributedkvstore/src/napi_queue.cpp | 3 +- kv_store/frameworks/libs/CMakeLists.txt | 2 +- .../include/cloud/asset_operation_utils.h | 2 + .../distributeddb/common/include/db_common.h | 2 +- .../common/include/db_constant.h | 7 +- .../common/include/relational/tracker_table.h | 1 + .../src/cloud/asset_operation_utils.cpp | 18 + .../distributeddb/common/src/db_common.cpp | 8 +- .../distributeddb/common/src/db_constant.cpp | 1 - .../common/src/db_dfx_adapter.cpp | 62 +- .../common/src/relational/tracker_table.cpp | 33 +- .../common/src/runtime_context_impl.cpp | 5 - .../include/communicator_type_define.h | 2 +- .../communicator/include/iadapter.h | 2 +- .../include/send_task_scheduler.h | 3 + .../src/communicator_aggregator.cpp | 15 +- .../communicator/src/network_adapter.cpp | 4 +- .../communicator/src/send_task_scheduler.cpp | 15 + .../communicator/src/serial_buffer.cpp | 2 +- .../src/executor/base/grd_db_api.cpp | 2 +- .../include/iprocess_communicator.h | 2 +- .../interfaces/include/store_types.h | 2 +- .../src/kv_store_delegate_manager.cpp | 227 +- .../interfaces/src/kv_store_errno.cpp | 2 +- .../relational_store_sqlite_ext.cpp | 4 +- .../storage/include/db_properties.h | 2 +- .../storage/src/cloud/cloud_storage_utils.cpp | 5 +- .../storage/src/cloud/schema_mgr.cpp | 2 +- .../rd_single_ver_natural_store.cpp | 2 +- .../storage/src/kv/sync_able_kvdb.h | 4 +- .../relational_sync_able_storage.cpp | 8 +- .../relational_sync_data_inserter.cpp | 3 +- .../cloud_sync_log_table_manager.cpp | 16 +- .../collaboration_log_table_manager.cpp | 14 +- .../split_device_log_table_manager.cpp | 4 +- .../relational/sqlite_relational_utils.cpp | 2 +- ...qlite_single_relational_storage_engine.cpp | 46 +- .../sqlite_single_relational_storage_engine.h | 2 +- ...single_ver_relational_storage_executor.cpp | 101 +- ...e_single_ver_relational_storage_executor.h | 12 +- ...ver_relational_storage_executor_extend.cpp | 34 +- ...ver_relational_storage_extend_executor.cpp | 33 +- .../src/sqlite/sqlite_log_table_manager.cpp | 4 +- .../sqlite_single_ver_database_upgrader.cpp | 44 +- .../sqlite_single_ver_database_upgrader.h | 3 +- .../sqlite_single_ver_natural_store.cpp | 63 +- .../sqlite/sqlite_single_ver_natural_store.h | 10 +- ...te_single_ver_natural_store_connection.cpp | 2 +- ...sqlite_single_ver_natural_store_extend.cpp | 153 +- .../sqlite_single_ver_storage_engine.cpp | 7 +- .../sqlite/sqlite_single_ver_storage_engine.h | 2 +- .../storage/src/sqlite/sqlite_utils.cpp | 6 +- .../storage/src/sqlite/sqlite_utils.h | 2 +- .../storage/src/storage_engine.cpp | 120 +- .../storage/src/storage_engine.h | 17 +- .../syncer/src/cloud/cloud_db_proxy.cpp | 79 +- .../syncer/src/cloud/cloud_db_proxy.h | 20 +- .../syncer/src/cloud/cloud_sync_strategy.cpp | 2 +- .../syncer/src/cloud/cloud_sync_strategy.h | 2 +- .../syncer/src/cloud/cloud_sync_utils.cpp | 3 + .../syncer/src/cloud/cloud_syncer.cpp | 57 +- .../syncer/src/cloud/cloud_syncer.h | 18 +- .../syncer/src/cloud/cloud_syncer_extend.cpp | 120 +- .../syncer/src/cloud/process_notifier.cpp | 32 + .../syncer/src/cloud/process_notifier.h | 4 + .../syncer/src/device/generic_syncer.cpp | 2 +- .../syncer/src/device/isync_task_context.h | 2 +- .../syncer/src/device/meta_data.cpp | 169 +- .../syncer/src/device/meta_data.h | 13 +- .../device/query_sync_water_mark_helper.cpp | 66 +- .../src/device/query_sync_water_mark_helper.h | 2 - .../syncer/src/device/remote_executor.cpp | 3 +- .../device/singlever/single_ver_data_sync.cpp | 8 +- .../device/singlever/single_ver_data_sync.h | 2 +- .../singlever/single_ver_data_sync_extend.cpp | 6 +- .../single_ver_sync_state_machine.cpp | 12 +- .../syncer/src/device/sync_task_context.cpp | 23 +- .../syncer/src/device/sync_task_context.h | 6 +- .../syncer/src/device/time_sync.cpp | 8 +- .../syncer/src/sync_operation.cpp | 6 +- .../libs/distributeddb/test/BUILD.gn | 1 + .../test/fuzztest/json_fuzzer/json_fuzzer.cpp | 7 +- .../jsoninner_fuzzer/jsoninner_fuzzer.cpp | 7 +- .../kvdelegatemanager_fuzzer.cpp | 14 +- .../nbdelegate_fuzzer/nbdelegate_fuzzer.cpp | 6 +- .../src/distributeddb_nb_observer_test.cpp | 8 +- .../common/distributeddb_tools_unit_test.cpp | 5 +- .../common/communicator/adapter_stub.cpp | 4 +- .../common/communicator/adapter_stub.h | 2 +- .../distributeddb_communicator_deep_test.cpp | 52 +- ...buteddb_communicator_send_receive_test.cpp | 2 +- ...uteddb_cloud_interfaces_reference_test.cpp | 2 +- ...b_cloud_interfaces_relational_ext_test.cpp | 11 +- ...cloud_interfaces_set_cloud_schema_test.cpp | 6 +- ...ddb_interfaces_database_rd_kernel_test.cpp | 2 +- ...ddb_interfaces_nb_delegate_extend_test.cpp | 76 + ...nterfaces_nb_delegate_local_batch_test.cpp | 329 +++ ...tributeddb_interfaces_nb_delegate_test.cpp | 329 +++ .../distributeddb_interfaces_query_test.cpp | 2 +- ...uteddb_interfaces_relational_sync_test.cpp | 3 +- ...stributeddb_interfaces_relational_test.cpp | 42 + ...terfaces_relational_tracker_table_test.cpp | 187 +- ...teddb_cloud_assets_operation_sync_test.cpp | 261 ++- .../distributeddb_cloud_check_sync_test.cpp | 83 + ..._cloud_interfaces_relational_sync_test.cpp | 2 +- ...relational_cloud_syncable_storage_test.cpp | 49 +- ...distributeddb_relational_get_data_test.cpp | 40 +- ..._sqlite_single_ver_storage_engine_test.cpp | 6 +- .../common/syncer/cloud/cloud_syncer_test.h | 5 + .../distributeddb_cloud_db_proxy_test.cpp | 92 + .../distributeddb_cloud_kv_syncer_test.cpp | 96 + .../distributeddb_cloud_kvstore_test.cpp | 103 + .../distributeddb_cloud_syncer_lock_test.cpp | 73 +- ...distributeddb_cloud_syncer_upload_test.cpp | 86 + .../syncer/cloud/virtual_asset_loader.cpp | 83 +- .../syncer/cloud/virtual_asset_loader.h | 23 + .../syncer/distributeddb_meta_data_test.cpp | 6 +- ...stributeddb_relational_multi_user_test.cpp | 61 + ...teddb_single_ver_p2p_complex_sync_test.cpp | 217 +- ...buteddb_single_ver_p2p_query_sync_test.cpp | 4 + ...buteddb_single_ver_p2p_sync_check_test.cpp | 37 + .../virtual_communicator_aggregator.cpp | 9 +- .../syncer/virtual_communicator_aggregator.h | 5 +- .../distributeddata/include/executor.h | 3 +- .../distributeddata/include/executor_pool.h | 7 +- .../distributeddata/include/priority_queue.h | 3 +- .../distributeddata/include/store_errno.h | 7 +- .../innerkits/distributeddata/include/types.h | 4 + .../taskscheduler_fuzzer.cpp | 15 +- mock/src/mock_notification.cpp | 1 + .../common/src/napi_preferences_error.cpp | 11 +- .../src/napi_preferences.cpp | 4 + .../js/napi/storage/src/napi_storage.cpp | 6 +- .../native/src/preferences_xml_utils.cpp | 21 +- .../frameworks/cj/include/native_log.h | 16 +- .../cj/include/relational_store_ffi.h | 257 ++- ...relational_store_impl_rdbpredicatesproxy.h | 102 +- .../include/relational_store_impl_rdbstore.h | 282 ++- .../relational_store_impl_resultsetproxy.h | 49 +- .../cj/include/relational_store_utils.h | 326 ++- .../cj/src/relational_store_ffi.cpp | 1957 ++++++++--------- .../napi/relationalstore/src/entry_point.cpp | 4 +- .../relationalstore/src/napi_async_call.cpp | 4 +- .../src/napi_rdb_const_properties.cpp | 13 +- .../relationalstore/src/napi_rdb_error.cpp | 20 +- .../relationalstore/src/napi_rdb_js_utils.cpp | 8 +- .../src/napi_rdb_predicates.cpp | 3 +- .../relationalstore/src/napi_rdb_store.cpp | 20 +- .../src/napi_rdb_store_helper.cpp | 1 + .../src/napi_rdb_store_observer.cpp | 1 - .../relationalstore/src/napi_result_set.cpp | 6 +- .../relationalstore/src/napi_transaction.cpp | 27 +- .../relationalstore/src/napi_uv_queue.cpp | 5 +- .../dfx/src/rdb_fault_hiview_reporter.cpp | 13 +- .../native/rdb/include/connection.h | 3 + .../native/rdb/include/connection_pool.h | 9 +- .../native/rdb/include/rdb_store_impl.h | 19 +- .../native/rdb/include/rdb_store_manager.h | 2 +- .../native/rdb/include/sqlite_connection.h | 5 + .../native/rdb/include/sqlite_global_config.h | 3 +- .../native/rdb/include/sqlite_utils.h | 1 + .../native/rdb/mock/include/rdb_store_impl.h | 15 +- .../native/rdb/src/abs_predicates.cpp | 4 +- .../native/rdb/src/abs_rdb_predicates.cpp | 24 +- .../native/rdb/src/abs_result_set.cpp | 16 +- .../native/rdb/src/abs_shared_result_set.cpp | 8 +- .../frameworks/native/rdb/src/big_integer.cpp | 14 +- .../native/rdb/src/cache_result_set.cpp | 2 +- .../frameworks/native/rdb/src/connection.cpp | 32 +- .../native/rdb/src/connection_pool.cpp | 101 +- .../native/rdb/src/delay_notify.cpp | 9 +- .../native/rdb/src/grd_api_manager.cpp | 2 +- .../native/rdb/src/raw_data_parser.cpp | 20 +- .../native/rdb/src/rd_connection.cpp | 36 +- .../native/rdb/src/rd_statement.cpp | 49 +- .../frameworks/native/rdb/src/rd_utils.cpp | 31 +- .../native/rdb/src/rdb_manager_impl.cpp | 27 +- .../native/rdb/src/rdb_notifier_stub.cpp | 5 +- .../native/rdb/src/rdb_security_manager.cpp | 7 +- .../native/rdb/src/rdb_service_proxy.cpp | 104 +- .../native/rdb/src/rdb_sql_utils.cpp | 6 +- .../frameworks/native/rdb/src/rdb_store.cpp | 54 +- .../native/rdb/src/rdb_store_config.cpp | 38 +- .../native/rdb/src/rdb_store_impl.cpp | 264 ++- .../native/rdb/src/rdb_store_manager.cpp | 74 +- .../native/rdb/src/rdb_types_util.cpp | 21 +- .../native/rdb/src/security_policy.cpp | 13 +- .../frameworks/native/rdb/src/share_block.cpp | 35 +- .../rdb/src/shared_block_serializer_info.cpp | 4 +- .../native/rdb/src/sqlite_connection.cpp | 175 +- .../native/rdb/src/sqlite_global_config.cpp | 16 +- .../rdb/src/sqlite_shared_result_set.cpp | 32 +- .../native/rdb/src/sqlite_sql_builder.cpp | 8 +- .../native/rdb/src/sqlite_statement.cpp | 28 +- .../native/rdb/src/sqlite_utils.cpp | 282 ++- .../native/rdb/src/step_result_set.cpp | 2 +- .../native/rdb/src/string_utils.cpp | 8 +- .../frameworks/native/rdb/src/trans_db.cpp | 11 +- .../frameworks/native/rdb/src/transaction.cpp | 2 +- .../native/rdb/src/transaction_impl.cpp | 19 +- .../native/rdb/src/values_bucket.cpp | 2 +- .../native/rdb/src/values_buckets.cpp | 7 +- .../inner_api/rdb/include/rdb_errno.h | 7 +- .../inner_api/rdb/include/rdb_store_config.h | 21 +- .../inner_api/rdb/include/shared_result_set.h | 2 +- .../rdb/mock/include/rdb_store_config.h | 7 + .../interfaces/ndk/include/relational_store.h | 45 +- .../unittest/src/RdbstoreInsertJsunit.test.js | 32 + .../src/RdbstoreEncryptionJsunit.test.js | 59 + .../src/RdbstoreRdbstoreJsunit.test.js | 6 +- .../clouddata/unittest/cloud_data_test.cpp | 112 + .../rdb/unittest/rdb_double_write_test.cpp | 50 +- .../rdb/unittest/rdb_read_only_test.cpp | 6 +- .../unittest/rdb_security_manager_test.cpp | 27 +- .../rdb_store_backup_restore_test.cpp | 439 +++- .../rdb/unittest/rdb_store_impl_test.cpp | 22 + .../native/rdb/unittest/sqlite_utils_test.cpp | 146 ++ test/CMakeLists.txt | 2 + .../innerkitsimpl/common/unified_meta.cpp | 4 +- .../data/preset_type_descriptors.cpp | 14 + .../jskitsimpl/common/napi_data_utils.cpp | 10 + udmf/framework/jskitsimpl/data/file_napi.cpp | 8 +- udmf/framework/jskitsimpl/data/html_napi.cpp | 8 +- udmf/framework/jskitsimpl/data/link_napi.cpp | 8 +- .../jskitsimpl/data/plain_text_napi.cpp | 8 +- udmf/framework/jskitsimpl/data/text_napi.cpp | 8 +- .../data/unified_data_channel_napi.cpp | 1 - .../jskitsimpl/data/unified_data_napi.cpp | 4 + .../data/unified_data_properties_napi.cpp | 3 +- .../jskitsimpl/unittest/UdmfPromiseJsTest.js | 28 + udmf/framework/ndkimpl/data/udmf.cpp | 1 + .../innerkits/common/unified_meta.h | 3 + .../innerkits/data/unified_data_properties.h | 2 +- .../jskits/common/napi_data_utils.h | 3 + 352 files changed, 10936 insertions(+), 3985 deletions(-) create mode 100644 data_object/frameworks/innerkitsimpl/test/unittest/src/app_device_handler_test.cpp create mode 100644 data_object/frameworks/innerkitsimpl/test/unittest/src/asset_change_timer_test.cpp create mode 100644 data_object/frameworks/innerkitsimpl/test/unittest/src/client_adaptor_test.cpp create mode 100644 data_object/frameworks/innerkitsimpl/test/unittest/src/distributed_object_impl_test.cpp create mode 100644 data_object/frameworks/innerkitsimpl/test/unittest/src/distributed_object_store_impl_test.cpp create mode 100644 data_object/frameworks/innerkitsimpl/test/unittest/src/flat_object_store_test.cpp create mode 100644 data_object/frameworks/innerkitsimpl/test/unittest/src/object_callback_stub_test.cpp create mode 100644 data_object/frameworks/innerkitsimpl/test/unittest/src/object_service_proxy_test.cpp create mode 100644 data_object/frameworks/innerkitsimpl/test/unittest/src/object_types_util_test.cpp create mode 100644 data_share/frameworks/cj/ffi/BUILD.gn create mode 100644 data_share/frameworks/cj/ffi/data_share_predicates/BUILD.gn create mode 100644 data_share/frameworks/cj/ffi/data_share_predicates/include/data_share_predicates_ffi.h create mode 100644 data_share/frameworks/cj/ffi/data_share_predicates/include/data_share_predicates_impl.h rename kv_store/interfaces/innerkits/distributeddata/include/active_boottime.h => data_share/frameworks/cj/ffi/data_share_predicates/include/data_share_predicates_utils.h (40%) create mode 100644 data_share/frameworks/cj/ffi/data_share_predicates/src/data_share_predicates_ffi.cpp create mode 100644 data_share/frameworks/cj/ffi/data_share_predicates/src/data_share_predicates_impl.cpp create mode 100644 data_share/frameworks/cj/ffi/data_share_predicates/src/data_share_predicates_utils.cpp create mode 100644 datamgr_service/services/distributeddataservice/service/test/data_share_obs_proxy_test.cpp create mode 100644 kv_store/frameworks/innerkitsimpl/kvdb/test/single_store_perf_pc_test.cpp create mode 100644 kv_store/frameworks/innerkitsimpl/kvdb/test/single_store_perf_phone_test.cpp diff --git a/data_object/frameworks/innerkitsimpl/test/unittest/BUILD.gn b/data_object/frameworks/innerkitsimpl/test/unittest/BUILD.gn index f27810cf..eaf6c5dd 100644 --- a/data_object/frameworks/innerkitsimpl/test/unittest/BUILD.gn +++ b/data_object/frameworks/innerkitsimpl/test/unittest/BUILD.gn @@ -19,9 +19,6 @@ data_object_base_path = "//foundation/distributeddatamgr/data_object" data_object_innerkits_path = "${data_object_base_path}/frameworks/innerkitsimpl" -kv_store_include_path = - "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb" - config("module_private_config") { visibility = [ ":*" ] @@ -31,14 +28,39 @@ config("module_private_config") { "${data_object_innerkits_path}/include/common", "${data_object_innerkits_path}/include/communicator", "${data_object_innerkits_path}/include", - "${kv_store_include_path}/include", - "${kv_store_include_path}/interfaces/include/", - "${kv_store_include_path}/interfaces/include/relational", - "//foundation/distributeddatamgr/kv_store/frameworks/common", - "${relational_store_path}/interfaces/inner_api/common_type/include", + "${data_object_base_path}/interfaces/innerkits", + "${data_object_base_path}/frameworks/innerkitsimpl/include/adaptor", + "${data_object_base_path}/frameworks/jskitsimpl/include/adaptor", + "${data_object_base_path}/frameworks/jskitsimpl/include/common", ] } +common_external_deps = [ + "ability_base:want", + "access_token:libaccesstoken_sdk", + "access_token:libnativetoken", + "access_token:libtoken_setproc", + "bundle_framework:appexecfwk_core", + "c_utils:utils", + "device_manager:devicemanagersdk", + "dsoftbus:softbus_client", + "ffmpeg:libohosffmpeg", + "hilog:libhilog", + "hisysevent:libhisysevent", + "hitrace:hitrace_meter", + "hitrace:libhitracechain", + "image_framework:image", + "image_framework:image", + "image_framework:image_native", + "image_framework:pixelmap", + "ipc:ipc_core", + "kv_store:distributeddata_inner", + "kv_store:distributeddata_mgr", + "kv_store:distributeddb", + "libexif:libexif", + "samgr:samgr_proxy", +] + ohos_unittest("NativeObjectStoreTest") { branch_protector_ret = "pac_ret" sanitize = { @@ -58,12 +80,7 @@ ohos_unittest("NativeObjectStoreTest") { configs = [ ":module_private_config" ] - external_deps = [ - "access_token:libaccesstoken_sdk", - "access_token:libnativetoken", - "access_token:libtoken_setproc", - "hilog:libhilog", - ] + external_deps = common_external_deps deps = [ "//foundation/distributeddatamgr/data_object/interfaces/innerkits:distributeddataobject_static", @@ -72,7 +89,207 @@ ohos_unittest("NativeObjectStoreTest") { ] } +ohos_unittest("ObjectTypesUtilTest") { + module_out_path = module_output_path + + sources = [ + "${data_object_base_path}/frameworks/innerkitsimpl/src/object_types_util.cpp", + "${data_object_base_path}/frameworks/innerkitsimpl/test/unittest/src/object_types_util_test.cpp", + ] + + configs = [ ":module_private_config" ] + external_deps = common_external_deps + deps = [ "${data_object_base_path}/interfaces/innerkits:distributeddataobject_static" ] +} + +ohos_unittest("ObjectServiceProxyTest") { + module_out_path = module_output_path + + sources = [ + "${data_object_base_path}/frameworks/innerkitsimpl/src/object_service_proxy.cpp", + "${data_object_base_path}/frameworks/innerkitsimpl/src/object_types_util.cpp", + "${data_object_base_path}/frameworks/innerkitsimpl/test/unittest/src/object_service_proxy_test.cpp", + ] + + configs = [ ":module_private_config" ] + external_deps = common_external_deps + deps = [ "${data_object_base_path}/interfaces/innerkits:distributeddataobject_static" ] +} + +ohos_unittest("ObjectCallbackStubTest") { + module_out_path = module_output_path + + sources = [ + "${data_object_base_path}/frameworks/innerkitsimpl/src/adaptor/object_callback_impl.cpp", + "${data_object_base_path}/frameworks/innerkitsimpl/src/object_callback_stub.cpp", + "${data_object_base_path}/frameworks/innerkitsimpl/src/object_service_proxy.cpp", + "${data_object_base_path}/frameworks/innerkitsimpl/src/object_types_util.cpp", + "${data_object_base_path}/frameworks/innerkitsimpl/test/unittest/src/object_callback_stub_test.cpp", + ] + + cflags_cc = [ "-DHILOG_ENABLE" ] + + configs = [ ":module_private_config" ] + + external_deps = common_external_deps + + defines = [ + "private = public", + "protected = public", + ] + deps = [ "${data_object_base_path}/interfaces/innerkits:distributeddataobject_static" ] +} + +ohos_unittest("AssetChangeTimerTest") { + module_out_path = module_output_path + + sources = [ + "${data_object_base_path}/frameworks/innerkitsimpl/src/adaptor/asset_change_timer.cpp", + "${data_object_base_path}/frameworks/innerkitsimpl/src/adaptor/client_adaptor.cpp", + "${data_object_base_path}/frameworks/innerkitsimpl/src/adaptor/flat_object_store.cpp", + "${data_object_base_path}/frameworks/innerkitsimpl/src/object_service_proxy.cpp", + "${data_object_base_path}/frameworks/innerkitsimpl/src/object_types_util.cpp", + "${data_object_base_path}/frameworks/innerkitsimpl/test/unittest/src/asset_change_timer_test.cpp", + "${data_object_base_path}/frameworks/jskitsimpl/src/adaptor/js_watcher.cpp", + "${data_object_base_path}/frameworks/jskitsimpl/src/adaptor/notifier_impl.cpp", + "${data_object_base_path}/frameworks/jskitsimpl/src/common/js_util.cpp", + "${data_object_base_path}/frameworks/jskitsimpl/src/common/uv_queue.cpp", + ] + + cflags_cc = [ "-DHILOG_ENABLE" ] + + configs = [ ":module_private_config" ] + + external_deps = common_external_deps + + defines = [ + "private = public", + "protected = public", + ] + deps = [ "${data_object_base_path}/interfaces/innerkits:distributeddataobject_static" ] +} + +ohos_unittest("ClientAdaptorTest") { + module_out_path = module_output_path + + sources = [ + "${data_object_base_path}/frameworks/innerkitsimpl/src/adaptor/client_adaptor.cpp", + "${data_object_base_path}/frameworks/innerkitsimpl/src/object_service_proxy.cpp", + "${data_object_base_path}/frameworks/innerkitsimpl/src/object_types_util.cpp", + "${data_object_base_path}/frameworks/innerkitsimpl/test/unittest/src/client_adaptor_test.cpp", + ] + + cflags_cc = [ "-DHILOG_ENABLE" ] + + configs = [ ":module_private_config" ] + + external_deps = common_external_deps + + defines = [ + "private = public", + "protected = public", + ] + deps = [ "${data_object_base_path}/interfaces/innerkits:distributeddataobject_static" ] +} + +ohos_unittest("DistributedObjectStoreImplTest") { + module_out_path = module_output_path + + sources = [ + "${data_object_base_path}/frameworks/innerkitsimpl/src/adaptor/distributed_object_store_impl.cpp", + "${data_object_base_path}/frameworks/innerkitsimpl/src/adaptor/flat_object_storage_engine.cpp", + "${data_object_base_path}/frameworks/innerkitsimpl/test/unittest/src/distributed_object_store_impl_test.cpp", + ] + + cflags_cc = [ "-DHILOG_ENABLE" ] + + configs = [ ":module_private_config" ] + + external_deps = common_external_deps + + defines = [ + "private = public", + "protected = public", + ] +} + +ohos_unittest("FlatObjectStoreTest") { + module_out_path = module_output_path + + sources = [ + "${data_object_base_path}/frameworks/innerkitsimpl/src/adaptor/flat_object_storage_engine.cpp", + "${data_object_base_path}/frameworks/innerkitsimpl/src/adaptor/flat_object_store.cpp", + "${data_object_base_path}/frameworks/innerkitsimpl/test/unittest/src/flat_object_store_test.cpp", + ] + + cflags_cc = [ "-DHILOG_ENABLE" ] + + configs = [ ":module_private_config" ] + + external_deps = common_external_deps + + defines = [ + "private = public", + "protected = public", + ] + deps = [ "${data_object_base_path}/interfaces/innerkits:distributeddataobject_static" ] +} + +ohos_unittest("DistributedObjectImplTest") { + module_out_path = module_output_path + + sources = [ + "${data_object_base_path}/frameworks/innerkitsimpl/src/adaptor/distributed_object_impl.cpp", + "${data_object_base_path}/frameworks/innerkitsimpl/test/unittest/src/distributed_object_impl_test.cpp", + ] + + cflags_cc = [ "-DHILOG_ENABLE" ] + + configs = [ ":module_private_config" ] + + external_deps = common_external_deps + + defines = [ + "private = public", + "protected = public", + ] + deps = [ "${data_object_base_path}/interfaces/innerkits:distributeddataobject_static" ] +} + +ohos_unittest("AppDeviceHandlerTest") { + module_out_path = module_output_path + + sources = [ + "${data_object_base_path}/frameworks/innerkitsimpl/src/communicator/app_device_handler.cpp", + "${data_object_base_path}/frameworks/innerkitsimpl/test/unittest/src/app_device_handler_test.cpp", + ] + + cflags_cc = [ "-DHILOG_ENABLE" ] + + configs = [ ":module_private_config" ] + + external_deps = common_external_deps + + defines = [ + "private = public", + "protected = public", + ] + deps = [ "${data_object_base_path}/interfaces/innerkits:distributeddataobject_static" ] +} + group("unittest") { testonly = true - deps = [ ":NativeObjectStoreTest" ] + deps = [] + deps += [ + ":AppDeviceHandlerTest", + ":AssetChangeTimerTest", + ":ClientAdaptorTest", + ":DistributedObjectImplTest", + ":DistributedObjectStoreImplTest", + ":FlatObjectStoreTest", + ":NativeObjectStoreTest", + ":ObjectCallbackStubTest", + ":ObjectServiceProxyTest", + ":ObjectTypesUtilTest", + ] } diff --git a/data_object/frameworks/innerkitsimpl/test/unittest/src/app_device_handler_test.cpp b/data_object/frameworks/innerkitsimpl/test/unittest/src/app_device_handler_test.cpp new file mode 100644 index 00000000..41d0e6ec --- /dev/null +++ b/data_object/frameworks/innerkitsimpl/test/unittest/src/app_device_handler_test.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 +#include + +#include "app_device_handler.h" +#include "app_types.h" + +using namespace testing::ext; +using namespace OHOS::ObjectStore; +using namespace OHOS; +using namespace std; +using namespace testing; + +namespace { +class AppDeviceHandlerTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void AppDeviceHandlerTest::SetUpTestCase(void) +{ + // input testsuit setup step,setup invoked before all testcases +} + +void AppDeviceHandlerTest::TearDownTestCase(void) +{ + // input testsuit teardown step,teardown invoked after all testcases +} + +void AppDeviceHandlerTest::SetUp(void) +{ + // input testcase setup step,setup invoked before each testcases +} + +void AppDeviceHandlerTest::TearDown(void) +{ + // input testcase teardown step,teardown invoked after each testcases +} + +/** + * @tc.name: GetLocalBasicInfo_001 + * @tc.desc: Normal test for GetLocalBasicInfo + * @tc.type: FUNC + */ + +HWTEST_F(AppDeviceHandlerTest, GetLocalBasicInfo_001, TestSize.Level1) +{ + AppDeviceHandler appDeviceHandler; + appDeviceHandler.softbusAdapter_ = std::make_shared(); + ObjectStore::DeviceInfo ret = appDeviceHandler.GetLocalBasicInfo(); + auto ret2 = appDeviceHandler.softbusAdapter_->GetLocalBasicInfo(); + EXPECT_EQ(ret.deviceId, ret2.deviceId); + EXPECT_EQ(ret.deviceName, ret2.deviceName); + EXPECT_EQ(ret.deviceType, ret2.deviceType); +} + +/** + * @tc.name: GetRemoteNodesBasicInfo_001 + * @tc.desc: Normal test for GetRemoteNodesBasicInfo + * @tc.type: FUNC + */ + +HWTEST_F(AppDeviceHandlerTest, GetRemoteNodesBasicInfo_001, TestSize.Level1) +{ + AppDeviceHandler appDeviceHandler; + appDeviceHandler.softbusAdapter_ = std::make_shared(); + std::vector ret = appDeviceHandler.GetRemoteNodesBasicInfo(); + auto ret2 = appDeviceHandler.softbusAdapter_->GetRemoteNodesBasicInfo(); + EXPECT_TRUE(ret.size() == ret2.size()); +} + +/** + * @tc.name: GetUuidByNodeId_001 + * @tc.desc: Normal test for GetUuidByNodeId + * @tc.type: FUNC + */ + +HWTEST_F(AppDeviceHandlerTest, GetUuidByNodeId_001, TestSize.Level1) +{ + std::string nodeId = "123"; + AppDeviceHandler appDeviceHandler; + appDeviceHandler.devManager_ = DevManager::GetInstance(); + std::string ret = appDeviceHandler.GetUuidByNodeId(nodeId); + EXPECT_EQ(ret, appDeviceHandler.devManager_->GetUuidByNodeId(nodeId)); +} +} diff --git a/data_object/frameworks/innerkitsimpl/test/unittest/src/asset_change_timer_test.cpp b/data_object/frameworks/innerkitsimpl/test/unittest/src/asset_change_timer_test.cpp new file mode 100644 index 00000000..7453ac4f --- /dev/null +++ b/data_object/frameworks/innerkitsimpl/test/unittest/src/asset_change_timer_test.cpp @@ -0,0 +1,184 @@ +/* + * 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 "asset_change_timer.h" + +#include "client_adaptor.h" +#include "logger.h" +#include "objectstore_errors.h" +#include "js_watcher.h" +#include "distributed_objectstore_impl.h" +#include "app_types.h" +#include "flat_object_storage_engine.h" +#include "distributed_object_impl.h" + +using namespace testing::ext; +using namespace OHOS::ObjectStore; +using namespace OHOS; +using namespace std; + +namespace { +class AssetChangeTimerTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void AssetChangeTimerTest::SetUpTestCase(void) +{ + // input testsuit setup step,setup invoked before all testcases +} + +void AssetChangeTimerTest::TearDownTestCase(void) +{ + // input testsuit teardown step,teardown invoked after all testcases +} + +void AssetChangeTimerTest::SetUp(void) +{ + // input testcase setup step,setup invoked before each testcases +} + +void AssetChangeTimerTest::TearDown(void) +{ + // input testcase teardown step,teardown invoked after each testcases +} + +/** + * @tc.name: StartTimer_001 + * @tc.desc: Normal test for StartTimer + * @tc.type: FUNC + */ + +HWTEST_F(AssetChangeTimerTest, StartTimer_001, TestSize.Level1) +{ + string sessionId = "sessionId1"; + string assetKey = "assetKey1"; + std::weak_ptr watcher; + const std::string bundleName = "bundleName"; + std::shared_ptr watcherImpl = std::make_shared(watcher); + FlatObjectStore *flatObjectStore = nullptr; + AssetChangeTimer assetChangeTimer(flatObjectStore); + assetChangeTimer.StartTimer(sessionId, assetKey, watcherImpl); + EXPECT_EQ(assetChangeTimer.assetChangeTasks_[sessionId + assetChangeTimer.ASSET_SEPARATOR + assetKey], + assetChangeTimer.executor_->Reset(assetChangeTimer.assetChangeTasks_[sessionId + + assetChangeTimer.ASSET_SEPARATOR + assetKey], std::chrono::milliseconds(assetChangeTimer.WAIT_INTERVAL))); +} + +/** + * @tc.name: StopTimer_001 + * @tc.desc: Normal test for StopTimer + * @tc.type: FUNC + */ + +HWTEST_F(AssetChangeTimerTest, StopTimer_001, TestSize.Level1) +{ + string sessionId = "sessionId2"; + string assetKey = "assetKey2"; + FlatObjectStore *flatObjectStore = nullptr; + AssetChangeTimer assetChangeTimer(flatObjectStore); + std::shared_ptr executor_ = std::make_shared(2, 3); + assetChangeTimer.StopTimer(sessionId, assetKey); + EXPECT_TRUE(assetChangeTimer.assetChangeTasks_.empty()); +} + +/** + * @tc.name: GetInstance_001 + * @tc.desc: Normal test for GetInstance + * @tc.type: FUNC + */ + +HWTEST_F(AssetChangeTimerTest, GetInstance_001, TestSize.Level1) +{ + FlatObjectStore *flatObjectStore = nullptr; + AssetChangeTimer assetChangeTimer(flatObjectStore); + auto ret = assetChangeTimer.GetInstance(flatObjectStore); + EXPECT_NE(ret, nullptr); +} + +/** + * @tc.name: OnAssetChanged_001 + * @tc.desc: Normal test for OnAssetChanged + * @tc.type: FUNC + */ + +HWTEST_F(AssetChangeTimerTest, OnAssetChanged_001, TestSize.Level1) +{ + string sessionId = "sessionId1"; + string assetKey = "assetKey1"; + std::weak_ptr watcher; + const std::string bundleName = "bundleName"; + std::shared_ptr watcherImpl = std::make_shared(watcher); + FlatObjectStore *flatObjectStore = nullptr; + AssetChangeTimer assetChangeTimer(flatObjectStore); + assetChangeTimer.OnAssetChanged(sessionId, assetKey, watcherImpl); + EXPECT_EQ(assetChangeTimer.assetChangeTasks_[sessionId + assetChangeTimer.ASSET_SEPARATOR + assetKey], + assetChangeTimer.executor_->Reset(assetChangeTimer.assetChangeTasks_[sessionId + + assetChangeTimer.ASSET_SEPARATOR + assetKey], std::chrono::milliseconds(assetChangeTimer.WAIT_INTERVAL))); +} + +/** + * @tc.name: HandleAssetChanges_001 + * @tc.desc: Abnormal test for HandleAssetChanges, no sessionid is stored in delegates_ + * @tc.type: FUNC + */ + +HWTEST_F(AssetChangeTimerTest, HandleAssetChanges_001, TestSize.Level1) +{ + string sessionId = "sessionId1"; + string assetKey = "assetKey1"; + std::string bundleName = "default"; + FlatObjectStore *flatObjectStore = new FlatObjectStore(bundleName); + AssetChangeTimer assetChangeTimer(flatObjectStore); + uint32_t ret = assetChangeTimer.HandleAssetChanges(sessionId, assetKey); + EXPECT_EQ(ret, ERR_DB_GET_FAIL); + delete flatObjectStore; +} + +/** + * @tc.name: GetAssetValue_001 + * @tc.desc: Abnormal test for GetAssetValue, no sessionid is stored in delegates_ + * @tc.type: FUNC + */ + +HWTEST_F(AssetChangeTimerTest, GetAssetValue_001, TestSize.Level1) +{ + string sessionId = "sessionId1"; + string assetKey = "assetKey1"; + Asset assetValue = { + .version = 0, + .status = 0, + .id = "id", + .name = "1.txt", + .uri = "file://com.example.myapp/data/dir/1.txt", + .createTime = "2024/10/26 19:48:00", + .modifyTime = "2024/10/26 20:10:00", + .size = "1", + .hash = "hash", + .path = "/dir/1.txt", + }; + std::string bundleName = "default"; + FlatObjectStore *flatObjectStore = new FlatObjectStore(bundleName); + AssetChangeTimer assetChangeTimer(flatObjectStore); + uint32_t ret = assetChangeTimer.GetAssetValue(sessionId, assetKey, assetValue); + EXPECT_FALSE(ret); + delete flatObjectStore; +} +} diff --git a/data_object/frameworks/innerkitsimpl/test/unittest/src/client_adaptor_test.cpp b/data_object/frameworks/innerkitsimpl/test/unittest/src/client_adaptor_test.cpp new file mode 100644 index 00000000..db0b1a06 --- /dev/null +++ b/data_object/frameworks/innerkitsimpl/test/unittest/src/client_adaptor_test.cpp @@ -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. + */ + +#include +#include + +#include +#include "client_adaptor.h" +#include "iservice_registry.h" +#include "itypes_util.h" +#include "logger.h" +#include "objectstore_errors.h" + +using namespace testing::ext; +using namespace OHOS::ObjectStore; +using namespace OHOS; +using namespace std; + +namespace { +class ClientAdaptorTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void ClientAdaptorTest::SetUpTestCase(void) +{ + // input testsuit setup step,setup invoked before all testcases +} + +void ClientAdaptorTest::TearDownTestCase(void) +{ + // input testsuit teardown step,teardown invoked after all testcases +} + +void ClientAdaptorTest::SetUp(void) +{ + // input testcase setup step,setup invoked before each testcases +} + +void ClientAdaptorTest::TearDown(void) +{ + // input testcase teardown step,teardown invoked after each testcases +} + +/** + * @tc.name: OnRemoteDied_001 + * @tc.desc: Normal test for OnRemoteDied + * @tc.type: FUNC + */ + +HWTEST_F(ClientAdaptorTest, OnRemoteDied_001, TestSize.Level1) +{ + ClientAdaptor clientAdaptor; + sptr impl = nullptr; + clientAdaptor.distributedDataMgr_ = std::make_shared(impl); + wptr remote = nullptr; + ClientAdaptor::ServiceDeathRecipient serviceDeathRecipient; + serviceDeathRecipient.OnRemoteDied(remote); + EXPECT_EQ(clientAdaptor.distributedDataMgr_, nullptr); +} + +/** + * @tc.name: RegisterClientDeathListener_001 + * @tc.desc: Abnormal test for RegisterClientDeathListener, remoteObject is nullptr + * @tc.type: FUNC + */ + +HWTEST_F(ClientAdaptorTest, RegisterClientDeathListener_001, TestSize.Level1) +{ + ClientAdaptor clientAdaptor; + sptr impl = nullptr; + clientAdaptor.distributedDataMgr_ = nullptr; + std::string appId = "123"; + sptr remoteObject = nullptr; + uint32_t ret = clientAdaptor.RegisterClientDeathListener(appId, remoteObject); + EXPECT_EQ(ret, ERR_EXIST); +} + +/** + * @tc.name: RegisterClientDeathListener_002 + * @tc.desc: Normal test for RegisterClientDeathListener + * @tc.type: FUNC + */ + +HWTEST_F(ClientAdaptorTest, RegisterClientDeathListener_002, TestSize.Level1) +{ + ClientAdaptor clientAdaptor; + sptr impl = nullptr; + clientAdaptor.distributedDataMgr_ = nullptr; + std::string appId = "123"; + sptr remoteObject = new IPCObjectStub(); + uint32_t ret = clientAdaptor.RegisterClientDeathListener(appId, remoteObject); + EXPECT_EQ(ret, SUCCESS); + delete remoteObject; +} +} diff --git a/data_object/frameworks/innerkitsimpl/test/unittest/src/distributed_object_impl_test.cpp b/data_object/frameworks/innerkitsimpl/test/unittest/src/distributed_object_impl_test.cpp new file mode 100644 index 00000000..93f4c8f1 --- /dev/null +++ b/data_object/frameworks/innerkitsimpl/test/unittest/src/distributed_object_impl_test.cpp @@ -0,0 +1,89 @@ +/* + * 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 "distributed_object_impl.h" + +#include "hitrace.h" +#include "objectstore_errors.h" +#include "string_utils.h" +#include "dev_manager.h" +#include "bytes_utils.h" +#include "object_radar_reporter.h" + +using namespace testing::ext; +using namespace OHOS::ObjectStore; +using namespace OHOS; +using namespace std; + +namespace { +class DistributedObjectImplTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void DistributedObjectImplTest::SetUpTestCase(void) +{ + // input testsuit setup step,setup invoked before all testcases +} + +void DistributedObjectImplTest::TearDownTestCase(void) +{ + // input testsuit teardown step,teardown invoked after all testcases +} + +void DistributedObjectImplTest::SetUp(void) +{ + // input testcase setup step,setup invoked before each testcases +} + +void DistributedObjectImplTest::TearDown(void) +{ + // input testcase teardown step,teardown invoked after each testcases +} + +/** + * @tc.name: BindAssetStore_001 + * @tc.desc: Abnormal test for BindAssetStore, data is not stored + * @tc.type: FUNC + */ + +HWTEST_F(DistributedObjectImplTest, BindAssetStore_001, TestSize.Level1) +{ + string assetKey = "assetKey"; + string sessionId = "123"; + AssetBindInfo bindInfo = { + .storeName = "storeName", + .tableName = "tableName", + .primaryKey = { + {"data1", 123}, + {"data2", "test1"} + }, + .field = "field", + .assetName = "assetName" + }; + std::string bundleName = "default"; + FlatObjectStore *flatObjectStore = new FlatObjectStore(bundleName); + DistributedObjectImpl distributedObjectImpl(bundleName, flatObjectStore); + uint32_t ret = distributedObjectImpl.BindAssetStore(assetKey, bindInfo); + EXPECT_NE(ret, SUCCESS); + delete flatObjectStore; +} +} \ No newline at end of file diff --git a/data_object/frameworks/innerkitsimpl/test/unittest/src/distributed_object_store_impl_test.cpp b/data_object/frameworks/innerkitsimpl/test/unittest/src/distributed_object_store_impl_test.cpp new file mode 100644 index 00000000..6d2791d3 --- /dev/null +++ b/data_object/frameworks/innerkitsimpl/test/unittest/src/distributed_object_store_impl_test.cpp @@ -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. + */ + +#include +#include + +#include +#include + +#include "hitrace.h" +#include "distributed_object_impl.h" +#include "distributed_objectstore_impl.h" +#include "objectstore_errors.h" +#include "softbus_adapter.h" +#include "string_utils.h" +#include "asset_change_timer.h" +#include "object_radar_reporter.h" +#include "mock_object_watcher.h" + +using namespace testing::ext; +using namespace OHOS::ObjectStore; +using namespace OHOS; +using namespace std; + +namespace { +class DistributedObjectStoreImplTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void DistributedObjectStoreImplTest::SetUpTestCase(void) +{ + // input testsuit setup step,setup invoked before all testcases +} + +void DistributedObjectStoreImplTest::TearDownTestCase(void) +{ + // input testsuit teardown step,teardown invoked after all testcases +} + +void DistributedObjectStoreImplTest::SetUp(void) +{ + // input testcase setup step,setup invoked before each testcases +} + +void DistributedObjectStoreImplTest::TearDown(void) +{ + // input testcase teardown step,teardown invoked after each testcases +} + +/** + * @tc.name: OnChanged_001 + * @tc.desc: Normal test for OnChanged + * @tc.type: FUNC + */ + +HWTEST_F(DistributedObjectStoreImplTest, OnChanged_001, TestSize.Level1) +{ + string sessionId = "sessionId"; + std::vector changedData = {}; + bool enableTransfer = false; + std::shared_ptr objectWatcher = std::make_shared(); + WatcherProxy watcherProxy(objectWatcher, sessionId); + watcherProxy.objectWatcher_ = nullptr; + watcherProxy.OnChanged(sessionId, changedData, enableTransfer); + EXPECT_EQ(watcherProxy.objectWatcher_, nullptr); +} + +/** + * @tc.name: FindChangedAssetKey_001 + * @tc.desc: Abnormal test for FindChangedAssetKey, changedKey.size() is less than MODIFY_TIME_SUFFIX + * @tc.type: FUNC + */ + +HWTEST_F(DistributedObjectStoreImplTest, FindChangedAssetKey_001, TestSize.Level1) +{ + string changedKey = "sessionId."; + string assetKey = "assetKey"; + std::shared_ptr objectWatcher = std::make_shared(); + WatcherProxy watcherProxy(objectWatcher, changedKey); + bool ret = watcherProxy.FindChangedAssetKey(changedKey, assetKey); + EXPECT_EQ(ret, false); +} +} diff --git a/data_object/frameworks/innerkitsimpl/test/unittest/src/flat_object_store_test.cpp b/data_object/frameworks/innerkitsimpl/test/unittest/src/flat_object_store_test.cpp new file mode 100644 index 00000000..105d96f8 --- /dev/null +++ b/data_object/frameworks/innerkitsimpl/test/unittest/src/flat_object_store_test.cpp @@ -0,0 +1,122 @@ +/* + * 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 "flat_object_store.h" + +#include "accesstoken_kit.h" +#include "block_data.h" +#include "bytes_utils.h" +#include "client_adaptor.h" +#include "distributed_objectstore_impl.h" +#include "ipc_skeleton.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" +#include "string_utils.h" + +#define OMIT_MULTI_VER + +using namespace testing::ext; +using namespace OHOS::ObjectStore; +using namespace OHOS; +using namespace std; + +namespace { +class FlatObjectStoreTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void FlatObjectStoreTest::SetUpTestCase(void) +{ + // input testsuit setup step,setup invoked before all testcases +} + +void FlatObjectStoreTest::TearDownTestCase(void) +{ + // input testsuit teardown step,teardown invoked after all testcases +} + +void FlatObjectStoreTest::SetUp(void) +{ + // input testcase setup step,setup invoked before each testcases +} + +void FlatObjectStoreTest::TearDown(void) +{ + // input testcase teardown step,teardown invoked after each testcases +} + +/** + * @tc.name: BindAssetStore_001 + * @tc.desc: Abnormal test for BindAssetStore, data is not stored + * @tc.type: FUNC + */ + +HWTEST_F(FlatObjectStoreTest, BindAssetStore_001, TestSize.Level1) +{ + string sessionId = "123"; + AssetBindInfo bindInfo = { + .storeName = "storeName", + .tableName = "tableName", + .primaryKey = { + {"data1", 123}, + {"data2", "test1"} + }, + .field = "field", + .assetName = "assetName" + }; + Asset assetValue = { + .version = 0, + .status = 0, + .id = "id", + .name = "1.txt", + .uri = "file://com.example.myapp/data/dir/1.txt", + .createTime = "2024/10/26 19:48:00", + .modifyTime = "2024/10/26 20:10:00", + .size = "1", + .hash = "hash", + .path = "/dir/1.txt", + }; + std::string bundleName = "default"; + FlatObjectStore flatObjectStore = FlatObjectStore(bundleName); + uint32_t ret = flatObjectStore.BindAssetStore(sessionId, bindInfo, assetValue); + EXPECT_NE(ret, SUCCESS); +} + +/** + * @tc.name: GetBundleName_001 + * @tc.desc: Normal test for GetBundleName + * @tc.type: FUNC + */ + +HWTEST_F(FlatObjectStoreTest, GetBundleName_001, TestSize.Level1) +{ + std::string bundleName = "default"; + FlatObjectStore flatObjectStore = FlatObjectStore(bundleName); + flatObjectStore.bundleName_ = bundleName; + std::string ret = flatObjectStore.GetBundleName(); + EXPECT_EQ(ret, bundleName); +} +} diff --git a/data_object/frameworks/innerkitsimpl/test/unittest/src/object_callback_stub_test.cpp b/data_object/frameworks/innerkitsimpl/test/unittest/src/object_callback_stub_test.cpp new file mode 100644 index 00000000..548ce8fd --- /dev/null +++ b/data_object/frameworks/innerkitsimpl/test/unittest/src/object_callback_stub_test.cpp @@ -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. + */ + +#include + +#include "object_service_proxy.h" +#include "object_callback_impl.h" +#include "object_callback_stub.h" +#include +#include +#include "itypes_util.h" +#include "log_print.h" + +using namespace testing::ext; +using namespace OHOS::DistributedObject; +using namespace OHOS::ObjectStore; +using namespace std; + +namespace { +class ObjectCallbackStubTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void ObjectCallbackStubTest::SetUpTestCase(void) +{ + // input testsuit setup step,setup invoked before all testcases +} + +void ObjectCallbackStubTest::TearDownTestCase(void) +{ + // input testsuit teardown step,teardown invoked after all testcases +} + +void ObjectCallbackStubTest::SetUp(void) +{ + // input testcase setup step,setup invoked before each testcases +} + +void ObjectCallbackStubTest::TearDown(void) +{ + // input testcase teardown step,teardown invoked after each testcases +} + +/** + * @tc.name: OnRemoteRequest_001 + * @tc.desc: Abnormal test for OnRemoteRequest, code is 0 + * @tc.type: FUNC + */ + +HWTEST_F(ObjectCallbackStubTest, OnRemoteRequest_001, TestSize.Level1) +{ + uint32_t code = 0; + OHOS::MessageParcel data; + OHOS::MessageParcel reply; + OHOS::MessageOption option; + const std::function> &, bool)> callback; + ObjectChangeCallback objectChangeCallback(callback); + OHOS::IPCObjectStub objectStub; + int ret = objectChangeCallback.OnRemoteRequest(code, data, reply, option); + EXPECT_EQ(ret, -1); +} +} diff --git a/data_object/frameworks/innerkitsimpl/test/unittest/src/object_service_proxy_test.cpp b/data_object/frameworks/innerkitsimpl/test/unittest/src/object_service_proxy_test.cpp new file mode 100644 index 00000000..4d736b42 --- /dev/null +++ b/data_object/frameworks/innerkitsimpl/test/unittest/src/object_service_proxy_test.cpp @@ -0,0 +1,120 @@ +/* + * 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 "object_service_proxy.h" +#include "objectstore_errors.h" + +using namespace testing::ext; +using namespace OHOS::ObjectStore; +using namespace OHOS::DistributedObject; +using namespace OHOS; +using namespace std; + +namespace { +class ObjectServiceProxyTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void ObjectServiceProxyTest::SetUpTestCase(void) +{ + // input testsuit setup step,setup invoked before all testcases +} + +void ObjectServiceProxyTest::TearDownTestCase(void) +{ + // input testsuit teardown step,teardown invoked after all testcases +} + +void ObjectServiceProxyTest::SetUp(void) +{ + // input testcase setup step,setup invoked before each testcases +} + +void ObjectServiceProxyTest::TearDown(void) +{ + // input testcase teardown step,teardown invoked after each testcases +} + +/** + * @tc.name: OnAssetChanged_001 + * @tc.desc: Abnormal test for OnAssetChanged, impl is nullptr + * @tc.type: FUNC + */ +HWTEST_F(ObjectServiceProxyTest, OnAssetChanged_001, TestSize.Level1) +{ + string bundleName = "com.example.myapplication"; + string sessionId = "123456"; + string deviceId = "devideId"; + Asset assetValue = { + .version = 0, + .status = 0, + .id = "id", + .name = "1.txt", + .uri = "file://com.example.myapp/data/dir/1.txt", + .createTime = "2024/10/26 19:48:00", + .modifyTime = "2024/10/26 20:10:00", + .size = "1", + .hash = "hash", + .path = "/dir/1.txt", + }; + sptr impl; + ObjectServiceProxy objectServiceProxy(impl); + int32_t ret = objectServiceProxy.OnAssetChanged(bundleName, sessionId, deviceId, assetValue); + EXPECT_EQ(ret, OHOS::ObjectStore::ERR_IPC); +} + +/** + * @tc.name: BindAssetStore_001 + * @tc.desc: Abnormal test for BindAssetStore, impl is nullptr + * @tc.type: FUNC + */ +HWTEST_F(ObjectServiceProxyTest, BindAssetStore_001, TestSize.Level1) +{ + string bundleName = "com.example.myapplication"; + string sessionId = "123456"; + Asset asset = { + .version = 0, + .status = 0, + .id = "id", + .name = "1.txt", + .uri = "file://com.example.myapp/data/dir/1.txt", + .createTime = "2024/10/26 19:48:00", + .modifyTime = "2024/10/26 20:10:00", + .size = "1", + .hash = "hash", + .path = "/dir/1.txt", + }; + AssetBindInfo bindInfo = { + .storeName = "storeName", + .tableName = "tableName", + .primaryKey = { + {"data1", 123}, + {"data2", "test1"} + }, + .field = "field", + .assetName = "assetName" + }; + sptr impl; + ObjectServiceProxy objectServiceProxy(impl); + int32_t ret = objectServiceProxy.BindAssetStore(bundleName, sessionId, asset, bindInfo); + EXPECT_EQ(ret, OHOS::ObjectStore::ERR_IPC); +} +} diff --git a/data_object/frameworks/innerkitsimpl/test/unittest/src/object_types_util_test.cpp b/data_object/frameworks/innerkitsimpl/test/unittest/src/object_types_util_test.cpp new file mode 100644 index 00000000..2ec7cd52 --- /dev/null +++ b/data_object/frameworks/innerkitsimpl/test/unittest/src/object_types_util_test.cpp @@ -0,0 +1,148 @@ +/* + * 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 "object_types_util.h" + +using namespace testing::ext; +using namespace OHOS::ObjectStore; +using namespace OHOS; + +namespace { +class ObjectTypesUtilTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void ObjectTypesUtilTest::SetUpTestCase(void) +{ + // input testsuit setup step,setup invoked before all testcases +} + +void ObjectTypesUtilTest::TearDownTestCase(void) +{ + // input testsuit teardown step,teardown invoked after all testcases +} + +void ObjectTypesUtilTest::SetUp(void) +{ + // input testcase setup step,setup invoked before each testcases +} + +void ObjectTypesUtilTest::TearDown(void) +{ + // input testcase teardown step,teardown invoked after each testcases +} + +/** + * @tc.name: Marshalling_001 + * @tc.desc: Normal test for Marshalling + * @tc.type: FUNC + */ +HWTEST_F(ObjectTypesUtilTest, Marshalling_001, TestSize.Level1) +{ + AssetBindInfo input = { + .storeName = "storeName", + .tableName = "tableName", + .primaryKey = { + {"data1", 123}, + {"data2", "test1"} + }, + .field = "field", + .assetName = "assetName" + }; + MessageParcel data; + bool ret = ITypesUtil::Marshalling(input, data); + EXPECT_TRUE(ret); +} + +/** + * @tc.name: Unmarshalling_001 + * @tc.desc: Normal test for Unmarshalling + * @tc.type: FUNC + */ +HWTEST_F(ObjectTypesUtilTest, Unmarshalling_001, TestSize.Level1) +{ + AssetBindInfo input = { + .storeName = "storeName", + .tableName = "tableName", + .primaryKey = { + {"data1", 123}, + {"data2", "test1"} + }, + .field = "field", + .assetName = "assetName" + }; + MessageParcel data; + ITypesUtil::Marshalling(input, data); + AssetBindInfo output; + bool ret = ITypesUtil::Unmarshalling(output, data); + EXPECT_TRUE(ret); +} + +/** + * @tc.name: Marshalling_002 + * @tc.desc: Normal test for Marshalling + * @tc.type: FUNC + */ +HWTEST_F(ObjectTypesUtilTest, Marshalling_002, TestSize.Level1) +{ + Asset input = { + .version = 0, + .status = 0, + .id = "id", + .name = "1.txt", + .uri = "file://com.example.myapp/data/dir/1.txt", + .createTime = "2024/10/26 19:48:00", + .modifyTime = "2024/10/26 20:10:00", + .size = "1", + .hash = "hash", + .path = "/dir/1.txt", + }; + MessageParcel data; + bool ret = ITypesUtil::Marshalling(input, data); + EXPECT_TRUE(ret); +} + +/** + * @tc.name: Unmarshalling_002 + * @tc.desc: Normal test for Unmarshalling + * @tc.type: FUNC + */ +HWTEST_F(ObjectTypesUtilTest, Unmarshalling_002, TestSize.Level1) +{ + Asset input = { + .version = 0, + .status = 0, + .id = "id", + .name = "1.txt", + .uri = "file://com.example.myapp/data/dir/1.txt", + .createTime = "2024/10/26 19:48:00", + .modifyTime = "2024/10/26 20:10:00", + .size = "1", + .hash = "hash", + .path = "/dir/1.txt", + }; + MessageParcel data; + ITypesUtil::Marshalling(input, data); + Asset output; + bool ret = ITypesUtil::Unmarshalling(output, data); + EXPECT_TRUE(ret); +} +} diff --git a/data_share/bundle.json b/data_share/bundle.json index 701fc5e7..29b7d7c8 100644 --- a/data_share/bundle.json +++ b/data_share/bundle.json @@ -78,12 +78,24 @@ "//foundation/distributeddatamgr/data_share/interfaces/inner_api:datashare_provider", "//foundation/distributeddatamgr/data_share/interfaces/inner_api/common:datashare_common", "//foundation/distributeddatamgr/data_share/interfaces/inner_api:datashare_ext_ability_module", - "//foundation/distributeddatamgr/data_share/frameworks/js/napi:datashare_napi_packages" + "//foundation/distributeddatamgr/data_share/frameworks/js/napi:datashare_napi_packages", + "//foundation/distributeddatamgr/data_share/frameworks/cj/ffi:datashare_cj_ffi_packages" ], "service_group": [ ] }, "inner_api": [ + { + "name": "//foundation/distributeddatamgr/data_share/frameworks/cj/ffi/data_share_predicates:cj_data_share_predicates_ffi", + "header": { + "header_files": [ + "data_share_predicates_ffi.h", + "data_share_predicates_impl.h", + "data_share_predicates_utils.h" + ], + "header_base": "//foundation/distributeddatamgr/data_share/frameworks/cj/ffi/data_share_predicates/include" + } + }, { "name": "//foundation/distributeddatamgr/data_share/interfaces/inner_api:datashare_consumer", "header": { diff --git a/data_share/datashare.gni b/data_share/datashare.gni index c8f388e7..c825769d 100644 --- a/data_share/datashare.gni +++ b/data_share/datashare.gni @@ -19,6 +19,8 @@ datashare_common_napi_path = "${datashare_base_path}/frameworks/js/napi/common" datashare_napi_path = "${datashare_base_path}/frameworks/js/napi" +datashare_cj_ffi_path = "${datashare_base_path}/frameworks/cj/ffi" + datashare_innerapi_path = "${datashare_base_path}/interfaces/inner_api" datashare_native_provider_path = diff --git a/data_share/frameworks/cj/ffi/BUILD.gn b/data_share/frameworks/cj/ffi/BUILD.gn new file mode 100644 index 00000000..3f93885b --- /dev/null +++ b/data_share/frameworks/cj/ffi/BUILD.gn @@ -0,0 +1,19 @@ +# 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/data_share/datashare.gni") + +group("datashare_cj_ffi_packages") { + deps = [ "${datashare_cj_ffi_path}/data_share_predicates:cj_data_share_predicates_ffi" ] +} diff --git a/data_share/frameworks/cj/ffi/data_share_predicates/BUILD.gn b/data_share/frameworks/cj/ffi/data_share_predicates/BUILD.gn new file mode 100644 index 00000000..718abfce --- /dev/null +++ b/data_share/frameworks/cj/ffi/data_share_predicates/BUILD.gn @@ -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. + +import("//build/ohos.gni") +import("//foundation/distributeddatamgr/data_share/datashare.gni") + +config("public_ffi_config") { + include_dirs = [ "include" ] + cflags_cc = [ "-std=c++17" ] +} + +ohos_shared_library("cj_data_share_predicates_ffi") { + branch_protector_ret = "pac_ret" + + include_dirs = [] + + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + boundary_sanitize = true + integer_overflow = true + ubsan = true + } + + public_configs = [ ":public_ffi_config" ] + + sources = [ + "src/data_share_predicates_ffi.cpp", + "src/data_share_predicates_impl.cpp", + "src/data_share_predicates_utils.cpp", + ] + + deps = [ "${datashare_innerapi_path}/common:datashare_common" ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "napi:ace_napi", + "napi:cj_bind_ffi", + "napi:cj_bind_native", + "relational_store:native_rdb", + ] + + innerapi_tags = [ "platformsdk" ] + + subsystem_name = "distributeddatamgr" + part_name = "data_share" +} diff --git a/data_share/frameworks/cj/ffi/data_share_predicates/include/data_share_predicates_ffi.h b/data_share/frameworks/cj/ffi/data_share_predicates/include/data_share_predicates_ffi.h new file mode 100644 index 00000000..c64b04a8 --- /dev/null +++ b/data_share/frameworks/cj/ffi/data_share_predicates/include/data_share_predicates_ffi.h @@ -0,0 +1,58 @@ +/* + * 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 DATA_SHARE_PREDICATES_FFI_H +#define DATA_SHARE_PREDICATES_FFI_H + +#include "data_share_predicates_utils.h" +#include "ffi_remote_data.h" + +namespace OHOS { +namespace DataShare { +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +FFI_EXPORT int64_t FfiOHOSDataSharePredicatesCreateDataSharePredicates(); + +FFI_EXPORT int32_t FfiOHOSDataSharePredicatesEqualTo(int64_t id, const char *field, CValueType value); + +FFI_EXPORT int32_t FfiOHOSDataSharePredicatesAnd(int64_t id); + +FFI_EXPORT int32_t FfiOHOSDataSharePredicatesOrderByAsc(int64_t id, const char *field); + +FFI_EXPORT int32_t FfiOHOSDataSharePredicatesOrderByDesc(int64_t id, const char *field); + +FFI_EXPORT int32_t FfiOHOSDataSharePredicatesLimit(int64_t id, const int32_t field, const int32_t value); + +FFI_EXPORT int32_t FfiOHOSDataSharePredicatesIn(int64_t id, const char *field, CValueType *values, int64_t valuesSize); + +FFI_EXPORT int32_t FfiOHOSDataSharePredicatesOr(int64_t id); + +FFI_EXPORT int32_t FfiOHOSDataSharePredicatesBeginWrap(int64_t id); + +FFI_EXPORT int32_t FfiOHOSDataSharePredicatesEndWrap(int64_t id); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif +} // namespace DataShare +} // namespace OHOS + +#endif // endif DATA_SHARE_PREDICATES_FFI_H diff --git a/data_share/frameworks/cj/ffi/data_share_predicates/include/data_share_predicates_impl.h b/data_share/frameworks/cj/ffi/data_share_predicates/include/data_share_predicates_impl.h new file mode 100644 index 00000000..e06a6640 --- /dev/null +++ b/data_share/frameworks/cj/ffi/data_share_predicates/include/data_share_predicates_impl.h @@ -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. + */ + +#ifndef DATA_SHARE_PREDICATES_IMPL_PREDICATES_H +#define DATA_SHARE_PREDICATES_IMPL_PREDICATES_H + +#include + +#include "cj_common_ffi.h" +#include "data_share_predicates_utils.h" +#include "ffi_remote_data.h" + +namespace OHOS { +namespace DataShare { + +class DataSharePredicatesImpl : public OHOS::FFI::FFIData { + DECL_TYPE(DataSharePredicatesImpl, OHOS::FFI::FFIData) +public: + explicit DataSharePredicatesImpl(); + + std::shared_ptr GetPredicates(); + + void EqualTo(const char *field, CValueType value); + + void And(); + + void OrderByAsc(const char *field); + + void OrderByDesc(const char *field); + + void Limit(const int32_t total, const int32_t offset); + + void In(const char *field, CValueType *values, int64_t valuesSize); + + void Or(); + + void BeginWrap(); + + void EndWrap(); + +private: + std::shared_ptr predicates_; +}; +} // namespace DataShare +} // namespace OHOS + +#endif // endif DATA_SHARE_PREDICATES_IMPL_H diff --git a/kv_store/interfaces/innerkits/distributeddata/include/active_boottime.h b/data_share/frameworks/cj/ffi/data_share_predicates/include/data_share_predicates_utils.h similarity index 40% rename from kv_store/interfaces/innerkits/distributeddata/include/active_boottime.h rename to data_share/frameworks/cj/ffi/data_share_predicates/include/data_share_predicates_utils.h index 2e52e8bc..4a511071 100644 --- a/kv_store/interfaces/innerkits/distributeddata/include/active_boottime.h +++ b/data_share/frameworks/cj/ffi/data_share_predicates/include/data_share_predicates_utils.h @@ -1,5 +1,5 @@ /* - * 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 @@ -13,35 +13,29 @@ * limitations under the License. */ -#ifndef OHOS_DISTRIBUTED_DATA_FRAMEWORKS_COMMON_ACTIVE_BOOTTIME_H -#define OHOS_DISTRIBUTED_DATA_FRAMEWORKS_COMMON_ACTIVE_BOOTTIME_H +#ifndef DATA_SHARE_PREDICATES_UTILS_H +#define DATA_SHARE_PREDICATES_UTILS_H -#if __linux__ -#include -#endif -#include +#include +#include -namespace OHOS { -class Boottime final { -public: - static constexpr int64_t SECONDS_TO_NANO = 1000000000; - - using NanoSec = std::chrono::nanoseconds; - using TimePoint = std::chrono::steady_clock::time_point; +#include "datashare_predicates.h" +#include "datashare_value_object.h" +#include "value_object.h" - static TimePoint Now() - { - #if __linux__ - struct timespec tv {}; - if (clock_gettime(CLOCK_BOOTTIME, &tv) < 0) { - return TimePoint(NanoSec(0)); - } - auto time = NanoSec(tv.tv_sec * SECONDS_TO_NANO + tv.tv_nsec); - return TimePoint(time); - #else - return std::chrono::steady_clock::now(); - #endif - } +namespace OHOS { +namespace DataShare { +struct CValueType { + int64_t integer; + double dou; + bool boolean; + char *string; + uint8_t tag; }; + +SingleValue::Type parseValueType(const CValueType &value); +MutliValue::Type parseValueTypeArray(const CValueType *array, int64_t size); +} // namespace DataShare } // namespace OHOS -#endif //OHOS_DISTRIBUTED_DATA_FRAMEWORKS_COMMON_ACTIVE_BOOTTIME_H + +#endif // endif DATA_SHARE_PREDICATES_UTILS_H diff --git a/data_share/frameworks/cj/ffi/data_share_predicates/src/data_share_predicates_ffi.cpp b/data_share/frameworks/cj/ffi/data_share_predicates/src/data_share_predicates_ffi.cpp new file mode 100644 index 00000000..8d9a222f --- /dev/null +++ b/data_share/frameworks/cj/ffi/data_share_predicates/src/data_share_predicates_ffi.cpp @@ -0,0 +1,133 @@ +/* + * 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 "data_share_predicates_ffi.h" +#include "data_share_predicates_impl.h" +#include "data_share_predicates_utils.h" + +using namespace OHOS::FFI; + +namespace OHOS { +namespace DataShare { +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif +int64_t FfiOHOSDataSharePredicatesCreateDataSharePredicates() +{ + auto impl = FFIData::Create(); + if (impl == nullptr) { + return -1; + } + return impl->GetID(); +} + +int32_t FfiOHOSDataSharePredicatesEqualTo(int64_t id, const char *field, CValueType value) +{ + auto impl = FFIData::GetData(id); + if (impl == nullptr) { + return -1; + } + impl->EqualTo(field, value); + return 0; +} + +int32_t FfiOHOSDataSharePredicatesAnd(int64_t id) +{ + auto impl = FFIData::GetData(id); + if (impl == nullptr) { + return -1; + } + impl->And(); + return 0; +} + +int32_t FfiOHOSDataSharePredicatesOrderByAsc(int64_t id, const char *field) +{ + auto impl = FFIData::GetData(id); + if (impl == nullptr) { + return -1; + } + impl->OrderByAsc(field); + return 0; +} + +int32_t FfiOHOSDataSharePredicatesOrderByDesc(int64_t id, const char *field) +{ + auto impl = FFIData::GetData(id); + if (impl == nullptr) { + return -1; + } + impl->OrderByDesc(field); + return 0; +} + +int32_t FfiOHOSDataSharePredicatesLimit(int64_t id, const int32_t field, const int32_t value) +{ + auto impl = FFIData::GetData(id); + if (impl == nullptr) { + return -1; + } + impl->Limit(field, value); + return 0; +} + +int32_t FfiOHOSDataSharePredicatesIn(int64_t id, const char *field, CValueType *values, int64_t valuesSize) +{ + auto impl = FFIData::GetData(id); + if (impl == nullptr) { + return -1; + } + impl->In(field, values, valuesSize); + return 0; +} + +int32_t FfiOHOSDataSharePredicatesOr(int64_t id) +{ + auto impl = FFIData::GetData(id); + if (impl == nullptr) { + return -1; + } + impl->Or(); + return 0; +} + +int32_t FfiOHOSDataSharePredicatesBeginWrap(int64_t id) +{ + auto impl = FFIData::GetData(id); + if (impl == nullptr) { + return -1; + } + impl->BeginWrap(); + return 0; +} + +int32_t FfiOHOSDataSharePredicatesEndWrap(int64_t id) +{ + auto impl = FFIData::GetData(id); + if (impl == nullptr) { + return -1; + } + impl->EndWrap(); + return 0; +} +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif +} // namespace DataShare +} // namespace OHOS diff --git a/data_share/frameworks/cj/ffi/data_share_predicates/src/data_share_predicates_impl.cpp b/data_share/frameworks/cj/ffi/data_share_predicates/src/data_share_predicates_impl.cpp new file mode 100644 index 00000000..c85d3c05 --- /dev/null +++ b/data_share/frameworks/cj/ffi/data_share_predicates/src/data_share_predicates_impl.cpp @@ -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. + */ + +#include "data_share_predicates_impl.h" + +#include "data_share_predicates_utils.h" + +namespace OHOS { +namespace DataShare { +DataSharePredicatesImpl::DataSharePredicatesImpl() +{ + predicates_ = std::make_shared(); +} + +std::shared_ptr DataSharePredicatesImpl::GetPredicates() +{ + return this->predicates_; +} + +void DataSharePredicatesImpl::EqualTo(const char *field, CValueType value) +{ + std::string cField = field; + SingleValue::Type valueObject = parseValueType(value); + predicates_->EqualTo(cField, valueObject); +} + +void DataSharePredicatesImpl::And() +{ + predicates_->And(); +} + +void DataSharePredicatesImpl::OrderByAsc(const char *field) +{ + std::string cField = field; + predicates_->OrderByAsc(cField); +} + +void DataSharePredicatesImpl::OrderByDesc(const char *field) +{ + std::string cField = field; + predicates_->OrderByDesc(cField); +} + +void DataSharePredicatesImpl::Limit(const int32_t total, const int32_t offset) +{ + predicates_->Limit(static_cast(total), static_cast(offset)); +} + +void DataSharePredicatesImpl::In(const char *field, CValueType *values, int64_t valuesSize) +{ + std::string cField = field; + auto valuesArray = parseValueTypeArray(values, valuesSize); + predicates_->In(cField, valuesArray); +} + +void DataSharePredicatesImpl::Or() +{ + predicates_->Or(); +} + +void DataSharePredicatesImpl::BeginWrap() +{ + predicates_->BeginWrap(); +} + +void DataSharePredicatesImpl::EndWrap() +{ + predicates_->EndWrap(); +} +} // namespace DataShare +} // namespace OHOS \ No newline at end of file diff --git a/data_share/frameworks/cj/ffi/data_share_predicates/src/data_share_predicates_utils.cpp b/data_share/frameworks/cj/ffi/data_share_predicates/src/data_share_predicates_utils.cpp new file mode 100644 index 00000000..a9e8cbbf --- /dev/null +++ b/data_share/frameworks/cj/ffi/data_share_predicates/src/data_share_predicates_utils.cpp @@ -0,0 +1,84 @@ +/* + * 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 "data_share_predicates_utils.h" + +namespace OHOS { +namespace DataShare { + +SingleValue::Type parseValueType(const CValueType &value) +{ + SingleValue::Type ret; + switch (static_cast(value.tag)) { + case DataShareValueObjectType::TYPE_INT: { + ret = value.integer; + break; + } + case DataShareValueObjectType::TYPE_DOUBLE: { + ret = value.dou; + break; + } + case DataShareValueObjectType::TYPE_STRING: { + ret = std::string(value.string); + break; + } + case DataShareValueObjectType::TYPE_BOOL: { + ret = value.boolean; + break; + } + default: + ret = 0; + break; + } + return ret; +} + +MutliValue::Type parseValueTypeArray(const CValueType *array, int64_t size) +{ + MutliValue::Type ret; + CValueType value = array[0]; + switch (static_cast(value.tag)) { + case DataShareValueObjectType::TYPE_INT: { + std::vector arr(size); + for (int64_t i = 0; i < size; ++i) { + arr[i] = array[i].integer; + } + ret = arr; + break; + } + case DataShareValueObjectType::TYPE_DOUBLE: { + std::vector arr(size); + for (int64_t i = 0; i < size; ++i) { + arr[i] = array[i].dou; + } + ret = arr; + break; + } + case DataShareValueObjectType::TYPE_STRING: { + std::vector arr(size); + for (int64_t i = 0; i < size; ++i) { + arr[i] = std::string(array[i].string); + } + ret = arr; + break; + } + default: + break; + } + return ret; +} + +} // namespace DataShare +} // namespace OHOS \ No newline at end of file diff --git a/data_share/frameworks/js/napi/common/src/datashare_js_utils.cpp b/data_share/frameworks/js/napi/common/src/datashare_js_utils.cpp index f55d034b..ea3d66c4 100644 --- a/data_share/frameworks/js/napi/common/src/datashare_js_utils.cpp +++ b/data_share/frameworks/js/napi/common/src/datashare_js_utils.cpp @@ -539,6 +539,12 @@ Template DataShareJSUtils::Convert2Template(napi_env env, napi_value value) LOG_ERROR("Convert2Template error, value is not object"); return {}; } + std::string update; + if (!UnwrapStringByPropertyName(env, value, "update", update)) { + LOG_INFO("Parameter update undefined"); + update = ""; + } + napi_value jsPredicates; auto status = napi_get_named_property(env, value, "predicates", &jsPredicates); if (status != napi_ok) { @@ -556,7 +562,7 @@ Template DataShareJSUtils::Convert2Template(napi_env env, napi_value value) LOG_ERROR("Convert scheduler failed"); return {}; } - Template tpl(predicates, scheduler); + Template tpl(update, predicates, scheduler); return tpl; } diff --git a/data_share/frameworks/native/common/src/datashare_itypes_utils.cpp b/data_share/frameworks/native/common/src/datashare_itypes_utils.cpp index a26d1bf5..7f66083e 100644 --- a/data_share/frameworks/native/common/src/datashare_itypes_utils.cpp +++ b/data_share/frameworks/native/common/src/datashare_itypes_utils.cpp @@ -134,13 +134,37 @@ bool Unmarshalling(PredicateTemplateNode &predicateTemplateNode, MessageParcel & template<> bool Marshalling(const RdbChangeNode &changeNode, MessageParcel &parcel) { - return ITypesUtil::Marshal(parcel, changeNode.uri_, changeNode.templateId_, changeNode.data_); + bool firstPart = ITypesUtil::Marshal( + parcel, changeNode.uri_, changeNode.templateId_, changeNode.data_, changeNode.isSharedMemory_); + if (!firstPart) { + return false; + } + if (changeNode.isSharedMemory_) { + if (changeNode.memory_ == nullptr) { + LOG_ERROR("Used shared memory but ashmem is nullptr."); + return false; + } + if (!parcel.WriteAshmem(changeNode.memory_)) { + return false; + } + } + return ITypesUtil::Marshal(parcel, changeNode.size_); } template<> bool Unmarshalling(RdbChangeNode &changeNode, MessageParcel &parcel) { - return ITypesUtil::Unmarshal(parcel, changeNode.uri_, changeNode.templateId_, changeNode.data_); + bool firstPart = ITypesUtil::Unmarshal( + parcel, changeNode.uri_, changeNode.templateId_, changeNode.data_, changeNode.isSharedMemory_); + if (!firstPart) { + return false; + } + if (changeNode.isSharedMemory_) { + changeNode.memory_ = parcel.ReadAshmem(); + } else { + changeNode.memory_ = nullptr; + } + return ITypesUtil::Unmarshal(parcel, changeNode.size_); } template<> diff --git a/data_share/frameworks/native/provider/include/js_datashare_ext_ability.h b/data_share/frameworks/native/provider/include/js_datashare_ext_ability.h index 8bc0871a..1951ed8d 100644 --- a/data_share/frameworks/native/provider/include/js_datashare_ext_ability.h +++ b/data_share/frameworks/native/provider/include/js_datashare_ext_ability.h @@ -273,53 +273,61 @@ public: void GetResult(std::string &value) { + std::lock_guard lock(asyncLock_); value = callbackResultString_; } void SetResult(const std::string value) { + std::lock_guard lock(asyncLock_); callbackResultString_ = value; } void GetResult(std::vector &value) { + std::lock_guard lock(asyncLock_); value = callbackResultStringArr_; } void SetResult(const std::vector &results) { + std::lock_guard lock(asyncLock_); updateResults_ = results; } void GetResult(std::vector &results) { + std::lock_guard lock(asyncLock_); results = updateResults_; } void SetResult(const std::vector value) { + std::lock_guard lock(asyncLock_); callbackResultStringArr_ = value; } void GetResultSet(std::shared_ptr &value) { - std::lock_guard lock(resultSetLock_); + std::lock_guard lock(asyncLock_); value = callbackResultObject_; } void SetResultSet(const std::shared_ptr value) { - std::lock_guard lock(resultSetLock_); + std::lock_guard lock(asyncLock_); callbackResultObject_ = value; } void GetBusinessError(DatashareBusinessError &businessError) { + std::lock_guard lock(asyncLock_); businessError = businessError_; } void SetBusinessError(DatashareBusinessError &businessError) { + std::lock_guard lock(asyncLock_); businessError_ = businessError; } struct AsyncContext { @@ -359,7 +367,7 @@ private: int callbackResultNumber_ = -1; std::string callbackResultString_ = ""; std::vector callbackResultStringArr_ = {}; - std::mutex resultSetLock_; + std::mutex asyncLock_; std::shared_ptr callbackResultObject_ = nullptr; DatashareBusinessError businessError_; std::vector updateResults_ = {}; diff --git a/data_share/frameworks/native/proxy/include/data_proxy_observer_stub.h b/data_share/frameworks/native/proxy/include/data_proxy_observer_stub.h index 490da4c1..9de980ae 100644 --- a/data_share/frameworks/native/proxy/include/data_proxy_observer_stub.h +++ b/data_share/frameworks/native/proxy/include/data_proxy_observer_stub.h @@ -28,9 +28,12 @@ public: RdbObserverStub(RdbCallback callback); virtual ~RdbObserverStub(); int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; - void OnChangeFromRdb(const RdbChangeNode &changeNode); + void OnChangeFromRdb(RdbChangeNode &changeNode); void ClearCallback(); private: + int RecoverRdbChangeNodeData(RdbChangeNode &changeNode); + int DeserializeDataFromAshmem(RdbChangeNode &changeNode); + int ReadAshmem(RdbChangeNode &changeNode, const void **data, int size, int &offset); std::mutex mutex_; RdbCallback callback_; }; diff --git a/data_share/frameworks/native/proxy/src/data_proxy_observer_stub.cpp b/data_share/frameworks/native/proxy/src/data_proxy_observer_stub.cpp index f5d8ee1b..d2d1981b 100644 --- a/data_share/frameworks/native/proxy/src/data_proxy_observer_stub.cpp +++ b/data_share/frameworks/native/proxy/src/data_proxy_observer_stub.cpp @@ -42,9 +42,97 @@ int RdbObserverStub::OnRemoteRequest(uint32_t code, MessageParcel &data, Message return ERR_OK; } -void RdbObserverStub::OnChangeFromRdb(const RdbChangeNode &changeNode) +int RdbObserverStub::ReadAshmem(RdbChangeNode &changeNode, const void **data, int size, int &offset) +{ + if (changeNode.memory_ == nullptr) { + LOG_ERROR("changeNode memory is nullptr."); + return E_ERROR; + } + const void *read = changeNode.memory_->ReadFromAshmem(size, offset); + if (read == nullptr) { + LOG_ERROR("failed to read from ashmem."); + changeNode.memory_->UnmapAshmem(); + changeNode.memory_->CloseAshmem(); + changeNode.memory_ = nullptr; + return E_ERROR; + } + *data = read; + offset += size; + return E_OK; +} + +int RdbObserverStub::DeserializeDataFromAshmem(RdbChangeNode &changeNode) +{ + if (changeNode.memory_ == nullptr) { + LOG_ERROR("changeNode.memory_ is null."); + return E_ERROR; + } + bool mapRet = changeNode.memory_->MapReadAndWriteAshmem(); + if (!mapRet) { + LOG_ERROR("failed to map read and write ashmem, ret=%{public}d", mapRet); + changeNode.memory_->CloseAshmem(); + changeNode.memory_ = nullptr; + return E_ERROR; + } + LOG_DEBUG("receive data size: %{public}d", changeNode.size_); + // Read data size + int intLen = 4; + int offset = 0; + const int *vecLenRead; + if (ReadAshmem(changeNode, (const void **)&vecLenRead, intLen, offset) != E_OK) { + LOG_ERROR("failed to read data with len %{public}d, offset %{public}d.", intLen, offset); + return E_ERROR; + } + int vecLen = *vecLenRead; + + // Read data + for (int i = 0; i < vecLen; i++) { + const int *dataLenRead; + if (ReadAshmem(changeNode, (const void **)&dataLenRead, intLen, offset) != E_OK) { + LOG_ERROR( + "failed to read data with index %{public}d, len %{public}d, offset %{public}d.", i, intLen, offset); + return E_ERROR; + } + int dataLen = *dataLenRead; + const char *dataRead; + if (ReadAshmem(changeNode, (const void **)&dataRead, dataLen, offset) != E_OK) { + LOG_ERROR( + "failed to read data with index %{public}d, len %{public}d, offset %{public}d.", i, dataLen, offset); + return E_ERROR; + } + std::string data(dataRead, dataLen); + changeNode.data_.push_back(data); + } + return E_OK; +} + +int RdbObserverStub::RecoverRdbChangeNodeData(RdbChangeNode &changeNode) +{ + int ret = E_OK; + if (changeNode.isSharedMemory_) { + // Recover form Ashmem + if (DeserializeDataFromAshmem(changeNode) != E_OK) { + LOG_ERROR("failed to deserialize data from ashmem."); + ret = E_ERROR; + } + if (changeNode.memory_ != nullptr) { + changeNode.memory_->UnmapAshmem(); + changeNode.memory_->CloseAshmem(); + changeNode.memory_ = nullptr; + } + changeNode.isSharedMemory_ = false; + changeNode.size_ = 0; + } + return ret; +} + +void RdbObserverStub::OnChangeFromRdb(RdbChangeNode &changeNode) { std::lock_guard lock(mutex_); + if (RecoverRdbChangeNodeData(changeNode) != E_OK) { + LOG_ERROR("failed to recover RdbChangeNode data."); + return; + } if (callback_) { callback_(changeNode); } 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 66ae66a0..eec0efbc 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 @@ -200,7 +200,12 @@ int DataShareServiceProxy::AddQueryTemplate(const std::string &uri, int64_t subs LOG_ERROR("Write descriptor failed!"); return DATA_SHARE_ERROR; } - if (!ITypesUtil::Marshal(data, uri, subscriberId, tpl.predicates_, tpl.scheduler_)) { + std::string updateSqlPrefix = "update"; + if (!tpl.update_.empty() && tpl.update_.compare(0, updateSqlPrefix.size(), updateSqlPrefix) != 0) { + LOG_ERROR("Parameter update only support update SQL"); + return DATA_SHARE_ERROR; + } + if (!ITypesUtil::Marshal(data, uri, subscriberId, tpl.update_, tpl.predicates_, tpl.scheduler_)) { LOG_ERROR("Write to message parcel failed!"); return DATA_SHARE_ERROR; } diff --git a/data_share/interfaces/inner_api/common/include/datashare_template.h b/data_share/interfaces/inner_api/common/include/datashare_template.h index 2488ede1..6f2a1fbd 100644 --- a/data_share/interfaces/inner_api/common/include/datashare_template.h +++ b/data_share/interfaces/inner_api/common/include/datashare_template.h @@ -23,6 +23,19 @@ namespace OHOS { namespace DataShare { +/** + * Specifies the upper limit of size of data that RdbChangeNode will transfer by IPC. Currently it's 200k. + */ +constexpr int32_t DATA_SIZE_IPC_TRANSFER_LIMIT = 200 << 10; +/** + * Specifies the upper limit of size of data that RdbChangeNode will transfer by the shared memory. Currently it's 10M. + */ +constexpr int32_t DATA_SIZE_ASHMEM_TRANSFER_LIMIT = (10 << 10) << 10; +/** + * Specifies the name of the shared memory that RdbChangeNode will transfer. + */ +constexpr const char* ASHMEM_NAME = "DataShareRdbChangeNode"; + /** * Specifies the predicates structure of the template. */ @@ -42,6 +55,11 @@ struct Template { Template() = default; Template(const std::vector &predicates, const std::string &scheduler) : predicates_(predicates), scheduler_(scheduler) {} + Template(const std::string &update, + const std::vector &predicates, + const std::string &scheduler) : update_(update), predicates_(predicates), scheduler_(scheduler) {} + /** Specifies the update sql of the template. */ + std::string update_; /** Specifies the predicates of the template. {@link #PredicateTemplateNode} */ std::vector predicates_; /** Specifies the scheduler sql of the template. */ @@ -147,6 +165,16 @@ struct RdbChangeNode { TemplateId templateId_; /** Specifies the datas of the callback. */ std::vector data_; + /** Specifies whether to use the shared meomry to transfer data. This will be set to be true when the size of + * the data is more than 200k, but no more than 10M. Usually the data will not be as large as 10M. + */ + bool isSharedMemory_ = false; + /** Specifies the address of the shared memory, wrapped by `OHOS::sptr`. + * (De)serialization: [vec_size(int32); str1_len(int32), str1; str2_len(int32), str2; ...] + */ + OHOS::sptr memory_; + /** Specifies the data size transferred the shared memory */ + int32_t size_; }; /** diff --git a/data_share/interfaces/inner_api/consumer/include/datashare_shared_result_set.h b/data_share/interfaces/inner_api/consumer/include/datashare_shared_result_set.h index 8335aca7..2e354d5b 100644 --- a/data_share/interfaces/inner_api/consumer/include/datashare_shared_result_set.h +++ b/data_share/interfaces/inner_api/consumer/include/datashare_shared_result_set.h @@ -26,7 +26,7 @@ namespace DataShare { class DataShareSharedResultSet { public: DataShareSharedResultSet() {} - ~DataShareSharedResultSet() {} + virtual ~DataShareSharedResultSet() {} /** * Obtains a block from the {@link SharedResultSet} */ diff --git a/data_share/test/native/BUILD.gn b/data_share/test/native/BUILD.gn index 1fc9557d..c578b827 100644 --- a/data_share/test/native/BUILD.gn +++ b/data_share/test/native/BUILD.gn @@ -52,6 +52,8 @@ config("permission_config") { ohos_unittest("NativeDataShareTest") { module_out_path = "data_share/native_datashare" + visibility = [ ":*" ] + include_dirs = [ "//foundation/ability/ability_runtime/interfaces/inner_api/ability_manager/include", "//foundation/ability/ability_runtime/interfaces/inner_api/app_manager/include/appmgr", @@ -65,10 +67,13 @@ ohos_unittest("NativeDataShareTest") { "//utils/system/safwk/native/include", "//foundation/communication/ipc/interfaces/innerkits/ipc_core/include", "//third_party/json/include", + "${datashare_native_proxy_path}/include", ] - sources = - [ "./unittest/mediadatashare_test/src/mediadatashare_unit_test.cpp" ] + sources = [ + "${datashare_native_proxy_path}/src/data_proxy_observer_stub.cpp", + "./unittest/mediadatashare_test/src/mediadatashare_unit_test.cpp", + ] deps = [ "${datashare_innerapi_path}:datashare_consumer", @@ -93,6 +98,12 @@ ohos_unittest("NativeDataShareTest") { "safwk:system_ability_fwk", "samgr:samgr_proxy", ] + + cflags = [ + "-fvisibility=hidden", + "-Dprivate=public", + "-Dprotected=public", + ] } ohos_unittest("PermissionTest") { diff --git a/data_share/test/native/unittest/mediadatashare_test/src/mediadatashare_unit_test.cpp b/data_share/test/native/unittest/mediadatashare_test/src/mediadatashare_unit_test.cpp index 2eb0d012..93ffe659 100644 --- a/data_share/test/native/unittest/mediadatashare_test/src/mediadatashare_unit_test.cpp +++ b/data_share/test/native/unittest/mediadatashare_test/src/mediadatashare_unit_test.cpp @@ -23,6 +23,7 @@ #include "dataobs_mgr_changeinfo.h" #include "datashare_log.h" #include "datashare_valuebucket_convert.h" +#include "data_proxy_observer_stub.h" #include "hap_token_info.h" #include "iservice_registry.h" #include "rdb_data_ability_utils.h" @@ -1673,5 +1674,274 @@ HWTEST_F(MediaDataShareUnitTest, MediaDataShare_BatchUpdateThanLimit_Test_001, T EXPECT_EQ(results.size(), 0); LOG_INFO("MediaDataShare_BatchUpdateThanLimit_Test_001 End"); } + +void OnChangeCallback(const RdbChangeNode &changeNode) +{ + // In test, put 2 uris into the data vec + int vecLen = 2; + EXPECT_EQ(changeNode.data_.size(), vecLen); + for (int i = 0; i < vecLen; i++) { + EXPECT_EQ(changeNode.data_[i], DATA_SHARE_URI); + } +} + +void PrepareNodeContent(RdbChangeNode &node) +{ + OHOS::sptr memory = Ashmem::CreateAshmem("PrepareNodeContent", DATA_SIZE_ASHMEM_TRANSFER_LIMIT); + EXPECT_NE(memory, nullptr); + bool mapRet = memory->MapReadAndWriteAshmem(); + ASSERT_TRUE(mapRet); + // write 2 uris + int vecLen = 2; + int intByteLen = 4; + int offset = 0; + bool writeRet = memory->WriteToAshmem((void*)&vecLen, intByteLen, offset); + ASSERT_TRUE(writeRet); + offset += intByteLen; + int len = DATA_SHARE_URI.length(); + const char *str = DATA_SHARE_URI.c_str(); + for (int i = 0; i < vecLen; i++) { + writeRet = memory->WriteToAshmem((void*)&len, intByteLen, offset); + ASSERT_TRUE(writeRet); + offset += intByteLen; + writeRet = memory->WriteToAshmem((void*)str, len, offset); + ASSERT_TRUE(writeRet); + offset += len; + } + node.memory_ = memory; + node.size_ = offset; + node.isSharedMemory_ = true; +} + +/** +* @tc.name: ReadAshmem +* @tc.desc: test ReadAshmem function. +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(MediaDataShareUnitTest, ReadAshmem, TestSize.Level1) +{ + LOG_INFO("ReadAshmem starts"); + RdbChangeNode node; + + OHOS::sptr memory = Ashmem::CreateAshmem("ReadAshmem", DATA_SIZE_ASHMEM_TRANSFER_LIMIT); + EXPECT_NE(memory, nullptr); + bool mapRet = memory->MapReadAndWriteAshmem(); + ASSERT_TRUE(mapRet); + int len = DATA_SHARE_URI.length(); + bool writeRet = memory->WriteToAshmem((void*)&len, 4, 0); + ASSERT_TRUE(writeRet); + const char *str = DATA_SHARE_URI.c_str(); + writeRet = memory->WriteToAshmem((void*)str, len, 4); + ASSERT_TRUE(writeRet); + node.memory_ = memory; + + RdbObserverStub stub(OnChangeCallback); + // Read an int + const int *lenRead; + int offset = 0; + int readRet = stub.ReadAshmem(node, (const void**)&lenRead, 4, offset); + EXPECT_EQ(readRet, E_OK); + EXPECT_EQ(offset, 4); + int lenFromAshmem = *lenRead; + EXPECT_EQ(lenFromAshmem, len); + // Read a string + readRet = stub.ReadAshmem(node, (const void**)&str, lenFromAshmem, offset); + EXPECT_EQ(readRet, E_OK); + EXPECT_EQ(offset, 4 + len); + std::string strRead(str, lenFromAshmem); + EXPECT_EQ(strRead, DATA_SHARE_URI); + + // Error path test + readRet = stub.ReadAshmem(node, (const void**)&str, DATA_SIZE_ASHMEM_TRANSFER_LIMIT, offset); + EXPECT_EQ(readRet, E_ERROR); + LOG_INFO("ReadAshmem ends"); +} + +/** +* @tc.name: DeserializeDataFromAshmem001 +* @tc.desc: test DeserializeDataFromAshmem function. +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(MediaDataShareUnitTest, DeserializeDataFromAshmem001, TestSize.Level1) +{ + LOG_INFO("DeserializeDataFromAshmem001::Start"); + RdbChangeNode node; + PrepareNodeContent(node); + + RdbObserverStub stub(OnChangeCallback); + int readRet = stub.DeserializeDataFromAshmem(node); + EXPECT_EQ(readRet, E_OK); + EXPECT_EQ(node.data_.size(), 2); + for (int i = 0; i < 2; i++) { + EXPECT_EQ(node.data_[i], DATA_SHARE_URI); + } + LOG_INFO("DeserializeDataFromAshmem001::End"); +} + +/** +* @tc.name: DeserializeDataFromAshmem002 +* @tc.desc: test DeserializeDataFromAshmem function, error tests. +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(MediaDataShareUnitTest, DeserializeDataFromAshmem002, TestSize.Level1) +{ + LOG_INFO("DeserializeDataFromAshmem002::Start"); + RdbChangeNode node; + RdbObserverStub stub(OnChangeCallback); + // memory_ is null. + int ret = stub.DeserializeDataFromAshmem(node); + EXPECT_EQ(ret, E_ERROR); + + // Error in read from Ashmem with error string length. + OHOS::sptr memory = Ashmem::CreateAshmem("DeserializeDataFromAshmem002", DATA_SIZE_ASHMEM_TRANSFER_LIMIT); + EXPECT_NE(memory, nullptr); + bool mapRet = memory->MapReadAndWriteAshmem(); + ASSERT_TRUE(mapRet); + int vecLen = 1; + int offset = 0; + bool writeRet = memory->WriteToAshmem((void*)&vecLen, 4, offset); + ASSERT_TRUE(writeRet); + offset += 4; + int len = DATA_SHARE_URI.length(); + int errorLen = DATA_SIZE_ASHMEM_TRANSFER_LIMIT; + const char *str = DATA_SHARE_URI.c_str(); + writeRet = memory->WriteToAshmem((void*)&errorLen, 4, offset); + ASSERT_TRUE(writeRet); + offset += 4; + writeRet = memory->WriteToAshmem((void*)str, len, offset); + ASSERT_TRUE(writeRet); + node.memory_ = memory; + + ret = stub.DeserializeDataFromAshmem(node); + EXPECT_EQ(ret, E_ERROR); + + // Error in read from Ashmem with vec size + OHOS::sptr memory2 = Ashmem::CreateAshmem("DeserializeDataFromAshmem002", 2); + EXPECT_NE(memory2, nullptr); + mapRet = memory2->MapReadAndWriteAshmem(); + ASSERT_TRUE(mapRet); + node.memory_ = memory2; + ret = stub.DeserializeDataFromAshmem(node); + EXPECT_EQ(ret, E_ERROR); + + // Error in read from Ashmem with str size + OHOS::sptr memory3 = Ashmem::CreateAshmem("DeserializeDataFromAshmem002", 5); + EXPECT_NE(memory3, nullptr); + mapRet = memory3->MapReadAndWriteAshmem(); + ASSERT_TRUE(mapRet); + writeRet = memory3->WriteToAshmem((void*)&vecLen, 4, 0); + ASSERT_TRUE(writeRet); + node.memory_ = memory3; + ret = stub.DeserializeDataFromAshmem(node); + EXPECT_EQ(ret, E_ERROR); + LOG_INFO("DeserializeDataFromAshmem002::End"); +} + +/** +* @tc.name: RecoverRdbChangeNodeData001 +* @tc.desc: test RecoverRdbChangeNodeData function +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(MediaDataShareUnitTest, RecoverRdbChangeNodeData001, TestSize.Level0) +{ + LOG_INFO("RecoverRdbChangeNodeData::Start"); + + // Recover + RdbChangeNode node; + PrepareNodeContent(node); + RdbObserverStub stub(OnChangeCallback); + int ret = stub.RecoverRdbChangeNodeData(node); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(node.data_.size(), 2); + for (int i = 0; i < 2; i++) { + EXPECT_EQ(node.data_[i], DATA_SHARE_URI); + } + EXPECT_EQ(node.memory_, nullptr); + EXPECT_EQ(node.size_, 0); + ASSERT_FALSE(node.isSharedMemory_); + + // Not recover + RdbChangeNode node2; + PrepareNodeContent(node2); + node2.isSharedMemory_ = false; + ret = stub.RecoverRdbChangeNodeData(node2); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(node2.data_.size(), 0); + EXPECT_NE(node2.memory_, nullptr); + EXPECT_EQ(node2.size_, 82); + ASSERT_FALSE(node2.isSharedMemory_); + + LOG_INFO("RecoverRdbChangeNodeData End"); +} + +/** +* @tc.name: RecoverRdbChangeNodeData002 +* @tc.desc: test RecoverRdbChangeNodeData function with error +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(MediaDataShareUnitTest, RecoverRdbChangeNodeData002, TestSize.Level0) +{ + LOG_INFO("RecoverRdbChangeNodeData002::Start"); + + RdbChangeNode node; + node.isSharedMemory_ = true; + RdbObserverStub stub(OnChangeCallback); + int ret = stub.RecoverRdbChangeNodeData(node); + EXPECT_EQ(ret, E_ERROR); + EXPECT_EQ(node.data_.size(), 0); + EXPECT_EQ(node.memory_, nullptr); + EXPECT_EQ(node.size_, 0); + ASSERT_FALSE(node.isSharedMemory_); + LOG_INFO("RecoverRdbChangeNodeData002::End"); +} + +/** +* @tc.name: OnChangeFromRdb001 +* @tc.desc: test OnChangeFromRdb function +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(MediaDataShareUnitTest, OnChangeFromRdb001, TestSize.Level0) +{ + LOG_INFO("OnChangeFromRdb001::Start"); + + RdbChangeNode node; + PrepareNodeContent(node); + RdbObserverStub stub(OnChangeCallback); + stub.OnChangeFromRdb(node); + EXPECT_EQ(node.data_.size(), 2); + for (int i = 0; i < 2; i++) { + EXPECT_EQ(node.data_[i], DATA_SHARE_URI); + } + EXPECT_EQ(node.memory_, nullptr); + EXPECT_EQ(node.size_, 0); + ASSERT_FALSE(node.isSharedMemory_); + LOG_INFO("OnChangeFromRdb001::End"); +} + +/** +* @tc.name: OnChangeFromRdb002 +* @tc.desc: test OnChangeFromRdb function with error +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(MediaDataShareUnitTest, OnChangeFromRdb002, TestSize.Level0) +{ + LOG_INFO("OnChangeFromRdb002::Start"); + RdbChangeNode node; + node.isSharedMemory_ = true; + RdbObserverStub stub(OnChangeCallback); + stub.OnChangeFromRdb(node); + EXPECT_EQ(node.data_.size(), 0); + EXPECT_EQ(node.memory_, nullptr); + EXPECT_EQ(node.size_, 0); + ASSERT_FALSE(node.isSharedMemory_); + LOG_INFO("OnChangeFromRdb002::End"); +} } // namespace DataShare } // namespace OHOS \ No newline at end of file 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 c99e49d9..5644959a 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 @@ -110,6 +110,8 @@ void AccountDelegateNormalImpl::SubscribeAccountEvent() matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_REMOVED); matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_SWITCHED); matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_UNLOCKED); + matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_STOPPING); + matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_STOPPED); CommonEventSubscribeInfo info(matchingSkills); eventSubscriber_ = std::make_shared(info); eventSubscriber_->SetEventCallback([this](AccountEventInfo& account) { @@ -131,6 +133,12 @@ void AccountDelegateNormalImpl::UpdateUserStatus(const AccountEventInfo& account case static_cast(AccountStatus::DEVICE_ACCOUNT_UNLOCKED): userStatus_.InsertOrAssign(atoi(account.userId.c_str()), true); break; + case static_cast(AccountStatus::DEVICE_ACCOUNT_STOPPING): + userStatus_.Erase(atoi(account.userId.c_str())); + break; + case static_cast(AccountStatus::DEVICE_ACCOUNT_STOPPED): + userStatus_.InsertOrAssign(atoi(account.userId.c_str()), false); + break; default: break; } diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.cpp b/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.cpp index c29f60aa..3820f25f 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.cpp @@ -43,8 +43,8 @@ AppPipeHandler::AppPipeHandler(const PipeInfo &pipeInfo) softbusAdapter_ = SoftBusAdapter::GetInstance(); } -Status AppPipeHandler::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, - uint32_t totalLength, const MessageInfo &info) +std::pair AppPipeHandler::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, + const DataInfo &dataInfo, uint32_t totalLength, const MessageInfo &info) { return softbusAdapter_->SendData(pipeInfo, deviceId, dataInfo, totalLength, info); } diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.h b/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.h index 2a2508c5..1fddf667 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.h +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_handler.h @@ -42,7 +42,7 @@ public: // stop DataChangeListener to watch data change; Status StopWatchDataChange(const AppDataChangeListener *observer, const PipeInfo &pipeInfo); // Send data to other device, function will be called back after sent to notify send result. - Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, + std::pair SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, uint32_t totalLength, const MessageInfo &info); bool IsSameStartedOnPeer(const struct PipeInfo &pipeInfo, const struct DeviceId &peer); diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.cpp b/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.cpp index f3794147..8073d0c8 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.cpp @@ -58,13 +58,13 @@ Status AppPipeMgr::StopWatchDataChange(const AppDataChangeListener *observer, co } // Send data to other device, function will be called back after sent to notify send result. -Status AppPipeMgr::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, - uint32_t totalLength, const MessageInfo &info) +std::pair AppPipeMgr::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, + const DataInfo &dataInfo, uint32_t totalLength, const MessageInfo &info) { if (dataInfo.length > DataBuffer::MAX_TRANSFER_SIZE || dataInfo.length == 0 || dataInfo.data == nullptr || pipeInfo.pipeId.empty() || deviceId.deviceId.empty()) { ZLOGW("Input is invalid, maxSize:%u, current size:%u", DataBuffer::MAX_TRANSFER_SIZE, dataInfo.length); - return Status::ERROR; + return std::make_pair(Status::ERROR, 0); } ZLOGD("pipeInfo:%s ,size:%u, total length:%u", pipeInfo.pipeId.c_str(), dataInfo.length, totalLength); std::shared_ptr appPipeHandler; @@ -73,7 +73,7 @@ Status AppPipeMgr::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, auto it = dataBusMap_.find(pipeInfo.pipeId); if (it == dataBusMap_.end()) { ZLOGW("pipeInfo:%s not found", pipeInfo.pipeId.c_str()); - return Status::KEY_NOT_FOUND; + return std::make_pair(Status::KEY_NOT_FOUND, 0); } appPipeHandler = it->second; } diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.h b/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.h index 222248c5..1ffb5659 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.h +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/app_pipe_mgr.h @@ -36,7 +36,7 @@ public: Status StopWatchDataChange(const AppDataChangeListener *observer, const PipeInfo &pipeInfo); // Send data to other device, function will be called back after sent to notify send result. - Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, + std::pair SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, uint32_t totalLength, const MessageInfo &info); // start server Status Start(const PipeInfo &pipeInfo); diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.cpp b/datamgr_service/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.cpp index 8b8eb488..65869012 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.cpp @@ -48,8 +48,8 @@ Status CommunicationProviderImpl::StopWatchDataChange(const AppDataChangeListene return appPipeMgr_.StopWatchDataChange(observer, pipeInfo); } -Status CommunicationProviderImpl::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, - uint32_t totalLength, const MessageInfo &info) +std::pair CommunicationProviderImpl::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, + const DataInfo &dataInfo, uint32_t totalLength, const MessageInfo &info) { return appPipeMgr_.SendData(pipeInfo, deviceId, dataInfo, totalLength, info); } diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.h b/datamgr_service/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.h index aac05a9f..5f13ab41 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.h +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/communication_provider_impl.h @@ -36,7 +36,7 @@ public: Status StopWatchDataChange(const AppDataChangeListener *observer, const PipeInfo &pipeInfo) override; // Send data to other device, function will be called back after sent to notify send result. - Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, + std::pair SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, uint32_t totalLength, const MessageInfo &info) override; // start 1 server to listen data from other devices; diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/communicator_context.cpp b/datamgr_service/services/distributeddataservice/adapter/communicator/src/communicator_context.cpp index 691b0aed..76f63db9 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/communicator_context.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/communicator_context.cpp @@ -17,6 +17,7 @@ #include "communicator_context.h" #include "log_print.h" #include "kvstore_utils.h" +#include "softbus_error_code.h" namespace OHOS::DistributedData { using KvUtils = OHOS::DistributedKv::KvStoreUtils; @@ -72,28 +73,32 @@ Status CommunicatorContext::UnRegSessionListener(const DevChangeListener *observ return Status::SUCCESS; } -void CommunicatorContext::NotifySessionReady(const std::string &deviceId) +void CommunicatorContext::NotifySessionReady(const std::string &deviceId, int32_t errCode) { if (deviceId.empty()) { ZLOGE("deviceId empty"); return; } - devices_.Insert(deviceId, deviceId); + if (errCode == SOFTBUS_OK) { + devices_.Insert(deviceId, deviceId); + } DeviceInfo devInfo; devInfo.uuid = deviceId; { std::lock_guard lock(mutex_); for (const auto &observer : observers_) { if (observer != nullptr) { - observer->OnSessionReady(devInfo); + observer->OnSessionReady(devInfo, errCode); } } ZLOGI("Notify session begin, deviceId:%{public}s, observer count:%{public}zu", KvUtils::ToBeAnonymous(deviceId).c_str(), observers_.size()); } - std::lock_guard sessionLockGard(sessionMutex_); - if (closeListener_) { - closeListener_(deviceId); + if (errCode == SOFTBUS_OK) { + std::lock_guard sessionLockGard(sessionMutex_); + if (closeListener_) { + closeListener_(deviceId); + } } } diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/device_manager_adapter.cpp b/datamgr_service/services/distributeddataservice/adapter/communicator/src/device_manager_adapter.cpp index cd9f85c7..677701c4 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 @@ -80,7 +80,9 @@ void DataMgrDmStateCall::OnDeviceReady(const DmDeviceInfo &info) class DataMgrDmInitCall final : public DistributedHardware::DmInitCallback { public: explicit DataMgrDmInitCall(DeviceManagerAdapter &dmAdapter, std::shared_ptr executors) - : dmAdapter_(dmAdapter), executors_(executors) {} + : dmAdapter_(dmAdapter), executors_(executors) + { + } void OnRemoteDied() override; private: @@ -162,8 +164,8 @@ struct DeviceExtraInfo final : public Serializable { int32_t OS_TYPE = OH_OS_TYPE; - DeviceExtraInfo() {}; - ~DeviceExtraInfo() {}; + DeviceExtraInfo(){}; + ~DeviceExtraInfo(){}; bool Marshal(json &node) const override { return SetValue(node[GET_NAME(OS_TYPE)], OS_TYPE); @@ -381,7 +383,7 @@ bool DeviceManagerAdapter::GetDeviceInfo(const DmDeviceInfo &dmInfo, DeviceInfo } if (uuid == CLOUD_DEVICE_UUID) { dvInfo = { uuid, udid, networkId, std::string(dmInfo.deviceName), dmInfo.deviceTypeId, OH_OS_TYPE, - static_cast(dmInfo.authForm)}; + static_cast(dmInfo.authForm) }; return true; } DeviceExtraInfo deviceExtraInfo; @@ -390,7 +392,7 @@ bool DeviceManagerAdapter::GetDeviceInfo(const DmDeviceInfo &dmInfo, DeviceInfo return false; } dvInfo = { uuid, udid, networkId, std::string(dmInfo.deviceName), dmInfo.deviceTypeId, deviceExtraInfo.OS_TYPE, - static_cast(dmInfo.authForm)}; + static_cast(dmInfo.authForm) }; return true; } @@ -450,9 +452,8 @@ std::vector DeviceManagerAdapter::GetRemoteDevices() ZLOGE("Unmarshall failed, deviceExtraInfo:%{public}s", dmInfo.extraData.c_str()); continue; } - DeviceInfo dvInfo = { std::move(uuid), std::move(udid), std::move(networkId), - std::string(dmInfo.deviceName), dmInfo.deviceTypeId, deviceExtraInfo.OS_TYPE, - static_cast(dmInfo.authForm) }; + DeviceInfo dvInfo = { std::move(uuid), std::move(udid), std::move(networkId), std::string(dmInfo.deviceName), + dmInfo.deviceTypeId, deviceExtraInfo.OS_TYPE, static_cast(dmInfo.authForm) }; dvInfos.emplace_back(std::move(dvInfo)); } return dvInfos; @@ -469,7 +470,7 @@ std::vector DeviceManagerAdapter::GetOnlineDevices() return devices; } -bool DeviceManagerAdapter::IsDeviceReady(const std::string& id) +bool DeviceManagerAdapter::IsDeviceReady(const std::string &id) { auto it = readyDevices_.Find(id); return (it.first && it.second.first == DeviceState::DEVICE_ONREADY); @@ -757,4 +758,27 @@ bool DeviceManagerAdapter::IsSameAccount(const std::string &id) auto networkId = DeviceManagerAdapter::GetInstance().ToNetworkID(id); return DeviceManager::GetInstance().IsSameAccount(networkId); } + +bool DeviceManagerAdapter::CheckAccessControl(const AccessCaller &accCaller, const AccessCallee &accCallee) +{ + DmAccessCaller dmAccessCaller = { .accountId = accCaller.accountId, + .pkgName = accCaller.bundleName, + .networkId = accCaller.networkId, + .userId = accCaller.userId }; + DmAccessCallee dmAccessCallee = { .accountId = accCallee.accountId, + .networkId = accCallee.networkId, + .userId = accCallee.userId }; + return DeviceManager::GetInstance().CheckAccessControl(dmAccessCaller, dmAccessCallee); +} + +bool DeviceManagerAdapter::IsSameAccount(const AccessCaller &accCaller, const AccessCallee &accCallee) +{ + DmAccessCaller dmAccessCaller = { .accountId = accCaller.accountId, + .networkId = accCaller.networkId, + .userId = accCaller.userId }; + DmAccessCallee dmAccessCallee = { .accountId = accCallee.accountId, + .networkId = accCallee.networkId, + .userId = accCallee.userId }; + return DeviceManager::GetInstance().CheckIsSameAccount(dmAccessCaller, dmAccessCallee); +} } // namespace OHOS::DistributedData diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/process_communicator_impl.cpp b/datamgr_service/services/distributeddataservice/adapter/communicator/src/process_communicator_impl.cpp index 2de88fc7..b3d43e80 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/process_communicator_impl.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/process_communicator_impl.cpp @@ -139,14 +139,18 @@ DBStatus ProcessCommunicatorImpl::SendData(const DeviceInfos &dstDevInfo, const const DataInfo dataInfo = { const_cast(data), length}; DeviceId destination; destination.deviceId = dstDevInfo.identifier; - Status errCode = CommunicationProvider::GetInstance().SendData(pi, destination, dataInfo, totalLength); + auto [errCode, softBusErrCode] = + CommunicationProvider::GetInstance().SendData(pi, destination, dataInfo, totalLength); if (errCode == Status::RATE_LIMIT) { - ZLOGD("commProvider_ opening session, status:%{public}d.", static_cast(errCode)); + ZLOGD("commProvider_ opening session, status:%{public}d.", static_cast(softBusErrCode)); return DBStatus::RATE_LIMIT; } if (errCode != Status::SUCCESS) { - ZLOGE("commProvider_ SendData Fail."); - return DBStatus::DB_ERROR; + ZLOGE("commProvider_ SendData Fail. code:%{public}d", softBusErrCode); + if (softBusErrCode == 0) { + return DBStatus::DB_ERROR; + } + return static_cast(softBusErrCode); } return DBStatus::OK; } @@ -221,7 +225,7 @@ void ProcessCommunicatorImpl::OnDeviceChanged(const DeviceInfo &info, const Devi onDeviceChangeHandler_(devInfo, (type == DeviceChangeType::DEVICE_ONLINE)); } -void ProcessCommunicatorImpl::OnSessionReady(const DeviceInfo &info) const +void ProcessCommunicatorImpl::OnSessionReady(const DeviceInfo &info, int32_t errCode) const { std::lock_guard lock(sessionMutex_); if (sessionListener_ == nullptr) { @@ -229,7 +233,7 @@ void ProcessCommunicatorImpl::OnSessionReady(const DeviceInfo &info) const } DeviceInfos devInfos; devInfos.identifier = info.uuid; - sessionListener_(devInfos); + sessionListener_(devInfos, errCode); } std::shared_ptr ProcessCommunicatorImpl::GetExtendHeaderHandle(const ExtendInfo &info) diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter.h b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter.h index c1d5ffea..5e70c301 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter.h +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_adapter.h @@ -52,8 +52,8 @@ public: Status StopWatchDataChange(const AppDataChangeListener *observer, const PipeInfo &pipeInfo); // Send data to other device, function will be called back after sent to notify send result. - Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, uint32_t length, - const MessageInfo &info); + std::pair SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, + const DataInfo &dataInfo, uint32_t length, const MessageInfo &info); bool IsSameStartedOnPeer(const struct PipeInfo &pipeInfo, const struct DeviceId &peer); @@ -83,7 +83,6 @@ public: void OnDeviceChanged(const AppDistributedKv::DeviceInfo &info, const AppDistributedKv::DeviceChangeType &type) const override; - private: using Time = std::chrono::steady_clock::time_point; using Duration = std::chrono::steady_clock::duration; @@ -95,6 +94,7 @@ private: void Reuse(const PipeInfo &pipeInfo, const DeviceId &deviceId, uint32_t qosType, std::shared_ptr &conn); void GetExpireTime(std::shared_ptr &conn); + std::pair OpenConnect(const std::shared_ptr &conn, const DeviceId &deviceId); static constexpr const char *PKG_NAME = "distributeddata-default"; static constexpr Time INVALID_NEXT = std::chrono::steady_clock::time_point::max(); static constexpr uint32_t QOS_COUNT = 3; 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 8edf7755..73d1bbe1 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 @@ -189,8 +189,8 @@ void SoftBusAdapter::GetExpireTime(std::shared_ptr &conn) } } -Status SoftBusAdapter::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, - uint32_t length, const MessageInfo &info) +std::pair SoftBusAdapter::SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, + const DataInfo &dataInfo, uint32_t length, const MessageInfo &info) { std::shared_ptr conn; bool isOHOSType = DmAdapter::GetInstance().IsOHOSType(deviceId.deviceId); @@ -218,29 +218,35 @@ Status SoftBusAdapter::SendData(const PipeInfo &pipeInfo, const DeviceId &device Reuse(pipeInfo, deviceId, qosType, conn); } if (conn == nullptr) { - return Status::ERROR; + return std::make_pair(Status::ERROR, 0); } auto status = conn->CheckStatus(); if (status == Status::RATE_LIMIT) { - return Status::RATE_LIMIT; + return std::make_pair(Status::RATE_LIMIT, 0); } if (status != Status::SUCCESS) { - auto task = [this, connect = std::weak_ptr(conn)]() { - auto conn = connect.lock(); - if (conn != nullptr) { - conn->OpenConnect(&clientListener_); - } - }; - auto networkId = DmAdapter::GetInstance().GetDeviceInfo(deviceId.deviceId).networkId; - ConnectManager::GetInstance()->ApplyConnect(networkId, task); - return Status::RATE_LIMIT; + return OpenConnect(conn, deviceId); } - status = conn->SendData(dataInfo, &clientListener_); if ((status != Status::NETWORK_ERROR) && (status != Status::RATE_LIMIT)) { GetExpireTime(conn); } - return status; + auto errCode = conn->GetSoftBusError(); + return std::make_pair(status, errCode); +} + +std::pair SoftBusAdapter::OpenConnect(const std::shared_ptr &conn, + const DeviceId &deviceId) +{ + auto task = [this, connect = std::weak_ptr(conn)]() { + auto conn = connect.lock(); + if (conn != nullptr) { + conn->OpenConnect(&clientListener_); + } + }; + auto networkId = DmAdapter::GetInstance().GetDeviceInfo(deviceId.deviceId).networkId; + ConnectManager::GetInstance()->ApplyConnect(networkId, task); + return std::make_pair(Status::RATE_LIMIT, 0); } void SoftBusAdapter::StartCloseSessionTask(const std::string &deviceId) 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 742628d5..9dfb23b2 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.cpp +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.cpp @@ -75,12 +75,20 @@ Status SoftBusClient::SendData(const DataInfo &dataInfo, const ISocketListener * if (ret != SOFTBUS_OK) { expireTime_ = std::chrono::steady_clock::now(); ZLOGE("send data to socket%{public}d failed, ret:%{public}d.", socket_, ret); + softBusError_ = ret; return Status::ERROR; } + softBusError_ = 0; expireTime_ = CalcExpireTime(); return Status::SUCCESS; } +int32_t SoftBusClient::GetSoftBusError() +{ + std::lock_guard lock(mutex_); + return softBusError_; +} + Status SoftBusClient::OpenConnect(const ISocketListener *listener) { std::lock_guard lock(mutex_); @@ -114,10 +122,8 @@ Status SoftBusClient::OpenConnect(const ISocketListener *listener) } ZLOGI("Bind Start, device:%{public}s socket:%{public}d type:%{public}u", KvStoreUtils::ToBeAnonymous(client->device_.deviceId).c_str(), clientSocket, type); - auto status = client->Open(clientSocket, QOS_INFOS[type % QOS_BUTT], listener); - if (status == Status::SUCCESS) { - Context::GetInstance().NotifySessionReady(client->device_.deviceId); - } + int32_t status = client->Open(clientSocket, QOS_INFOS[type % QOS_BUTT], listener); + Context::GetInstance().NotifySessionReady(client->device_.deviceId, status); client->isOpening_.store(false); }; Context::GetInstance().GetThreadPool()->Execute(task); @@ -138,7 +144,7 @@ Status SoftBusClient::CheckStatus() return Status::ERROR; } -Status SoftBusClient::Open(int32_t socket, const QosTV qos[], const ISocketListener *listener) +int32_t SoftBusClient::Open(int32_t socket, const QosTV qos[], const ISocketListener *listener) { int32_t status = ::Bind(socket, qos, QOS_COUNT, listener); ZLOGI("Bind %{public}s,session:%{public}s,socketId:%{public}d", @@ -148,14 +154,15 @@ Status SoftBusClient::Open(int32_t socket, const QosTV qos[], const ISocketListe ZLOGE("[Bind] device:%{public}s socket failed, session:%{public}s,result:%{public}d", KvStoreUtils::ToBeAnonymous(device_.deviceId).c_str(), pipe_.pipeId.c_str(), status); ::Shutdown(socket); - return Status::NETWORK_ERROR; + return status; } UpdateExpireTime(); uint32_t mtu = 0; std::tie(status, mtu) = GetMtu(socket); if (status != SOFTBUS_OK) { - ZLOGE("GetMtu failed, session:%{public}s, socket:%{public}d", pipe_.pipeId.c_str(), socket_); - return Status::NETWORK_ERROR; + ZLOGE("GetMtu failed, session:%{public}s, socket:%{public}d, status:%{public}d", pipe_.pipeId.c_str(), socket_, + status); + return status; } { std::lock_guard lock(mutex_); @@ -166,7 +173,7 @@ Status SoftBusClient::Open(int32_t socket, const QosTV qos[], const ISocketListe ZLOGI("open %{public}s, session:%{public}s success, socket:%{public}d", KvStoreUtils::ToBeAnonymous(device_.deviceId).c_str(), pipe_.pipeId.c_str(), socket_); ConnectManager::GetInstance()->OnSessionOpen(DmAdapter::GetInstance().GetDeviceInfo(device_.deviceId).networkId); - return Status::SUCCESS; + return status; } SoftBusClient::Time SoftBusClient::GetExpireTime() const diff --git a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.h b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.h index 898a7ada..1547e32d 100644 --- a/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.h +++ b/datamgr_service/services/distributeddataservice/adapter/communicator/src/softbus_client.h @@ -48,11 +48,12 @@ public: int32_t GetSocket() const; uint32_t GetQoSType() const; void UpdateExpireTime(); + int32_t GetSoftBusError(); bool needRemove = false; bool isReuse = false; private: - Status Open(int32_t socket, const QosTV qos[], const ISocketListener *listener); + int32_t Open(int32_t socket, const QosTV qos[], const ISocketListener *listener); std::pair GetMtu(int32_t socket); Time CalcExpireTime() const; @@ -85,6 +86,7 @@ private: int32_t socket_ = INVALID_SOCKET_ID; int32_t bindState_ = -1; + int32_t softBusError_ = 0; }; } // namespace OHOS::AppDistributedKv 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 58c8e534..6c82c8b7 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 @@ -133,8 +133,8 @@ HWTEST_F(CommunicationProviderImplTest, CommunicationProvider005, TestSize.Level const uint8_t *t = reinterpret_cast(content.c_str()); DeviceId di17 = {"127.0.0.2"}; DataInfo data = { const_cast(t), static_cast(content.length())}; - Status status = CommunicationProvider::GetInstance().SendData(id17, di17, data, 0); - EXPECT_NE(status, Status::SUCCESS); + auto status = CommunicationProvider::GetInstance().SendData(id17, di17, data, 0); + EXPECT_NE(status.first, Status::SUCCESS); CommunicationProvider::GetInstance().StopWatchDataChange(dataListener17, id17); CommunicationProvider::GetInstance().Stop(id17); delete dataListener17; @@ -234,8 +234,8 @@ HWTEST_F(CommunicationProviderImplTest, CommunicationProvider011, TestSize.Level 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); + auto status = CommunicationProvider::GetInstance().SendData(id, di, data, 0); + EXPECT_EQ(status.first, Status::ERROR); CommunicationProvider::GetInstance().StopWatchDataChange(dataListener, id); CommunicationProvider::GetInstance().Stop(id); delete dataListener; @@ -259,8 +259,8 @@ HWTEST_F(CommunicationProviderImplTest, CommunicationProvider012, TestSize.Level 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); + auto status = CommunicationProvider::GetInstance().SendData(id, di, data, 0); + EXPECT_EQ(status.first, Status::ERROR); CommunicationProvider::GetInstance().StopWatchDataChange(dataListener, id); CommunicationProvider::GetInstance().Stop(id); delete dataListener; @@ -282,8 +282,8 @@ HWTEST_F(CommunicationProviderImplTest, CommunicationProvider013, TestSize.Level 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); + auto status = CommunicationProvider::GetInstance().SendData(id, di, data, 0); + EXPECT_EQ(status.first, Status::ERROR); CommunicationProvider::GetInstance().StopWatchDataChange(dataListener, id); CommunicationProvider::GetInstance().Stop(id); delete dataListener; @@ -307,8 +307,8 @@ HWTEST_F(CommunicationProviderImplTest, CommunicationProvider014, TestSize.Level 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); + auto status = CommunicationProvider::GetInstance().SendData(id, di, data, 0); + EXPECT_EQ(status.first, Status::ERROR); CommunicationProvider::GetInstance().StopWatchDataChange(dataListener, id); CommunicationProvider::GetInstance().Stop(id); delete dataListener; 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 index 9804ce14..41239891 100644 --- 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 @@ -155,8 +155,8 @@ HWTEST_F(SoftbusAdapterStandardTest, SendData, TestSize.Level1) 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); + auto status = SoftBusAdapter::GetInstance()->SendData(id, di, data, 11, { MessageType::DEFAULT }); + EXPECT_NE(status.first, Status::SUCCESS); SoftBusAdapter::GetInstance()->StopWatchDataChange(dataListener, id); delete dataListener; } diff --git a/datamgr_service/services/distributeddataservice/adapter/include/communicator/app_device_change_listener.h b/datamgr_service/services/distributeddataservice/adapter/include/communicator/app_device_change_listener.h index 8d460299..94b6b9f8 100644 --- a/datamgr_service/services/distributeddataservice/adapter/include/communicator/app_device_change_listener.h +++ b/datamgr_service/services/distributeddataservice/adapter/include/communicator/app_device_change_listener.h @@ -32,7 +32,7 @@ public: { return ChangeLevelType::HIGH; } - API_EXPORT virtual void OnSessionReady(const DeviceInfo &info) const {} + API_EXPORT virtual void OnSessionReady(const DeviceInfo &info, int32_t errCode) const {} }; } // namespace AppDistributedKv } // namespace OHOS 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 afe72286..6b1f1af6 100644 --- a/datamgr_service/services/distributeddataservice/adapter/include/communicator/commu_types.h +++ b/datamgr_service/services/distributeddataservice/adapter/include/communicator/commu_types.h @@ -30,6 +30,25 @@ struct API_EXPORT DeviceInfo { int32_t authForm; }; +struct API_EXPORT AccessCaller { + std::string accountId; + std::string bundleName; + std::string networkId; + int32_t userId; +}; + +struct API_EXPORT AccessCallee { + std::string accountId; + std::string networkId; + int32_t userId; +}; + +struct API_EXPORT AclParams { + AccessCaller accCaller; + AccessCallee accCallee; + int32_t authType = 0; +}; + enum RouteType : int32_t { INVALID_ROUTE_TYPE = -1, ROUTE_TYPE_ALL = 0, diff --git a/datamgr_service/services/distributeddataservice/adapter/include/communicator/communication_provider.h b/datamgr_service/services/distributeddataservice/adapter/include/communicator/communication_provider.h index e694ae53..94cd0ed4 100644 --- a/datamgr_service/services/distributeddataservice/adapter/include/communicator/communication_provider.h +++ b/datamgr_service/services/distributeddataservice/adapter/include/communicator/communication_provider.h @@ -45,8 +45,9 @@ public: virtual Status StopWatchDataChange(const AppDataChangeListener *observer, const PipeInfo &pipeInfo) = 0; // Send data to other device, function will be called back after sent to notify send result - virtual Status SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, const DataInfo &dataInfo, - uint32_t totalLength, const MessageInfo &info = { MessageType::DEFAULT }) = 0; + virtual std::pair SendData(const PipeInfo &pipeInfo, const DeviceId &deviceId, + const DataInfo &dataInfo, uint32_t totalLength, + const MessageInfo &info = { MessageType::DEFAULT }) = 0; // start one server to listen data from other devices; virtual Status Start(const PipeInfo &pipeInfo) = 0; 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 a77a2db3..ce09ab58 100644 --- a/datamgr_service/services/distributeddataservice/adapter/include/communicator/communicator_context.h +++ b/datamgr_service/services/distributeddataservice/adapter/include/communicator/communicator_context.h @@ -36,7 +36,7 @@ public: std::shared_ptr GetThreadPool(); Status RegSessionListener(const DevChangeListener *observer); Status UnRegSessionListener(const DevChangeListener *observer); - void NotifySessionReady(const std::string &deviceId); + void NotifySessionReady(const std::string &deviceId, int32_t errCode); void NotifySessionClose(const std::string &deviceId); void SetSessionListener(const OnCloseAble &closeAbleCallback); bool IsSessionReady(const std::string &deviceId); 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 7c99f1fb..7edbd0fd 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 @@ -50,6 +50,8 @@ public: using AppDeviceChangeListener = OHOS::AppDistributedKv::AppDeviceChangeListener; using Status = OHOS::DistributedKv::Status; using Time = std::chrono::steady_clock::time_point; + using AccessCaller = OHOS::AppDistributedKv::AccessCaller; + using AccessCallee = OHOS::AppDistributedKv::AccessCallee; static DeviceManagerAdapter &GetInstance(); static constexpr const char *CLOUD_DEVICE_UUID = "cloudDeviceUuid"; static constexpr const char *CLOUD_DEVICE_UDID = "cloudDeviceUdid"; @@ -78,6 +80,8 @@ public: NetworkType GetNetworkType(bool retrieve = false); int32_t GetAuthType(const std::string& id); bool IsSameAccount(const std::string &id); + bool IsSameAccount(const AccessCaller &accCaller, const AccessCallee &accCallee); + bool CheckAccessControl(const AccessCaller &accCaller, const AccessCallee &accCallee); friend class DataMgrDmStateCall; friend class NetConnCallbackObserver; diff --git a/datamgr_service/services/distributeddataservice/adapter/include/communicator/process_communicator_impl.h b/datamgr_service/services/distributeddataservice/adapter/include/communicator/process_communicator_impl.h index ee32d141..4620c0fc 100644 --- a/datamgr_service/services/distributeddataservice/adapter/include/communicator/process_communicator_impl.h +++ b/datamgr_service/services/distributeddataservice/adapter/include/communicator/process_communicator_impl.h @@ -57,7 +57,7 @@ public: std::vector GetRemoteOnlineDeviceInfosList() override; bool IsSameProcessLabelStartedOnPeerDevice(const DeviceInfos &peerDevInfo) override; void OnDeviceChanged(const DeviceInfo &info, const DeviceChangeType &type) const override; - void OnSessionReady(const DeviceInfo &info) const override; + void OnSessionReady(const DeviceInfo &info, int32_t errCode) const override; API_EXPORT std::shared_ptr GetExtendHeaderHandle( const DistributedDB::ExtendInfo &info) override; diff --git a/datamgr_service/services/distributeddataservice/app/src/checker/bundle_checker.cpp b/datamgr_service/services/distributeddataservice/app/src/checker/bundle_checker.cpp index 8d61d921..674e09d5 100644 --- a/datamgr_service/services/distributeddataservice/app/src/checker/bundle_checker.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/checker/bundle_checker.cpp @@ -17,9 +17,14 @@ #include "bundle_checker.h" #include #include "accesstoken_kit.h" +#include "bundlemgr/bundle_mgr_proxy.h" #include "hap_token_info.h" +#include "ipc_skeleton.h" +#include "iservice_registry.h" #include "log_print.h" +#include "system_ability_definition.h" #include "utils/crypto.h" + namespace OHOS { namespace DistributedData { using namespace Security::AccessToken; @@ -56,27 +61,47 @@ bool BundleChecker::SetSwitchesInfo(const CheckerManager::Switches &switches) return true; } -std::string BundleChecker::GetAppId(const CheckerManager::StoreInfo &info) +std::string BundleChecker::GetBundleAppId(const CheckerManager::StoreInfo &info) { - if (AccessTokenKit::GetTokenTypeFlag(info.tokenId) != TOKEN_HAP) { + auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (samgrProxy == nullptr) { + ZLOGE("Failed to get system ability mgr."); return ""; } - HapTokenInfo tokenInfo; - auto result = AccessTokenKit::GetHapTokenInfo(info.tokenId, tokenInfo); - if (result != RET_SUCCESS) { - ZLOGE("token:0x%{public}x, result:%{public}d", info.tokenId, result); + auto bundleMgrProxy = samgrProxy->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); + if (bundleMgrProxy == nullptr) { + ZLOGE("Failed to Get BMS SA."); return ""; } - if (!info.bundleName.empty() && tokenInfo.bundleName != info.bundleName) { - ZLOGE("bundlename:%{public}s <-> %{public}s", info.bundleName.c_str(), tokenInfo.bundleName.c_str()); + auto bundleManager = iface_cast(bundleMgrProxy); + if (bundleManager == nullptr) { + ZLOGE("Failed to get bundle manager"); + return ""; + } + int32_t userId = info.uid / OHOS::AppExecFwk::Constants::BASE_USER_RANGE; + std::string appId = bundleManager->GetAppIdByBundleName(info.bundleName, userId); + if (appId.empty()) { + ZLOGE("GetAppIdByBundleName failed appId:%{public}s, bundleName:%{public}s, uid:%{public}d", + appId.c_str(), info.bundleName.c_str(), userId); + } + return appId; +} + +std::string BundleChecker::GetAppId(const CheckerManager::StoreInfo &info) +{ + if (AccessTokenKit::GetTokenTypeFlag(info.tokenId) != TOKEN_HAP) { + return ""; + } + auto appId = GetBundleAppId(info); + if (appId.empty()) { return ""; } auto it = trusts_.find(info.bundleName); - if (it != trusts_.end() && (it->second == tokenInfo.appID)) { + if (it != trusts_.end() && (it->second == appId)) { return info.bundleName; } - ZLOGD("bundleName:%{public}s, appId:%{public}s", info.bundleName.c_str(), tokenInfo.appID.c_str()); - return Crypto::Sha256(tokenInfo.appID); + ZLOGD("bundleName:%{public}s, appId:%{public}s", info.bundleName.c_str(), appId.c_str()); + return Crypto::Sha256(appId); } bool BundleChecker::IsValid(const CheckerManager::StoreInfo &info) @@ -98,18 +123,12 @@ bool BundleChecker::IsDistrust(const CheckerManager::StoreInfo &info) if (AccessTokenKit::GetTokenTypeFlag(info.tokenId) != TOKEN_HAP) { return false; } - HapTokenInfo tokenInfo; - auto result = AccessTokenKit::GetHapTokenInfo(info.tokenId, tokenInfo); - if (result != RET_SUCCESS) { - ZLOGE("token:0x%{public}x, result:%{public}d", info.tokenId, result); - return false; - } - if (!info.bundleName.empty() && tokenInfo.bundleName != info.bundleName) { - ZLOGE("bundlename:%{public}s <-> %{public}s", info.bundleName.c_str(), tokenInfo.bundleName.c_str()); + auto appId = GetBundleAppId(info); + if (appId.empty()) { return false; } auto it = distrusts_.find(info.bundleName); - if (it != distrusts_.end() && (it->second == tokenInfo.appID)) { + if (it != distrusts_.end() && (it->second == appId)) { return true; } return false; diff --git a/datamgr_service/services/distributeddataservice/app/src/checker/bundle_checker.h b/datamgr_service/services/distributeddataservice/app/src/checker/bundle_checker.h index 794ceaa1..1eba18e5 100644 --- a/datamgr_service/services/distributeddataservice/app/src/checker/bundle_checker.h +++ b/datamgr_service/services/distributeddataservice/app/src/checker/bundle_checker.h @@ -44,6 +44,7 @@ private: std::map switches_; std::vector dynamicStores_; std::vector staticStores_; + std::string GetBundleAppId(const CheckerManager::StoreInfo &info); }; } // namespace DistributedData } // namespace OHOS 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 5606a61a..f543039d 100644 --- a/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.cpp @@ -363,12 +363,11 @@ void KvStoreDataService::StartService() // subscribe account event listener to EventNotificationMgr auto autoLaunch = [this](const std::string &identifier, DistributedDB::AutoLaunchParam ¶m) -> bool { - auto status = ResolveAutoLaunchParamByIdentifier(identifier, param); features_.ForEachCopies([&identifier, ¶m](const auto &, sptr &value) { value->ResolveAutoLaunch(identifier, param); return false; }); - return status; + return false; }; KvStoreDelegateManager::SetAutoLaunchRequestCallback(autoLaunch); ZLOGI("Start distributedata Success, Publish ret: %{public}d", static_cast(ret)); @@ -396,180 +395,6 @@ void KvStoreDataService::OnStoreMetaChanged( ZLOGI("dirty kv store. storeId:%{public}s", Anonymous::Change(metaData.storeId).c_str()); } -bool KvStoreDataService::CompareTripleIdentifier(const std::string &accountId, const std::string &identifier, - const StoreMetaData &storeMeta) -{ - std::vector accountIds { accountId, "ohosAnonymousUid", "default" }; - for (auto &id : accountIds) { - auto convertedIds = - AppIdMappingConfigManager::GetInstance().Convert(storeMeta.appId, storeMeta.user); - const std::string &tempTripleIdentifier = - DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(id, convertedIds.first, - storeMeta.storeId, false); - if (tempTripleIdentifier == identifier) { - ZLOGI("find triple identifier,storeId:%{public}s,id:%{public}s", - Anonymous::Change(storeMeta.storeId).c_str(), Anonymous::Change(id).c_str()); - return true; - } - } - return false; -} - -bool KvStoreDataService::ResolveAutoLaunchParamByIdentifier( - const std::string &identifier, DistributedDB::AutoLaunchParam ¶m) -{ - std::vector entries; - std::string localDeviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; - if (!MetaDataManager::GetInstance().LoadMeta(StoreMetaData::GetPrefix({ localDeviceId }), entries)) { - ZLOGE("get full meta failed"); - 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) && - (StoreMetaData::STORE_RELATIONAL_END >= storeMeta.storeType))) { - // judge local userid and local meta - continue; - } - bool isTripleIdentifierEqual = CompareTripleIdentifier(accountId, identifier, storeMeta); - const std::string &itemDualIdentifier = - DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier("", storeMeta.appId, storeMeta.storeId, true); - if (isTripleIdentifierEqual && storeMeta.bundleName != Bootstrap::GetInstance().GetProcessLabel()) { - ResolveAutoLaunchCompatible(storeMeta, identifier, accountId); - } - if (identifier == itemDualIdentifier || isTripleIdentifierEqual) { - ZLOGI("identifier find"); - DistributedDB::AutoLaunchOption option; - option.createIfNecessary = false; - option.isEncryptedDb = storeMeta.isEncrypt; - - SecretKeyMeta secretKey; - if (storeMeta.isEncrypt && MetaDataManager::GetInstance().LoadMeta(storeMeta.GetSecretKey(), secretKey)) { - std::vector decryptKey; - CryptoManager::GetInstance().Decrypt(secretKey.sKey, decryptKey); - option.passwd.SetValue(decryptKey.data(), decryptKey.size()); - std::fill(decryptKey.begin(), decryptKey.end(), 0); - } - - if (storeMeta.bundleName == Bootstrap::GetInstance().GetProcessLabel()) { - param.userId = storeMeta.user; - } - option.schema = storeMeta.schema; - option.createDirByStoreIdOnly = true; - option.dataDir = storeMeta.dataDir; - option.secOption = ConvertSecurity(storeMeta.securityLevel); - option.isAutoSync = storeMeta.isAutoSync; - option.syncDualTupleMode = true; // dual tuple flag - param.appId = storeMeta.appId; - param.storeId = storeMeta.storeId; - param.option = option; - return true; - } - } - ZLOGI("not find identifier"); - return false; -} - -DistributedDB::SecurityOption KvStoreDataService::ConvertSecurity(int securityLevel) -{ - if (securityLevel < SecurityLevel::NO_LABEL || securityLevel > SecurityLevel::S4) { - return {DistributedDB::NOT_SET, DistributedDB::ECE}; - } - switch (securityLevel) { - case SecurityLevel::S3: - return {DistributedDB::S3, DistributedDB::SECE}; - case SecurityLevel::S4: - return {DistributedDB::S4, DistributedDB::ECE}; - default: - return {securityLevel, DistributedDB::ECE}; - } -} - -void KvStoreDataService::ResolveAutoLaunchCompatible(const StoreMetaData &storeMeta, const std::string &identifier, - const std::string &accountId) -{ - 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({ DirectoryManager::GetInstance().GetStorePath(storeMeta) }); - Options options = { - .createIfMissing = false, - .encrypt = storeMeta.isEncrypt, - .autoSync = storeMeta.isAutoSync, - .securityLevel = storeMeta.securityLevel, - .kvStoreType = static_cast(storeMeta.storeType), - }; - DistributedDB::KvStoreNbDelegate::Option dbOptions; - SecretKeyMeta secretKey; - if (storeMeta.isEncrypt && MetaDataManager::GetInstance().LoadMeta(storeMeta.GetSecretKey(), secretKey)) { - std::vector decryptKey; - CryptoManager::GetInstance().Decrypt(secretKey.sKey, decryptKey); - std::fill(secretKey.sKey.begin(), secretKey.sKey.end(), 0); - secretKey.sKey = std::move(decryptKey); - std::fill(decryptKey.begin(), decryptKey.end(), 0); - } - InitNbDbOption(options, secretKey.sKey, dbOptions); - DistributedDB::KvStoreNbDelegate *store = nullptr; - delegateManager.GetKvStore(storeMeta.storeId, dbOptions, - [&store, &storeMeta, &accountId](int status, DistributedDB::KvStoreNbDelegate *delegate) { - ZLOGI("temporary open db for equal identifier, ret:%{public}d", status); - if (delegate != nullptr) { - KvStoreTuple tuple = { accountId, storeMeta.appId, storeMeta.storeId }; - UpgradeManager::SetCompatibleIdentifyByType(delegate, tuple); - store = delegate; - } - }); - ExecutorPool::Task delayTask([store]() { - ZLOGI("AutoLaunch:close store after 60s while autolaunch finishied"); - DistributedDB::KvStoreDelegateManager delegateManager("", ""); - delegateManager.CloseKvStore(store); - }); - constexpr int CLOSE_STORE_DELAY_TIME = 60; // unit: seconds - executors_->Schedule(std::chrono::seconds(CLOSE_STORE_DELAY_TIME), std::move(delayTask)); -} - -Status KvStoreDataService::InitNbDbOption(const Options &options, const std::vector &cipherKey, - DistributedDB::KvStoreNbDelegate::Option &dbOption) -{ - DistributedDB::CipherPassword password; - auto status = password.SetValue(cipherKey.data(), cipherKey.size()); - if (status != DistributedDB::CipherPassword::ErrorCode::OK) { - ZLOGE("Failed to set the passwd."); - return Status::DB_ERROR; - } - - dbOption.syncDualTupleMode = true; // tuple of (appid+storeid) - dbOption.createIfNecessary = options.createIfMissing; - dbOption.isMemoryDb = (!options.persistent); - dbOption.isEncryptedDb = options.encrypt; - dbOption.isNeedCompressOnSync = options.isNeedCompress; - if (options.encrypt) { - dbOption.cipher = DistributedDB::CipherType::AES_256_GCM; - dbOption.passwd = password; - } - - if (options.kvStoreType == KvStoreType::SINGLE_VERSION) { - dbOption.conflictResolvePolicy = DistributedDB::LAST_WIN; - } else if (options.kvStoreType == KvStoreType::DEVICE_COLLABORATION) { - dbOption.conflictResolvePolicy = DistributedDB::DEVICE_COLLABORATION; - } else { - ZLOGE("kvStoreType is invalid"); - return Status::INVALID_ARGUMENT; - } - - dbOption.schema = options.schema; - dbOption.createDirByStoreIdOnly = true; - dbOption.secOption = ConvertSecurity(options.securityLevel); - return Status::SUCCESS; -} - void KvStoreDataService::OnStop() { ZLOGI("begin."); 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 53a02afe..77f221bb 100644 --- a/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.h +++ b/datamgr_service/services/distributeddataservice/app/src/kvstore_data_service.h @@ -165,19 +165,9 @@ private: void OnStoreMetaChanged(const std::vector &key, const std::vector &value, CHANGE_FLAG flag); Status AppExit(pid_t uid, pid_t pid, uint32_t token, const AppId &appId); - - bool ResolveAutoLaunchParamByIdentifier(const std::string &identifier, DistributedDB::AutoLaunchParam ¶m); - void ResolveAutoLaunchCompatible(const StoreMetaData &storeMeta, const std::string &identifier, - const std::string &accountId); - + void LoadConfigs(); - bool CompareTripleIdentifier(const std::string &accountId, const std::string &identifier, - const StoreMetaData &storeMeta); - static DistributedDB::SecurityOption ConvertSecurity(int securityLevel); - static Status InitNbDbOption(const Options &options, const std::vector &cipherKey, - DistributedDB::KvStoreNbDelegate::Option &dbOption); - static constexpr int TEN_SEC = 10; ConcurrentMap> clients_; diff --git a/datamgr_service/services/distributeddataservice/app/src/kvstore_device_listener.cpp b/datamgr_service/services/distributeddataservice/app/src/kvstore_device_listener.cpp index 1104cfc1..65a741b5 100644 --- a/datamgr_service/services/distributeddataservice/app/src/kvstore_device_listener.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/kvstore_device_listener.cpp @@ -34,8 +34,9 @@ void KvStoreDeviceListener::OnDeviceChanged( ZLOGI("device is %{public}d", type); } -void KvStoreDeviceListener::OnSessionReady(const AppDistributedKv::DeviceInfo &info) const +void KvStoreDeviceListener::OnSessionReady(const AppDistributedKv::DeviceInfo &info, int32_t errCode) const { + (void)errCode; kvStoreDataService_.OnSessionReady(info); } diff --git a/datamgr_service/services/distributeddataservice/app/src/kvstore_device_listener.h b/datamgr_service/services/distributeddataservice/app/src/kvstore_device_listener.h index 037c367d..f9ee5058 100644 --- a/datamgr_service/services/distributeddataservice/app/src/kvstore_device_listener.h +++ b/datamgr_service/services/distributeddataservice/app/src/kvstore_device_listener.h @@ -26,7 +26,7 @@ public: void OnDeviceChanged( const AppDistributedKv::DeviceInfo &info, const AppDistributedKv::DeviceChangeType &type) const override; AppDistributedKv::ChangeLevelType GetChangeLevelType() const override; - void OnSessionReady(const AppDistributedKv::DeviceInfo &info) const override; + void OnSessionReady(const AppDistributedKv::DeviceInfo &info, int32_t errCode = 0) const override; private: KvStoreDataService &kvStoreDataService_; 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 96705c43..5c19c739 100644 --- a/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/kvstore_meta_manager.cpp @@ -362,17 +362,7 @@ std::function KvStoreMetaManager::CloudSyncTask() std::lock_guard lock(mutex_); delaySyncTaskId_ = ExecutorPool::INVALID_TASK_ID; } - 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)); }; } 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 318891be..d602b206 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 @@ -78,15 +78,14 @@ DistributedDB::DBStatus RouteHeadHandlerImpl::GetHeadDataSize(uint32_t &headSize ZLOGI("meta data permitted"); return DistributedDB::OK; } - 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 (devInfo.osType != OH_OS_TYPE) { + ZLOGD("devicdId:%{public}s is not oh type", + Anonymous::Change(session_.targetDeviceId).c_str()); + return DistributedDB::OK; } + bool flag = false; + auto peerCap = UpgradeManager::GetInstance().GetCapability(session_.targetDeviceId, flag); if (!flag) { ZLOGI("get peer cap failed"); return DistributedDB::DB_ERROR; diff --git a/datamgr_service/services/distributeddataservice/app/src/session_manager/session_manager.cpp b/datamgr_service/services/distributeddataservice/app/src/session_manager/session_manager.cpp index d46217a4..3fd3f6a5 100644 --- a/datamgr_service/services/distributeddataservice/app/src/session_manager/session_manager.cpp +++ b/datamgr_service/services/distributeddataservice/app/src/session_manager/session_manager.cpp @@ -28,8 +28,10 @@ #include "utils/anonymous.h" #include "utils/converter.h" #include "types.h" +#include "device_manager_adapter.h" namespace OHOS::DistributedData { using namespace OHOS::DistributedKv; +using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; SessionManager &SessionManager::GetInstance() { static SessionManager instance; @@ -58,58 +60,96 @@ Session SessionManager::GetSession(const SessionPoint &from, const std::string & } } - std::string bundleName = ""; - int32_t authType = static_cast(AuthType::DEFAULT); - if (!GetAuthParams(from, bundleName, authType)) { - ZLOGE("GetAuthParams failed"); + AclParams aclParams; + if (!GetSendAuthParams(from, targetDeviceId, aclParams)) { + ZLOGE("get send auth params failed:%{public}s", Anonymous::Change(targetDeviceId).c_str()); return session; } - for (const auto &user : users) { - bool isPermitted = AuthDelegate::GetInstance()->CheckAccess(from.userId, user.id, - targetDeviceId, authType); - ZLOGD("access to peer user %{public}d is %{public}d", user.id, isPermitted); + aclParams.accCallee.userId = user.id; + auto [isPermitted, isSameAccount] = AuthDelegate::GetInstance()->CheckAccess(from.userId, user.id, + targetDeviceId, aclParams); if (isPermitted) { auto it = std::find(session.targetUserIds.begin(), session.targetUserIds.end(), user.id); - if (it == session.targetUserIds.end()) { + if (it == session.targetUserIds.end() && isSameAccount) { + session.targetUserIds.insert(session.targetUserIds.begin(), user.id); + } + if (it == session.targetUserIds.end() && !isSameAccount) { session.targetUserIds.push_back(user.id); } } } - ZLOGD("end"); + ZLOGD("access to peer users:%{public}s", DistributedData::Serializable::Marshall(session.targetUserIds).c_str()); return session; } -bool SessionManager::GetAuthParams(const SessionPoint &from, std::string &bundleName, int32_t &auth) const +bool SessionManager::GetSendAuthParams(const SessionPoint &from, const std::string &targetDeviceId, + AclParams &aclParams) const { std::vector metaData; if (!MetaDataManager::GetInstance().LoadMeta(StoreMetaData::GetPrefix({ from.deviceId }), metaData)) { - ZLOGW("load meta failed, deviceId:%{public}s", Anonymous::Change(from.deviceId).c_str()); + ZLOGE("load meta failed, deviceId:%{public}s, user:%{public}d", Anonymous::Change(from.deviceId).c_str(), + from.userId); return false; } for (const auto &storeMeta : metaData) { - if (storeMeta.appId == from.appId) { - bundleName = storeMeta.bundleName; - auth = storeMeta.authType; - break; + if (storeMeta.appId == from.appId && storeMeta.storeId == from.storeId) { + aclParams.accCaller.bundleName = storeMeta.bundleName; + aclParams.accCaller.accountId = AccountDelegate::GetInstance()->GetCurrentAccountId(); + aclParams.accCaller.userId = from.userId; + aclParams.accCaller.networkId = DmAdapter::GetInstance().ToNetworkID(from.deviceId); + + aclParams.accCallee.networkId = DmAdapter::GetInstance().ToNetworkID(targetDeviceId); + aclParams.authType = storeMeta.authType; + return true; } } - if (bundleName.empty()) { - ZLOGE("not find bundleName"); + ZLOGE("get params failed,appId:%{public}s,localDevId:%{public}s,tarDevid:%{public}s,user:%{public}d,", + from.appId.c_str(), Anonymous::Change(from.deviceId).c_str(), + Anonymous::Change(targetDeviceId).c_str(), from.userId); + return false; +} + +bool SessionManager::GetRecvAuthParams(const SessionPoint &from, const std::string &targetDeviceId, + AclParams &aclParams, int32_t peerUser) const +{ + std::vector metaData; + if (!MetaDataManager::GetInstance().LoadMeta(StoreMetaData::GetPrefix({ targetDeviceId }), metaData)) { + ZLOGE("load meta failed, deviceId:%{public}s, user:%{public}d", Anonymous::Change(targetDeviceId).c_str(), + peerUser); return false; } - return true; + for (const auto &storeMeta : metaData) { + if (storeMeta.appId == from.appId) { + auto accountId = AccountDelegate::GetInstance()->GetCurrentAccountId(); + aclParams.accCaller.bundleName = storeMeta.bundleName; + aclParams.accCaller.accountId = accountId; + aclParams.accCaller.userId = from.userId; + aclParams.accCaller.networkId = DmAdapter::GetInstance().ToNetworkID(from.deviceId); + + aclParams.accCallee.accountId = accountId; + aclParams.accCallee.userId = peerUser; + aclParams.accCallee.networkId = DmAdapter::GetInstance().ToNetworkID(targetDeviceId); + aclParams.authType = storeMeta.authType; + return true; + } + } + + ZLOGE("get params failed,appId:%{public}s,tarDevid:%{public}s,user:%{public}d,peer:%{public}d", + from.appId.c_str(), Anonymous::Change(targetDeviceId).c_str(), from.userId, peerUser); + return false; } bool SessionManager::CheckSession(const SessionPoint &from, const SessionPoint &to) const { - std::string bundleName = ""; - int32_t authType = static_cast(AuthType::DEFAULT); - if (!GetAuthParams(from, bundleName, authType)) { - ZLOGE("GetAuthParams failed"); + AclParams aclParams; + if (!GetRecvAuthParams(from, to.deviceId, aclParams, to.userId)) { + ZLOGE("get recv auth params failed:%{public}s", Anonymous::Change(to.deviceId).c_str()); return false; } - return AuthDelegate::GetInstance()->CheckAccess(from.userId, to.userId, to.deviceId, authType, false); + auto [isPermitted, isSameAccount] = AuthDelegate::GetInstance()->CheckAccess(from.userId, + to.userId, to.deviceId, aclParams); + return isPermitted; } bool Session::Marshal(json &node) const diff --git a/datamgr_service/services/distributeddataservice/app/src/session_manager/session_manager.h b/datamgr_service/services/distributeddataservice/app/src/session_manager/session_manager.h index 43c6312f..df16d859 100644 --- a/datamgr_service/services/distributeddataservice/app/src/session_manager/session_manager.h +++ b/datamgr_service/services/distributeddataservice/app/src/session_manager/session_manager.h @@ -20,8 +20,11 @@ #include #include "serializable/serializable.h" - +#include "commu_types.h" +#include "metadata/user_meta_data.h" namespace OHOS::DistributedData { +using AclParams = OHOS::AppDistributedKv::AclParams; +using DistributedData::UserStatus; struct SessionPoint { std::string deviceId; uint32_t userId; @@ -50,7 +53,10 @@ public: Session GetSession(const SessionPoint &from, const std::string &targetDeviceId) const; bool CheckSession(const SessionPoint &from, const SessionPoint &to) const; private: - bool GetAuthParams(const SessionPoint &from, std::string &bundleName, int32_t &auth) const; + bool GetSendAuthParams(const SessionPoint &from, const std::string &targetDeviceId, + AclParams &aclParams) const; + bool GetRecvAuthParams(const SessionPoint &from, const std::string &targetDeviceId, + AclParams &aclParams, int peerUser) const; }; } // namespace OHOS::DistributedData 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 65360d84..4055f30f 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,57 +87,4 @@ bool UpgradeManager::InitLocalCapability() ZLOGI("put capability meta data ret %{public}d", status); 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) -{ - if (storeDelegate == nullptr) { - ZLOGE("null store delegate"); - return; - } - auto uuids = DmAdapter::ToUUID(DmAdapter::GetInstance().GetRemoteDevices()); - if (uuids.empty()) { - ZLOGI("no remote devs"); - return; - } - - std::vector sameAccountDevs {}; - std::vector defaultAccountDevs {}; - GetIdentifierParams(sameAccountDevs, uuids, IDENTICAL_ACCOUNT); - GetIdentifierParams(defaultAccountDevs, uuids, NO_ACCOUNT); - if (!sameAccountDevs.empty()) { - auto convertedIds = AppIdMappingConfigManager::GetInstance().Convert(tuple.appId, tuple.userId); - auto identifier = - DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(convertedIds.second, - convertedIds.first, tuple.storeId); - ZLOGI("same account store:%{public}s, user:%{public}s, device:%{public}.10s, appId:%{public}s", - Anonymous::Change(tuple.storeId).c_str(), Anonymous::Change(convertedIds.second).c_str(), - DistributedData::Serializable::Marshall(sameAccountDevs).c_str(), convertedIds.first.c_str()); - storeDelegate->SetEqualIdentifier(identifier, sameAccountDevs); - } - if (!defaultAccountDevs.empty()) { - auto convertedIds = AppIdMappingConfigManager::GetInstance().Convert(tuple.appId, defaultAccountId); - auto identifier = - DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(convertedIds.second, - convertedIds.first, tuple.storeId); - ZLOGI("no account identifier, store:%{public}s, device:%{public}.10s, appId:%{public}s", - Anonymous::Change(tuple.storeId).c_str(), - DistributedData::Serializable::Marshall(defaultAccountDevs).c_str(), convertedIds.first.c_str()); - storeDelegate->SetEqualIdentifier(identifier, 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 9348fc02..411181e3 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,11 +32,6 @@ public: static UpgradeManager &GetInstance(); void Init(std::shared_ptr executors); CapMetaData GetCapability(const std::string &deviceId, bool &status); - 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 diff --git a/datamgr_service/services/distributeddataservice/app/test/unittest/kvstore_data_service_test.cpp b/datamgr_service/services/distributeddataservice/app/test/unittest/kvstore_data_service_test.cpp index 581d6f6a..4b3fe063 100644 --- a/datamgr_service/services/distributeddataservice/app/test/unittest/kvstore_data_service_test.cpp +++ b/datamgr_service/services/distributeddataservice/app/test/unittest/kvstore_data_service_test.cpp @@ -178,56 +178,3 @@ HWTEST_F(KvStoreDataServiceTest, AppExit001, TestSize.Level1) Status status = kvStoreDataServiceTest.AppExit(uid, pid, token, appId); EXPECT_EQ(status, SUCCESS); } - -/** -* @tc.name: ResolveAutoLaunchParamByIdentifier001 -* @tc.desc: -* @tc.type: FUNC -* @tc.require: -* @tc.author: wangbin -*/ -HWTEST_F(KvStoreDataServiceTest, ResolveAutoLaunchParamByIdentifier001, TestSize.Level1) -{ - KvStoreDataService kvStoreDataServiceTest; - std::string identifier = "kvstoredataservicetest"; - DistributedDB::AutoLaunchParam param; - auto status = kvStoreDataServiceTest.ResolveAutoLaunchParamByIdentifier(identifier, param); - EXPECT_EQ(status, SUCCESS); -} - -/** -* @tc.name: ConvertSecurity001 -* @tc.desc: -* @tc.type: FUNC -* @tc.require: -* @tc.author: wangbin -*/ -HWTEST_F(KvStoreDataServiceTest, ConvertSecurity001, TestSize.Level1) -{ - KvStoreDataService kvStoreDataServiceTest; - auto object = kvStoreDataServiceTest.ConvertSecurity(0); - ASSERT_NE(&object, nullptr); -} - -/** -* @tc.name: InitNbDbOption001 -* @tc.desc: -* @tc.type: FUNC -* @tc.require: -* @tc.author: wangbin -*/ -HWTEST_F(KvStoreDataServiceTest, InitNbDbOption001, TestSize.Level1) -{ - KvStoreDataService kvStoreDataServiceTest; - DistributedDB::KvStoreNbDelegate::Option dbOption; - Options options = { - .createIfMissing = false, - .encrypt = true, - .autoSync = false, - .securityLevel = 1, - }; - std::vector decryptKey; - DistributedDB::KvStoreNbDelegate::Option dbOptions; - auto status = kvStoreDataServiceTest.InitNbDbOption(options, decryptKey, dbOptions); - EXPECT_EQ(status, SUCCESS); -} \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/framework/directory/directory_manager.cpp b/datamgr_service/services/distributeddataservice/framework/directory/directory_manager.cpp index 1312cf32..ce5cf452 100644 --- a/datamgr_service/services/distributeddataservice/framework/directory/directory_manager.cpp +++ b/datamgr_service/services/distributeddataservice/framework/directory/directory_manager.cpp @@ -286,6 +286,7 @@ bool DirectoryManager::DeleteDirectory(const char* path) return true; } if (chdir(path) == -1) { + closedir(dir); return false; } while ((dirEntry = readdir(dir))) { @@ -293,6 +294,7 @@ bool DirectoryManager::DeleteDirectory(const char* path) continue; } if (stat(dirEntry->d_name, &buf) == -1) { + closedir(dir); return false; } if (S_ISDIR(buf.st_mode)) { @@ -300,6 +302,7 @@ bool DirectoryManager::DeleteDirectory(const char* path) continue; } if (remove(dirEntry->d_name) == -1) { + closedir(dir); return false; } } diff --git a/datamgr_service/services/distributeddataservice/framework/include/account/account_delegate.h b/datamgr_service/services/distributeddataservice/framework/include/account/account_delegate.h index 29a8c7e4..2f32674d 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/account/account_delegate.h +++ b/datamgr_service/services/distributeddataservice/framework/include/account/account_delegate.h @@ -32,6 +32,8 @@ enum class AccountStatus { DEVICE_ACCOUNT_DELETE, // the device account is deleted DEVICE_ACCOUNT_SWITCHED, // the device account is switched DEVICE_ACCOUNT_UNLOCKED, // the device account is unlocked + DEVICE_ACCOUNT_STOPPING, // the device account is stopping + DEVICE_ACCOUNT_STOPPED, // the device account is stopped }; struct AccountEventInfo { 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 ddc987ad..1d654f28 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/store/general_store.h +++ b/datamgr_service/services/distributeddataservice/framework/include/store/general_store.h @@ -176,7 +176,7 @@ public: virtual std::vector GetWaterVersion(const std::string &deviceId) = 0; - virtual void SetEqualIdentifier(const std::string &appId, const std::string &storeId) {}; + virtual void SetEqualIdentifier(const std::string &appId, const std::string &storeId, const std::string &account = "") {}; virtual void SetConfig(const StoreConfig &storeConfig) {}; 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 b33b7f5e..dea972be 100644 --- a/datamgr_service/services/distributeddataservice/framework/metadata/store_meta_data.cpp +++ b/datamgr_service/services/distributeddataservice/framework/metadata/store_meta_data.cpp @@ -135,7 +135,8 @@ bool StoreMetaData::operator==(const StoreMetaData &metaData) const Constant::NotEqual(isSearchable, metaData.isSearchable) || Constant::NotEqual(isNeedCompress, metaData.isNeedCompress) || Constant::NotEqual(enableCloud, metaData.enableCloud) || - Constant::NotEqual(cloudAutoSync, metaData.cloudAutoSync)) { + Constant::NotEqual(cloudAutoSync, metaData.cloudAutoSync) || + Constant::NotEqual(isManualClean, metaData.isManualClean)) { return false; } return (version == metaData.version && storeType == metaData.storeType && dataType == metaData.dataType && diff --git a/datamgr_service/services/distributeddataservice/framework/test/checker_manager_test.cpp b/datamgr_service/services/distributeddataservice/framework/test/checker_manager_test.cpp index d95a7df7..ca21b606 100644 --- a/datamgr_service/services/distributeddataservice/framework/test/checker_manager_test.cpp +++ b/datamgr_service/services/distributeddataservice/framework/test/checker_manager_test.cpp @@ -153,25 +153,6 @@ HWTEST_F(CheckerManagerTest, SystemCheckerIVI, TestSize.Level0) ASSERT_TRUE(CheckerManager::GetInstance().IsValid(info)); } -/** -* @tc.name: BundleChecker -* @tc.desc: checker the bundle name of the bundle abilities. -* @tc.type: FUNC -* @tc.require: -* @tc.author: Sven Wang -*/ -HWTEST_F(CheckerManagerTest, BundleChecker, TestSize.Level0) -{ - CheckerManager::StoreInfo storeInfo; - storeInfo.uid = 2000000; - storeInfo.tokenId = AccessTokenKit::GetHapTokenID(100, "ohos.test.demo", 0); - storeInfo.bundleName = "ohos.test.demo"; - HapTokenInfo tokenInfo; - AccessTokenKit::GetHapTokenInfo(storeInfo.tokenId, tokenInfo); - ASSERT_EQ(Crypto::Sha256(tokenInfo.appID), CheckerManager::GetInstance().GetAppId(storeInfo)); - ASSERT_TRUE(CheckerManager::GetInstance().IsValid(storeInfo)); -} - /** * @tc.name: IsDynamic * @tc.desc: checker data type. 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 2be9b510..cbd0125b 100644 --- a/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.cpp @@ -196,6 +196,7 @@ int32_t CloudServiceImpl::DoClean(const CloudInfo &cloudInfo, const std::map &selectionArgs = std::vector()) = 0; virtual std::shared_ptr QuerySql(const std::string &sql) = 0; + virtual std::pair UpdateSql(const std::string &sql) = 0; virtual bool IsInvalid() = 0; static void SetExecutorPool(std::shared_ptr executor); static void EraseStoreCache(const int32_t tokenId); diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/kv_delegate.cpp b/datamgr_service/services/distributeddataservice/service/data_share/common/kv_delegate.cpp index 23aa6a61..e9c66e2c 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/kv_delegate.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/kv_delegate.cpp @@ -42,7 +42,7 @@ const char* g_backupFiles[] = { const char* BACKUP_SUFFIX = ".backup"; // If isBackUp is true, remove db backup files. Otherwise remove source db files. -void KvDelegate::RemoveDbFile(bool isBackUp) +void KvDelegate::RemoveDbFile(bool isBackUp) const { for (auto &fileName: g_backupFiles) { std::string dbPath = path_ + "/" + fileName; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/common/kv_delegate.h b/datamgr_service/services/distributeddataservice/service/data_share/common/kv_delegate.h index 13499f70..3ec92c7c 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/common/kv_delegate.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/common/kv_delegate.h @@ -46,7 +46,7 @@ private: bool RestoreIfNeed(int32_t dbStatus); void Backup(); void Restore(); - void RemoveDbFile(bool isBackUp); + void RemoveDbFile(bool isBackUp) const; bool CopyFile(bool isBackup); std::recursive_mutex mutex_; std::string path_; 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 df25e901..3b8203b4 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 @@ -90,15 +90,10 @@ std::pair RdbDelegate::GetConfig(const DistributedData::Sto } RdbDelegate::RdbDelegate(const DistributedData::StoreMetaData &meta, int version, - bool registerFunction, const std::string &extUriData, const std::string &backup) + bool registerFunction, const std::string &extUri, const std::string &backup) + : tokenId_(meta.tokenId), bundleName_(meta.bundleName), storeName_(meta.storeId), + haMode_(meta.haMode), extUri_(extUri), backup_(backup) { - tokenId_ = meta.tokenId; - bundleName_ = meta.bundleName; - storeName_ = meta.storeId; - extUri_ = extUriData; - haMode_ = meta.haMode; - backup_ = backup; - auto [err, config] = GetConfig(meta, registerFunction); if (err != E_OK) { ZLOGW("Get rdbConfig failed, errCode is %{public}d, dir is %{public}s", err, @@ -290,6 +285,22 @@ std::shared_ptr RdbDelegate::QuerySql(const std::string &s return resultSet; } +std::pair RdbDelegate::UpdateSql(const std::string &sql) +{ + if (store_ == nullptr) { + ZLOGE("store is null"); + return std::make_pair(E_ERROR, 0); + } + auto[ret, outValue] = store_->Execute(sql); + if (ret != E_OK) { + ZLOGE("execute update sql failed, err:%{public}d", ret); + return std::make_pair(ret, 0); + } + int64_t rowCount = 0; + outValue.GetLong(rowCount); + return std::make_pair(ret, rowCount); +} + bool RdbDelegate::IsInvalid() { return store_ == 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 b73ac308..b65e6f9a 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 @@ -38,6 +38,7 @@ public: const int32_t callingPid) override; std::string Query(const std::string &sql, const std::vector &selectionArgs) override; std::shared_ptr QuerySql(const std::string &sql) override; + std::pair UpdateSql(const std::string &sql) override; bool IsInvalid() override; std::pair InsertEx(const std::string &tableName, const DataShareValuesBucket &valuesBucket) override; 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 e02fec3b..8ed18697 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 @@ -91,7 +91,7 @@ void SchedulerManager::DestoryTimerTask(int64_t timerId) void SchedulerManager::ResetTimerTask(int64_t timerId, int64_t reminderTime) { - TimeServiceClient::GetInstance()->StopTimer(timerId); + // This start also means reset, new one will replace old one TimeServiceClient::GetInstance()->StartTimer(timerId, static_cast(reminderTime)); } diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data/template_data.cpp b/datamgr_service/services/distributeddataservice/service/data_share/data/template_data.cpp index f99bec09..baf5dc4d 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data/template_data.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/data/template_data.cpp @@ -18,18 +18,20 @@ namespace OHOS::DataShare { bool TemplateNode::Marshal(DistributedData::Serializable::json &node) const { - bool ret = SetValue(node[GET_NAME(predicates)], predicates); + bool ret = SetValue(node[GET_NAME(update)], update); + ret = SetValue(node[GET_NAME(predicates)], predicates); ret = ret && SetValue(node[GET_NAME(scheduler)], scheduler); return ret; } bool TemplateNode::Unmarshal(const DistributedData::Serializable::json &node) { - bool ret = GetValue(node, GET_NAME(predicates), predicates); + bool ret = GetValue(node, GET_NAME(update), update); + ret = GetValue(node, GET_NAME(predicates), predicates); return ret && GetValue(node, GET_NAME(scheduler), scheduler); } -TemplateNode::TemplateNode(const Template &tpl) : scheduler(tpl.scheduler_) +TemplateNode::TemplateNode(const Template &tpl) : update(tpl.update_), scheduler(tpl.scheduler_) { for (auto &item:tpl.predicates_) { predicates.emplace_back(item.key_, item.selectSql_); @@ -42,7 +44,7 @@ Template TemplateNode::ToTemplate() const for (const auto &predicate: predicates) { nodes.emplace_back(predicate.key, predicate.selectSql); } - return Template(nodes, scheduler); + return Template(update, nodes, scheduler); } bool TemplateRootNode::Marshal(DistributedData::Serializable::json &node) const diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data/template_data.h b/datamgr_service/services/distributeddataservice/service/data_share/data/template_data.h index 859f0d2d..f0fe0b30 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data/template_data.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/data/template_data.h @@ -36,6 +36,7 @@ struct TemplateNode final: public DistributedData::Serializable { bool Unmarshal(const json &node) override; Template ToTemplate() const; private: + std::string update; std::vector predicates; std::string scheduler; }; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_share_obs_proxy.cpp b/datamgr_service/services/distributeddataservice/service/data_share/data_share_obs_proxy.cpp index ce644032..769ea0b3 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_share_obs_proxy.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_share_obs_proxy.cpp @@ -15,13 +15,124 @@ #define LOG_TAG "ObserverProxy" #include "data_share_obs_proxy.h" +#include "datashare_errno.h" #include "itypes_util.h" +#include "datashare_itypes_utils.h" #include "log_print.h" namespace OHOS { namespace DataShare { static constexpr int REQUEST_CODE = 0; +int RdbObserverProxy::CreateAshmem(RdbChangeNode &changeNode) +{ + OHOS::sptr memory = Ashmem::CreateAshmem(ASHMEM_NAME, DATA_SIZE_ASHMEM_TRANSFER_LIMIT); + if (memory == nullptr) { + ZLOGE("failed to create Ashmem instance."); + return E_ERROR; + } + bool mapRet = memory->MapReadAndWriteAshmem(); + if (!mapRet) { + ZLOGE("failed to map read and write ashmem, ret=%{public}d", mapRet); + memory->CloseAshmem(); + return E_ERROR; + } + if (changeNode.memory_ != nullptr) { + ZLOGE( + "Unknown error: changeNode.memory_ should be null, but something is there %{public}p", + (void *)changeNode.memory_ + ); + return E_ERROR; + } + changeNode.memory_ = memory; + return E_OK; +} + +int RdbObserverProxy::WriteAshmem(RdbChangeNode &changeNode, void *data, int len, int &offset) +{ + if (changeNode.memory_ == nullptr) { + ZLOGE("changeNode memory is nullptr."); + return E_ERROR; + } + bool writeRet = changeNode.memory_->WriteToAshmem(data, len, offset); + if (!writeRet) { + ZLOGE("failed to write into ashmem, ret=%{public}d", writeRet); + changeNode.memory_->UnmapAshmem(); + changeNode.memory_->CloseAshmem(); + changeNode.memory_ = nullptr; + return E_ERROR; + } + offset += len; + return E_OK; +} + +int RdbObserverProxy::SerializeDataIntoAshmem(RdbChangeNode &changeNode) +{ + if (changeNode.memory_ == nullptr) { + ZLOGE("changeNode.memory_ is nullptr"); + return E_ERROR; + } + // move data + // simple serialization: [vec_size(int32); str1_len(int32), str1; str2_len(int32), str2; ...], + // total byte size is recorded in changeNode.size + int offset = 0; + // 4 byte for length int + int intLen = 4; + int dataSize = changeNode.data_.size(); + if (WriteAshmem(changeNode, (void *)&dataSize, intLen, offset) != E_OK) { + ZLOGE("failed to write data with len %{public}d, offset %{public}d.", intLen, offset); + return E_ERROR; + } + for (int i = 0; i < dataSize; i++) { + const char *str = changeNode.data_[i].c_str(); + int strLen = changeNode.data_[i].length(); + // write length int + if (WriteAshmem(changeNode, (void *)&strLen, intLen, offset) != E_OK) { + ZLOGE("failed to write data with index %{public}d, len %{public}d, offset %{public}d.", i, intLen, offset); + return E_ERROR; + } + // write str + if (WriteAshmem(changeNode, (void *)str, strLen, offset) != E_OK) { + ZLOGE("failed to write data with index %{public}d, len %{public}d, offset %{public}d.", i, strLen, offset); + return E_ERROR; + } + } + changeNode.size_ = offset; + return E_OK; +} + +int RdbObserverProxy::PrepareRdbChangeNodeData(RdbChangeNode &changeNode) +{ + // If data size is bigger than the limit, move it to the shared memory + // 4 byte for length int + int intByteLen = 4; + int size = intByteLen; + for (int i = 0; i < changeNode.data_.size(); i++) { + size += intByteLen; + size += changeNode.data_[i].length(); + } + if (size > DATA_SIZE_ASHMEM_TRANSFER_LIMIT) { + ZLOGE("Data to write into ashmem is %{public}d bytes, over 10M.", size); + return E_ERROR; + } + if (size > DATA_SIZE_IPC_TRANSFER_LIMIT) { + ZLOGD("Data size is over 200k, transfer it by the shared memory"); + if (RdbObserverProxy::CreateAshmem(changeNode) != E_OK) { + ZLOGE("failed to create ashmem."); + return E_ERROR; + } + if (RdbObserverProxy::SerializeDataIntoAshmem(changeNode) != E_OK) { + ZLOGE("failed to serialize data into ashmem."); + return E_ERROR; + } + // clear original data spot + changeNode.data_.clear(); + changeNode.isSharedMemory_ = true; + ZLOGD("Preparation done. Data size: %{public}d", changeNode.size_); + } + return E_OK; +} + void RdbObserverProxy::OnChangeFromRdb(RdbChangeNode &changeNode) { MessageParcel parcel; @@ -29,6 +140,11 @@ void RdbObserverProxy::OnChangeFromRdb(RdbChangeNode &changeNode) return; } + if (RdbObserverProxy::PrepareRdbChangeNodeData(changeNode) != E_OK) { + ZLOGE("failed to prepare RdbChangeNode data."); + return; + } + if (!ITypesUtil::Marshal(parcel, changeNode)) { ZLOGE("failed to WriteParcelable changeNode "); return; diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_share_obs_proxy.h b/datamgr_service/services/distributeddataservice/service/data_share/data_share_obs_proxy.h index b54e0b0c..42a3f106 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_share_obs_proxy.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_share_obs_proxy.h @@ -28,6 +28,10 @@ public: void OnChangeFromRdb(RdbChangeNode &changeNode) override; private: + int PrepareRdbChangeNodeData(RdbChangeNode &changeNode); + int CreateAshmem(RdbChangeNode &changeNode); + int WriteAshmem(RdbChangeNode &changeNode, void *data, int len, int &offset); + int SerializeDataIntoAshmem(RdbChangeNode &changeNode); static inline BrokerDelegator delegator_; }; 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 fe13493f..1b31c377 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 @@ -216,7 +216,7 @@ int32_t DataShareServiceImpl::AddTemplate(const std::string &uri, const int64_t return templateStrategy_.Execute(context, [&uri, &tpltId, &tplt, &context]() -> int32_t { auto result = TemplateManager::GetInstance().Add( Key(uri, tpltId.subscriberId_, tpltId.bundleName_), context->currentUserId, tplt); - RdbSubscriberManager::GetInstance().Emit(context->uri, tpltId.subscriberId_, context); + RdbSubscriberManager::GetInstance().Emit(context->uri, tpltId.subscriberId_, tpltId.bundleName_, context); return result; }); } 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 df4b59e5..fca1209d 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 @@ -117,7 +117,7 @@ int32_t DataShareServiceStub::OnAddTemplate(MessageParcel &data, MessageParcel & std::string uri; int64_t subscriberId; Template tpl; - if (!ITypesUtil::Unmarshal(data, uri, subscriberId, tpl.predicates_, tpl.scheduler_)) { + if (!ITypesUtil::Unmarshal(data, uri, subscriberId, tpl.update_, tpl.predicates_, tpl.scheduler_)) { ZLOGW("read device list failed."); return -1; } diff --git a/datamgr_service/services/distributeddataservice/service/data_share/data_share_types_util.cpp b/datamgr_service/services/distributeddataservice/service/data_share/data_share_types_util.cpp index 804a6f76..32f850f1 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/data_share_types_util.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/data_share_types_util.cpp @@ -85,7 +85,21 @@ bool Unmarshalling(PredicateTemplateNode &predicateTemplateNode, MessageParcel & template<> bool Marshalling(const RdbChangeNode &changeNode, MessageParcel &parcel) { - return ITypesUtil::Marshal(parcel, changeNode.uri_, changeNode.templateId_, changeNode.data_); + bool firstPart = ITypesUtil::Marshal( + parcel, changeNode.uri_, changeNode.templateId_, changeNode.data_, changeNode.isSharedMemory_); + if (!firstPart) { + return false; + } + if (changeNode.isSharedMemory_) { + if (changeNode.memory_ == nullptr) { + ZLOGE("Used shared memory but ashmem is nullptr."); + return false; + } + if (!parcel.WriteAshmem(changeNode.memory_)) { + return false; + } + } + return ITypesUtil::Marshal(parcel, changeNode.size_); } template<> 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 630e721f..9608475a 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 @@ -343,6 +343,13 @@ int RdbSubscriberManager::Notify(const Key &key, int32_t userId, const std::vect } changeNode.data_.emplace_back("{\"" + predicate.key_ + "\":" + result + "}"); } + if (!tpl.update_.empty()) { + auto [errCode, rowCount] = delegate->UpdateSql(tpl.update_); + if (errCode != E_OK) { + ZLOGE("Update failed, err:%{public}d, %{public}s, %{public}" PRId64 ", %{public}s", + errCode, DistributedData::Anonymous::Change(key.uri).c_str(), key.subscriberId, key.bundleName.c_str()); + } + } ZLOGI("emit, valSize: %{public}zu, dataSize:%{public}zu, uri:%{public}s,", val.size(), changeNode.data_.size(), DistributedData::Anonymous::Change(changeNode.uri_).c_str()); @@ -359,7 +366,8 @@ void RdbSubscriberManager::Clear() rdbCache_.Clear(); } -void RdbSubscriberManager::Emit(const std::string &uri, int64_t subscriberId, std::shared_ptr context) +void RdbSubscriberManager::Emit(const std::string &uri, int64_t subscriberId, + const std::string &bundleName, std::shared_ptr context) { if (!URIUtils::IsDataProxyURI(uri)) { return; @@ -376,8 +384,9 @@ void RdbSubscriberManager::Emit(const std::string &uri, int64_t subscriberId, st SetObserverNotifyOnEnabled(val); return false; }); - SchedulerManager::GetInstance().Execute( - uri, context->currentUserId, context->calledSourceDir, context->version, context->calledBundleName); + Key executeKey(uri, subscriberId, bundleName); + SchedulerManager::GetInstance().Execute(executeKey, context->currentUserId, + context->calledSourceDir, context->version); } RdbSubscriberManager::ObserverNode::ObserverNode(const sptr &observer, uint32_t firstCallerTokenId, uint32_t callerTokenId) diff --git a/datamgr_service/services/distributeddataservice/service/data_share/subscriber_managers/rdb_subscriber_manager.h b/datamgr_service/services/distributeddataservice/service/data_share/subscriber_managers/rdb_subscriber_manager.h index 94355e6f..108c01d6 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/subscriber_managers/rdb_subscriber_manager.h +++ b/datamgr_service/services/distributeddataservice/service/data_share/subscriber_managers/rdb_subscriber_manager.h @@ -61,7 +61,8 @@ public: void Delete(uint32_t callerTokenId); int Disable(const Key &key, uint32_t firstCallerTokenId); int Enable(const Key &key, std::shared_ptr context); - void Emit(const std::string &uri, int64_t subscriberId, std::shared_ptr context); + void Emit(const std::string &uri, int64_t subscriberId, const std::string &bundleName, + std::shared_ptr context); void Emit(const std::string &uri, std::shared_ptr context); void Emit(const std::string &uri, int32_t userId, DistributedData::StoreMetaData &metaData); void EmitByKey(const Key &key, int32_t userId, const std::string &rdbPath, int version); diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/auth_delegate.cpp b/datamgr_service/services/distributeddataservice/service/kvdb/auth_delegate.cpp index fc72e1cf..234a1698 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/auth_delegate.cpp +++ b/datamgr_service/services/distributeddataservice/service/kvdb/auth_delegate.cpp @@ -30,16 +30,21 @@ using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; class AuthHandlerStub : public AuthHandler { public: // override for mock auth in current version, need remove in the future - bool CheckAccess( - int localUserId, int peerUserId, const std::string &peerDeviceId, - int32_t authType, bool isSend = true) override; + std::pair CheckAccess(int localUserId, int peerUserId, const std::string &peerDeviceId, + const AclParams &aclParams) override; private: bool IsUserActive(const std::vector &users, int32_t userId); bool CheckUsers(int localUserId, int peerUserId, const std::string &peerDeviceId); + bool IsSystemUser(int localUserId, int peerUserId); static constexpr pid_t UID_CAPACITY = 10000; static constexpr int SYSTEM_USER = 0; }; +bool AuthHandlerStub::IsSystemUser(int localUserId, int peerUserId) +{ + return localUserId == SYSTEM_USER && peerUserId == SYSTEM_USER; +} + bool AuthHandlerStub::CheckUsers(int localUserId, int peerUserId, const std::string &peerDeviceId) { if (localUserId == SYSTEM_USER) { @@ -51,15 +56,37 @@ bool AuthHandlerStub::CheckUsers(int localUserId, int peerUserId, const std::str return peerUserId != SYSTEM_USER && IsUserActive(localUsers, localUserId) && IsUserActive(peerUsers, peerUserId); } -bool AuthHandlerStub::CheckAccess( - int localUserId, int peerUserId, const std::string &peerDeviceId, int32_t authType, bool isSend) +std::pair AuthHandlerStub::CheckAccess(int localUserId, int peerUserId, const std::string &peerDeviceId, + const AclParams &aclParams) { - if (authType == static_cast(DistributedKv::AuthType::IDENTICAL_ACCOUNT) && - !DmAdapter::GetInstance().IsSameAccount(peerDeviceId)) { - ZLOGE("CheckAccess failed."); - return false; + if (IsSystemUser(localUserId, peerUserId)) { + return std::make_pair(true, false); + } + if (!CheckUsers(localUserId, peerUserId, peerDeviceId)) { + return std::make_pair(false, false); + } + if (!DmAdapter::GetInstance().IsOHOSType(peerDeviceId)) { + return std::make_pair(true, false); + } + if (aclParams.authType == static_cast(DistributedKv::AuthType::DEFAULT)) { + if (DmAdapter::GetInstance().IsSameAccount(aclParams.accCaller, aclParams.accCallee)) { + return std::make_pair(true, true); + } + if (DmAdapter::GetInstance().CheckAccessControl(aclParams.accCaller, aclParams.accCallee)) { + return std::make_pair(true, false); + } + ZLOGE("CheckAccess failed. bundleName:%{public}s, localUser:%{public}d, peerUser:%{public}d", + aclParams.accCaller.bundleName.c_str(), localUserId, peerUserId); + return std::make_pair(false, false); + } + + if (aclParams.authType == static_cast(DistributedKv::AuthType::IDENTICAL_ACCOUNT)) { + auto isSameAccount = DmAdapter::GetInstance().IsSameAccount(aclParams.accCaller, aclParams.accCallee); + return std::make_pair(isSameAccount, isSameAccount); } - return CheckUsers(localUserId, peerUserId, peerDeviceId); + ZLOGE("CheckAccess failed.bundleName:%{public}s,peerDeviceId:%{public}s,authtype:%{public}d", + aclParams.accCaller.bundleName.c_str(), Anonymous::Change(peerDeviceId).c_str(), aclParams.authType); + return std::make_pair(false, false); } bool AuthHandlerStub::IsUserActive(const std::vector &users, int32_t userId) diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/auth_delegate.h b/datamgr_service/services/distributeddataservice/service/kvdb/auth_delegate.h index 11a93199..199b7e74 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/auth_delegate.h +++ b/datamgr_service/services/distributeddataservice/service/kvdb/auth_delegate.h @@ -20,7 +20,9 @@ #include "metadata/user_meta_data.h" #include "serializable/serializable.h" +#include "commu_types.h" namespace OHOS::DistributedData { +using AclParams = OHOS::AppDistributedKv::AclParams; enum AUTH_GROUP_TYPE { ALL_GROUP = 0, IDENTICAL_ACCOUNT_GROUP = 1, @@ -31,8 +33,8 @@ enum AUTH_GROUP_TYPE { class AuthHandler { public: - virtual bool CheckAccess( - int localUserId, int peerUserId, const std::string &peerDeviceId, int32_t authType, bool isSend = true); + virtual std::pair CheckAccess(int localUserId, int peerUserId, + const std::string &peerDeviceId, const AclParams &aclParams); }; class AuthDelegate { 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 ab5ab9a0..f40aeab4 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_general_store.cpp +++ b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_general_store.cpp @@ -423,7 +423,7 @@ int32_t KVDBGeneralStore::Sync(const Devices &devices, GenQuery &query, DetailAs return ConvertStatus(dbStatus); } -void KVDBGeneralStore::SetEqualIdentifier(const std::string &appId, const std::string &storeId) +void KVDBGeneralStore::SetEqualIdentifier(const std::string &appId, const std::string &storeId, const std::string &account) { std::shared_lock lock(rwMutex_); if (delegate_ == nullptr) { @@ -434,10 +434,14 @@ void KVDBGeneralStore::SetEqualIdentifier(const std::string &appId, const std::s std::vector sameAccountDevs{}; std::vector defaultAccountDevs{}; auto uuids = DMAdapter::ToUUID(DMAdapter::GetInstance().GetRemoteDevices()); + if (uuids.empty()) { + ZLOGI("no remote device to sync.appId:%{public}s", appId.c_str()); + return; + } GetIdentifierParams(sameAccountDevs, uuids, IDENTICAL_ACCOUNT); GetIdentifierParams(defaultAccountDevs, uuids, NO_ACCOUNT); if (!sameAccountDevs.empty()) { - auto accountId = AccountDelegate::GetInstance()->GetUnencryptedAccountId(); + auto accountId = account.empty() ? AccountDelegate::GetInstance()->GetUnencryptedAccountId() : account; auto convertedIds = AppIdMappingConfigManager::GetInstance().Convert(appId, accountId); auto identifier = KvManager::GetKvStoreIdentifier(convertedIds.second, convertedIds.first, storeId); ZLOGI("same account store:%{public}s, user:%{public}s, device:%{public}.10s, appId:%{public}s", 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 8caa063b..5a84a0f2 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_general_store.h +++ b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_general_store.h @@ -73,7 +73,7 @@ public: int32_t MergeMigratedData(const std::string &tableName, VBuckets &&values) override; int32_t CleanTrackerData(const std::string &tableName, int64_t cursor) override; std::vector GetWaterVersion(const std::string &deviceId) override; - void SetEqualIdentifier(const std::string &appId, const std::string &storeId) override; + void SetEqualIdentifier(const std::string &appId, const std::string &storeId, const std::string &account = "") override; void SetConfig(const StoreConfig &storeConfig) override; void SetExecutor(std::shared_ptr executor) override; static DBPassword GetDBPassword(const StoreMetaData &data); 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 00911ffe..2efbeeaf 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp @@ -49,6 +49,7 @@ #include "utils/constant.h" #include "utils/converter.h" #include "water_version_manager.h" +#include "app_id_mapping/app_id_mapping_config_manager.h" namespace OHOS::DistributedKv { using namespace OHOS::DistributedData; @@ -58,6 +59,7 @@ using system_clock = std::chrono::system_clock; using DMAdapter = DistributedData::DeviceManagerAdapter; using DumpManager = OHOS::DistributedData::DumpManager; using CommContext = OHOS::DistributedData::CommunicatorContext; +using SecretKeyMeta = DistributedData::SecretKeyMetaData; static constexpr const char *DEFAULT_USER_ID = "0"; __attribute__((used)) KVDBServiceImpl::Factory KVDBServiceImpl::factory_; KVDBServiceImpl::Factory::Factory() @@ -753,31 +755,57 @@ int32_t KVDBServiceImpl::OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const return SUCCESS; } +bool KVDBServiceImpl::CompareTripleIdentifier(const std::string &accountId, const std::string &identifier, + const StoreMetaData &storeMeta) +{ + std::vector accountIds { accountId, "ohosAnonymousUid", "default" }; + for (auto &id : accountIds) { + auto convertedIds = + AppIdMappingConfigManager::GetInstance().Convert(storeMeta.appId, storeMeta.user); + const std::string &tempTripleIdentifier = + DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(id, convertedIds.first, + storeMeta.storeId, false); + if (tempTripleIdentifier == identifier) { + ZLOGI("find triple identifier,storeId:%{public}s,id:%{public}s", + Anonymous::Change(storeMeta.storeId).c_str(), Anonymous::Change(id).c_str()); + return true; + } + } + return false; +} + int32_t KVDBServiceImpl::ResolveAutoLaunch(const std::string &identifier, DBLaunchParam ¶m) { ZLOGI("user:%{public}s appId:%{public}s storeId:%{public}s identifier:%{public}s", param.userId.c_str(), param.appId.c_str(), Anonymous::Change(param.storeId).c_str(), Anonymous::Change(identifier).c_str()); + std::vector metaData; - auto prefix = StoreMetaData::GetPrefix({ DMAdapter::GetInstance().GetLocalDevice().uuid, param.userId }); + auto prefix = StoreMetaData::GetPrefix({ DMAdapter::GetInstance().GetLocalDevice().uuid }); if (!MetaDataManager::GetInstance().LoadMeta(prefix, metaData)) { - ZLOGE("no store in user:%{public}s", param.userId.c_str()); + ZLOGE("no meta data appId:%{public}s", param.appId.c_str()); return STORE_NOT_FOUND; } + auto accountId = AccountDelegate::GetInstance()->GetUnencryptedAccountId(); for (const auto &storeMeta : metaData) { if (storeMeta.storeType < StoreMetaData::StoreType::STORE_KV_BEGIN || - storeMeta.storeType > StoreMetaData::StoreType::STORE_KV_END) { + storeMeta.storeType > StoreMetaData::StoreType::STORE_KV_END || + (!param.userId.empty() && (param.userId != storeMeta.user))) { continue; } auto identifierTag = DBManager::GetKvStoreIdentifier("", storeMeta.appId, storeMeta.storeId, true); - if (identifier != identifierTag) { + bool isTripleIdentifierEqual = CompareTripleIdentifier(accountId, identifier, storeMeta); + if (identifier != identifierTag && !isTripleIdentifierEqual) { continue; } auto watchers = GetWatchers(storeMeta.tokenId, storeMeta.storeId); - AutoCache::GetInstance().GetStore(storeMeta, watchers); - - ZLOGD("user:%{public}s appId:%{public}s storeId:%{public}s", storeMeta.user.c_str(), - storeMeta.bundleName.c_str(), Anonymous::Change(storeMeta.storeId).c_str()); + auto store = AutoCache::GetInstance().GetStore(storeMeta, watchers); + if (isTripleIdentifierEqual && store != nullptr) { + store->SetEqualIdentifier(storeMeta.appId, storeMeta.storeId, accountId); + } + ZLOGI("isTriple:%{public}d,storeId:%{public}s,appId:%{public}s,size:%{public}zu,user:%{public}s", + isTripleIdentifierEqual, Anonymous::Change(storeMeta.storeId).c_str(), storeMeta.storeId.c_str(), + watchers.size(), storeMeta.user.c_str()); } return SUCCESS; } @@ -973,7 +1001,7 @@ Status KVDBServiceImpl::DoSyncInOrder( if (uuids.empty()) { ZLOGW("no device seqId:0x%{public}" PRIx64 " remote:%{public}zu appId:%{public}s storeId:%{public}s", info.seqId, info.devices.size(), meta.bundleName.c_str(), Anonymous::Change(meta.storeId).c_str()); - return Status::ERROR; + return Status::DEVICE_NOT_ONLINE; } if (IsNeedMetaSync(meta, uuids)) { auto recv = DeviceMatrix::GetInstance().GetRecvLevel(uuids[0], @@ -1121,8 +1149,14 @@ Status KVDBServiceImpl::DoComplete(const StoreMetaData &meta, const SyncInfo &in 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); + if (AccessTokenKit::GetTokenTypeFlag(meta.tokenId) != TOKEN_HAP) { + for (auto &[key, status] : dbResult) { + result[key] = ConvertDbStatusNative(status); + } + } else { + for (auto &[key, status] : dbResult) { + result[key] = ConvertDbStatus(status); + } } for (const auto &device : info.devices) { auto it = result.find(device); @@ -1145,6 +1179,18 @@ Status KVDBServiceImpl::DoComplete(const StoreMetaData &meta, const SyncInfo &in return SUCCESS; } +Status KVDBServiceImpl::ConvertDbStatusNative(DBStatus status) +{ + auto innerStatus = static_cast(status); + if (innerStatus < 0) { + return static_cast(status); + } else if (status == DBStatus::COMM_FAILURE) { + return Status::DEVICE_NOT_ONLINE; + } else { + return ConvertDbStatus(status); + } +} + uint32_t KVDBServiceImpl::GetSyncDelayTime(uint32_t delay, const StoreId &storeId) { if (delay != 0) { @@ -1398,7 +1444,15 @@ Status KVDBServiceImpl::RemoveDeviceData(const AppId &appId, const StoreId &stor if (device.empty()) { ret = store->Clean({}, KVDBGeneralStore::NEARBY_DATA, ""); } else { - ret = store->Clean({ DMAdapter::GetInstance().ToUUID(device) }, KVDBGeneralStore::NEARBY_DATA, ""); + auto uuid = DMAdapter::GetInstance().ToUUID(device); + if (uuid.empty()) { + auto tokenId = IPCSkeleton::GetCallingTokenID(); + if (AccessTokenKit::GetTokenTypeFlag(tokenId) != TOKEN_HAP) { + ZLOGW("uuid convert empty! device:%{public}s", Anonymous::Change(device).c_str()); + uuid = device; + } + } + ret = store->Clean({ uuid }, KVDBGeneralStore::NEARBY_DATA, ""); } return ConvertGeneralErr(GeneralError(ret)); } 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 c2fcef04..dba6babe 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.h +++ b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.h @@ -39,6 +39,7 @@ public: using DBLaunchParam = DistributedDB::AutoLaunchParam; using Handler = std::function> &)>; using RefCount = DistributedData::RefCount; + using StoreMetaData = OHOS::DistributedData::StoreMetaData; API_EXPORT KVDBServiceImpl(); virtual ~KVDBServiceImpl(); Status GetStoreIds(const AppId &appId, std::vector &storeIds) override; @@ -77,7 +78,6 @@ public: Status RemoveDeviceData(const AppId &appId, const StoreId &storeId, const std::string &device) override; private: - using StoreMetaData = OHOS::DistributedData::StoreMetaData; using StrategyMeta = OHOS::DistributedData::StrategyMeta; using StoreMetaDataLocal = OHOS::DistributedData::StoreMetaDataLocal; using ChangeType = OHOS::DistributedData::DeviceMatrix::ChangeType; @@ -150,6 +150,9 @@ private: void TryToSync(const StoreMetaData &metaData, bool force = false); bool IsRemoteChange(const StoreMetaData &metaData, const std::string &device); bool IsOHOSType(const std::vector &ids); + Status ConvertDbStatusNative(DBStatus status); + bool CompareTripleIdentifier(const std::string &accountId, const std::string &identifier, + const StoreMetaData &storeMeta); static Factory factory_; ConcurrentMap syncAgents_; std::shared_ptr executors_; 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 6fb60685..88f61d48 100644 --- a/datamgr_service/services/distributeddataservice/service/matrix/include/device_matrix.h +++ b/datamgr_service/services/distributeddataservice/service/matrix/include/device_matrix.h @@ -88,7 +88,6 @@ public: bool IsDynamic(const StoreMetaData &metaData); bool IsStatics(const StoreMetaData &metaData); bool IsSupportMatrix(); - bool IsConsistent(); private: static constexpr uint32_t RESET_MASK_DELAY = 10; // min 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 337ae786..bfea3636 100644 --- a/datamgr_service/services/distributeddataservice/service/matrix/src/device_matrix.cpp +++ b/datamgr_service/services/distributeddataservice/service/matrix/src/device_matrix.cpp @@ -762,26 +762,4 @@ bool DeviceMatrix::IsSupportMatrix() { return isSupportBroadcast_; } - -bool DeviceMatrix::IsConsistent() -{ - std::vector metas; - if (!MetaDataManager::GetInstance().LoadMeta(MatrixMetaData::GetPrefix({}), metas, true)) { - return true; - } - for (const auto &meta : metas) { - if (meta.origin == MatrixMetaData::Origin::REMOTE_RECEIVED) { - MatrixMetaData consistentMeta; - consistentMeta.deviceId = meta.deviceId; - if (!MetaDataManager::GetInstance().LoadMeta(consistentMeta.GetConsistentKey(), consistentMeta, true)) { - return false; - } - if ((High(meta.statics) > High(consistentMeta.statics)) || - (High(meta.dynamic) > High(consistentMeta.dynamic))) { - return false; - } - } - } - return true; -} } // namespace OHOS::DistributedData \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_asset_loader.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_asset_loader.cpp index 62a1262e..5bb2e7cb 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_asset_loader.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_asset_loader.cpp @@ -77,6 +77,7 @@ void RdbAssetLoader::UpdateStatus(AssetRecord &assetRecord, const VBucket &asset for (const auto &[key, value] : assets) { auto downloadAssets = std::get_if(&value); if (downloadAssets == nullptr) { + assetRecord.status = DBStatus::CLOUD_ERROR; continue; } for (const auto &asset : *downloadAssets) { 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 3a5cf6ca..954e6ead 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.cpp @@ -136,6 +136,10 @@ RdbGeneralStore::RdbGeneralStore(const StoreMetaData &meta) static_cast(const_cast(static_cast(&meta.isManualClean))); delegate_->Pragma(PragmaCmd::LOGIC_DELETE_SYNC_DATA, data); } + ZLOGI("Get rdb store, tokenId:%{public}u, bundleName:%{public}s, storeName:%{public}s, user:%{public}s," + "isEncrypt:%{public}d, isManualClean:%{public}d, isSearchable:%{public}d", + meta.tokenId, meta.bundleName.c_str(), Anonymous::Change(meta.storeId).c_str(), meta.user.c_str(), + meta.isEncrypt, meta.isManualClean, meta.isSearchable); } RdbGeneralStore::~RdbGeneralStore() @@ -1119,7 +1123,7 @@ Executor::Task RdbGeneralStore::GetFinishTask(SyncId syncId) }); if (cb != nullptr) { ZLOGW("database:%{public}s syncId:%{public}" PRIu64 " miss finished. ", - Anonymous::Change(storeInfo_.storeName).c_str(), syncId); + Anonymous::Change(storeInfo_.storeName).c_str(), syncId); std::map result; result.insert({ "", { DistributedDB::FINISHED, DBStatus::DB_ERROR } }); cb(result); @@ -1144,7 +1148,7 @@ void RdbGeneralStore::RemoveTasks() tasks_->EraseIf([&cbs, &taskIds, store = storeInfo_.storeName](SyncId syncId, const FinishTask &task) { if (task.cb != nullptr) { ZLOGW("database:%{public}s syncId:%{public}" PRIu64 " miss finished. ", Anonymous::Change(store).c_str(), - syncId); + syncId); } cbs.push_back(std::move(task.cb)); taskIds.push_back(task.taskId); 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 7f54d05f..e35e1efc 100644 --- a/datamgr_service/services/distributeddataservice/service/test/cloud_data_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/cloud_data_test.cpp @@ -49,6 +49,7 @@ #include "store/auto_cache.h" #include "store/general_value.h" #include "store/store_info.h" +#include "sync_manager.h" #include "token_setproc.h" using namespace testing::ext; @@ -2002,5 +2003,36 @@ HWTEST_F(CloudDataTest, Report, TestSize.Level0) auto ret = cloudReport->Report(reportParam); EXPECT_TRUE(ret); } + +/** +* @tc.name: IsOn +* @tc.desc: Test IsOn. +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, IsOn, TestSize.Level0) +{ + auto cloudServerMock = std::make_shared(); + auto user = DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(OHOS::IPCSkeleton::GetCallingTokenID()); + auto cloudInfo = cloudServerMock->GetServerInfo(user, true); + int32_t instanceId = 0; + auto ret = cloudInfo.IsOn("", instanceId); + EXPECT_FALSE(ret); +} + +/** +* @tc.name: IsAllSwitchOff +* @tc.desc: Test IsAllSwitchOff. +* @tc.type: FUNC +* @tc.require: + */ +HWTEST_F(CloudDataTest, IsAllSwitchOff, TestSize.Level0) +{ + auto cloudServerMock = std::make_shared(); + auto user = DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(OHOS::IPCSkeleton::GetCallingTokenID()); + auto cloudInfo = cloudServerMock->GetServerInfo(user, true); + auto ret = cloudInfo.IsAllSwitchOff(); + EXPECT_FALSE(ret); +} } // namespace DistributedDataTest } // namespace OHOS::Test \ No newline at end of file diff --git a/datamgr_service/services/distributeddataservice/service/test/data_share_obs_proxy_test.cpp b/datamgr_service/services/distributeddataservice/service/test/data_share_obs_proxy_test.cpp new file mode 100644 index 00000000..ec335f6e --- /dev/null +++ b/datamgr_service/services/distributeddataservice/service/test/data_share_obs_proxy_test.cpp @@ -0,0 +1,318 @@ +/* +* 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 "DataShareObsProxyTest" + +#include +#include + +#include "data_share_obs_proxy.h" +#include "datashare_errno.h" +#include "log_print.h" + +namespace OHOS::Test { +using namespace testing::ext; +using namespace OHOS::DataShare; +std::string BUNDLE_NAME = "ohos.datasharetest.demo"; +constexpr int64_t TEST_SUB_ID = 100; + +class DataShareObsProxyTest : public testing::Test { +public: + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp(){}; + void TearDown(){}; +}; + +RdbChangeNode SampleRdbChangeNode() +{ + TemplateId tplId; + tplId.subscriberId_ = TEST_SUB_ID; + tplId.bundleName_ = BUNDLE_NAME; + + RdbChangeNode node; + node.uri_ = std::string(""); + node.templateId_ = tplId; + node.data_ = std::vector(); + node.isSharedMemory_ = false; + node.memory_ = nullptr; + node.size_ = 0; + + return node; +} + +/** +* @tc.name: CreateAshmem +* @tc.desc: test CreateAshmem function +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(DataShareObsProxyTest, CreateAshmem, TestSize.Level1) +{ + ZLOGI("CreateAshmem starts"); + RdbChangeNode node = SampleRdbChangeNode(); + + OHOS::sptr fake = nullptr; + RdbObserverProxy proxy(fake); + int ret = proxy.CreateAshmem(node); + EXPECT_EQ(ret, DataShare::E_OK); + EXPECT_NE(node.memory_, nullptr); + ZLOGI("CreateAshmem ends"); +} + +/** +* @tc.name: WriteAshmem001 +* @tc.desc: test WriteAshmem function. Write an int +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(DataShareObsProxyTest, WriteAshmem001, TestSize.Level1) +{ + ZLOGI("WriteAshmem001 starts"); + RdbChangeNode node = SampleRdbChangeNode(); + OHOS::sptr fake = nullptr; + RdbObserverProxy proxy(fake); + int retCreate = proxy.CreateAshmem(node); + EXPECT_EQ(retCreate, DataShare::E_OK); + + int len = 10; + int intLen = 4; + int offset = 0; + int ret = proxy.WriteAshmem(node, (void *)&len, intLen, offset); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(offset, intLen); + + // read from the start + const void *read = node.memory_->ReadFromAshmem(intLen, 0); + EXPECT_NE(read, nullptr); + int lenRead = *reinterpret_cast(read); + EXPECT_EQ(len, lenRead); + ZLOGI("WriteAshmem001 ends"); +} + +/** +* @tc.name: WriteAshmem002 +* @tc.desc: test WriteAshmem function. Write a str +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(DataShareObsProxyTest, WriteAshmem002, TestSize.Level1) +{ + ZLOGI("WriteAshmem002 starts"); + RdbChangeNode node = SampleRdbChangeNode(); + OHOS::sptr fake = nullptr; + RdbObserverProxy proxy(fake); + int retCreate = proxy.CreateAshmem(node); + EXPECT_EQ(retCreate, DataShare::E_OK); + + std::string string("Hello World"); + const char *str = string.c_str(); + int len = string.length(); + int offset = 0; + int ret = proxy.WriteAshmem(node, (void *)str, len, offset); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(offset, len); + + // read from the start + const void *read = node.memory_->ReadFromAshmem(len, 0); + EXPECT_NE(read, nullptr); + const char *strRead = reinterpret_cast(read); + std::string stringRead(strRead, len); + EXPECT_EQ(stringRead, string); + ZLOGI("WriteAshmem002 ends"); +} + +/** +* @tc.name: WriteAshmem003 +* @tc.desc: test WriteAshmem function with error +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(DataShareObsProxyTest, WriteAshmem003, TestSize.Level1) +{ + ZLOGI("WriteAshmem003 starts"); + RdbChangeNode node = SampleRdbChangeNode(); + OHOS::sptr fake = nullptr; + RdbObserverProxy proxy(fake); + + OHOS::sptr memory = Ashmem::CreateAshmem("WriteAshmem003", 2); + EXPECT_NE(memory, nullptr); + bool mapRet = memory->MapReadAndWriteAshmem(); + ASSERT_TRUE(mapRet); + node.memory_ = memory; + + int len = 10; + int offset = 0; + int ret = proxy.WriteAshmem(node, (void *)&len, 4, offset); + EXPECT_EQ(ret, E_ERROR); + ZLOGI("WriteAshmem003 ends"); +} + +/** +* @tc.name: SerializeDataIntoAshmem +* @tc.desc: test SerializeDataIntoAshmem function +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(DataShareObsProxyTest, SerializeDataIntoAshmem, TestSize.Level1) +{ + ZLOGI("SerializeDataIntoAshmem starts"); + RdbChangeNode node = SampleRdbChangeNode(); + + OHOS::sptr fake = nullptr; + RdbObserverProxy proxy(fake); + + int retCreate = proxy.CreateAshmem(node); + EXPECT_EQ(retCreate, E_OK); + + // Push three times + node.data_.push_back(BUNDLE_NAME); + node.data_.push_back(BUNDLE_NAME); + node.data_.push_back(BUNDLE_NAME); + + int intLen = 4; + // item length size + (str length size + str length) * 3 + int offset = intLen + (intLen + strlen(BUNDLE_NAME.c_str())) * 3; + int retSe = proxy.SerializeDataIntoAshmem(node); + EXPECT_EQ(retSe, E_OK); + EXPECT_EQ(node.size_, offset); + + offset = 0; + const void *vecLenRead = node.memory_->ReadFromAshmem(intLen, offset); + EXPECT_NE(vecLenRead, nullptr); + int vecLen = *reinterpret_cast(vecLenRead); + EXPECT_EQ(vecLen, 3); + offset += intLen; + + // 3 strings in the vec + for (int i = 0; i < 3; i++) { + const void *strLenRead = node.memory_->ReadFromAshmem(intLen, offset); + EXPECT_NE(strLenRead, nullptr); + int strLen = *reinterpret_cast(strLenRead); + EXPECT_EQ(strLen, BUNDLE_NAME.length()); + offset += intLen; + + const void *strRead = node.memory_->ReadFromAshmem(strLen, offset); + EXPECT_NE(strRead, nullptr); + const char *str = reinterpret_cast(strRead); + std::string stringRead(str, strLen); + EXPECT_EQ(stringRead, BUNDLE_NAME); + offset += strLen; + } + ZLOGI("SerializeDataIntoAshmem ends"); +} + +/** +* @tc.name: SerializeDataIntoAshmem002 +* @tc.desc: test SerializeDataIntoAshmem function +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(DataShareObsProxyTest, SerializeDataIntoAshmem002, TestSize.Level1) +{ + ZLOGI("SerializeDataIntoAshmem starts"); + RdbChangeNode node = SampleRdbChangeNode(); + + OHOS::sptr fake = nullptr; + RdbObserverProxy proxy(fake); + + // Push three times + node.data_.push_back(BUNDLE_NAME); + node.data_.push_back(BUNDLE_NAME); + node.data_.push_back(BUNDLE_NAME); + + // memory too small for vec length + OHOS::sptr memory = Ashmem::CreateAshmem("SerializeDataIntoAshmem002", 2); + EXPECT_NE(memory, nullptr); + bool mapRet = memory->MapReadAndWriteAshmem(); + ASSERT_TRUE(mapRet); + node.memory_ = memory; + + int retSe = proxy.SerializeDataIntoAshmem(node); + EXPECT_EQ(retSe, E_ERROR); + EXPECT_EQ(node.size_, 0); + EXPECT_EQ(node.data_.size(), 3); + ASSERT_FALSE(node.isSharedMemory_); + + // memory too small for string length + OHOS::sptr memory2 = Ashmem::CreateAshmem("SerializeDataIntoAshmem002", 6); + EXPECT_NE(memory2, nullptr); + mapRet = memory2->MapReadAndWriteAshmem(); + ASSERT_TRUE(mapRet); + node.memory_ = memory2; + + retSe = proxy.SerializeDataIntoAshmem(node); + EXPECT_EQ(retSe, E_ERROR); + EXPECT_EQ(node.size_, 0); + EXPECT_EQ(node.data_.size(), 3); + ASSERT_FALSE(node.isSharedMemory_); + + // memory too small for string + OHOS::sptr memory3 = Ashmem::CreateAshmem("SerializeDataIntoAshmem002", 10); + EXPECT_NE(memory3, nullptr); + mapRet = memory3->MapReadAndWriteAshmem(); + ASSERT_TRUE(mapRet); + node.memory_ = memory3; + + retSe = proxy.SerializeDataIntoAshmem(node); + EXPECT_EQ(retSe, E_ERROR); + EXPECT_EQ(node.size_, 0); + EXPECT_EQ(node.data_.size(), 3); + ASSERT_FALSE(node.isSharedMemory_); + + ZLOGI("SerializeDataIntoAshmem002 ends"); +} + +/** +* @tc.name: PreparationData +* @tc.desc: test PrepareRdbChangeNodeData function +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(DataShareObsProxyTest, PreparationData, TestSize.Level1) +{ + ZLOGI("PreparationData starts"); + RdbChangeNode node = SampleRdbChangeNode(); + OHOS::sptr fake = nullptr; + RdbObserverProxy proxy(fake); + + // Push three times, less than 200k + node.data_.push_back(BUNDLE_NAME); + node.data_.push_back(BUNDLE_NAME); + node.data_.push_back(BUNDLE_NAME); + + int ret = proxy.PrepareRdbChangeNodeData(node); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(node.data_.size(), 3); + EXPECT_FALSE(node.isSharedMemory_); + + // Try to fake a 200k data. BUNDLE_NAME is 23 byte long and 7587 BUNDLE_NAMEs is over 200k. + for (int i = 0; i < 7587; i++) { + node.data_.push_back(BUNDLE_NAME); + } + ret = proxy.PrepareRdbChangeNodeData(node); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(node.data_.size(), 0); + EXPECT_TRUE(node.isSharedMemory_); + + // Try to fake data over 10M. Write data of such size should fail because it exceeds the limit. + for (int i = 0; i < 388362; i++) { + node.data_.push_back(BUNDLE_NAME); + } + ret = proxy.PrepareRdbChangeNodeData(node); + EXPECT_EQ(ret, E_ERROR); + + ZLOGI("PreparationData ends"); +} +} // 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 0746d85a..7ee102b2 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 @@ -178,7 +178,7 @@ HWTEST_F(DataShareSubscriberManagersTest, Emit, TestSize.Level1) { auto context = std::make_shared(DATA_SHARE_URI_TEST); RdbSubscriberManager::GetInstance().Emit(DATA_SHARE_URI_TEST, context); - RdbSubscriberManager::GetInstance().Emit(DATA_SHARE_URI_TEST, TEST_SUB_ID, context); + RdbSubscriberManager::GetInstance().Emit(DATA_SHARE_URI_TEST, TEST_SUB_ID, BUNDLE_NAME_TEST, context); TemplateId tpltId; tpltId.subscriberId_ = TEST_SUB_ID; tpltId.bundleName_ = BUNDLE_NAME_TEST; 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 4f44b6a1..848e5900 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 @@ -128,6 +128,8 @@ ohos_fuzztest("CloudServiceStubFuzzTest") { "kv_store:distributeddata_inner", "kv_store:distributeddata_mgr", "relational_store:native_rdb", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", ] } 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 310150e2..ee4edc63 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 @@ -104,6 +104,7 @@ ohos_fuzztest("DataShareServiceStubFuzzTest") { ] external_deps = [ + "ability_base:base", "ability_base:want", "ability_base:zuri", "ability_runtime:dataobs_manager", 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 83c0d398..1aad884a 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 @@ -117,6 +117,8 @@ ohos_fuzztest("KvdbServiceStubFuzzTest") { "ipc:ipc_core", "kv_store:distributeddata_inner", "kv_store:distributeddata_mgr", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", ] } diff --git a/datamgr_service/services/distributeddataservice/service/test/kvdb_service_test.cpp b/datamgr_service/services/distributeddataservice/service/test/kvdb_service_test.cpp index 5e7d6159..2317e82b 100644 --- a/datamgr_service/services/distributeddataservice/service/test/kvdb_service_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/kvdb_service_test.cpp @@ -657,30 +657,31 @@ HWTEST_F(AuthHandlerTest, AuthHandler, TestSize.Level0) int localUserId = 0; int peerUserId = 0; std::string peerDeviceId = ""; - int32_t authType = static_cast(DistributedKv::AuthType::IDENTICAL_ACCOUNT); - bool isSend = false; - auto result = AuthDelegate::GetInstance()->CheckAccess(localUserId, peerUserId, peerDeviceId, authType, isSend); - EXPECT_FALSE(result); - authType = static_cast(DistributedKv::AuthType::DEFAULT); - result = AuthDelegate::GetInstance()->CheckAccess(localUserId, peerUserId, peerDeviceId, authType, isSend); - EXPECT_TRUE(result); - - authType = static_cast(DistributedKv::AuthType::IDENTICAL_ACCOUNT); + AclParams aclParams; + aclParams.authType = static_cast(DistributedKv::AuthType::IDENTICAL_ACCOUNT); + auto result = AuthDelegate::GetInstance()->CheckAccess(localUserId, peerUserId, peerDeviceId, aclParams); + EXPECT_TRUE(result.first); + + aclParams.authType = static_cast(DistributedKv::AuthType::DEFAULT); + result = AuthDelegate::GetInstance()->CheckAccess(localUserId, peerUserId, peerDeviceId, aclParams); + EXPECT_TRUE(result.first); + + aclParams.authType = static_cast(DistributedKv::AuthType::IDENTICAL_ACCOUNT); peerDeviceId = "peerDeviceId"; - result = AuthDelegate::GetInstance()->CheckAccess(localUserId, peerUserId, peerDeviceId, authType, isSend); - EXPECT_FALSE(result); + result = AuthDelegate::GetInstance()->CheckAccess(localUserId, peerUserId, peerDeviceId, aclParams); + EXPECT_TRUE(result.first); - authType = static_cast(DistributedKv::AuthType::DEFAULT); - result = AuthDelegate::GetInstance()->CheckAccess(localUserId, peerUserId, peerDeviceId, authType, isSend); - EXPECT_TRUE(result); + aclParams.authType = static_cast(DistributedKv::AuthType::DEFAULT); + result = AuthDelegate::GetInstance()->CheckAccess(localUserId, peerUserId, peerDeviceId, aclParams); + EXPECT_TRUE(result.first); localUserId = 1; - result = AuthDelegate::GetInstance()->CheckAccess(localUserId, peerUserId, peerDeviceId, authType, isSend); - EXPECT_FALSE(result); + result = AuthDelegate::GetInstance()->CheckAccess(localUserId, peerUserId, peerDeviceId, aclParams); + EXPECT_FALSE(result.first); peerUserId = 1; - result = AuthDelegate::GetInstance()->CheckAccess(localUserId, peerUserId, peerDeviceId, authType, isSend); - EXPECT_FALSE(result); + result = AuthDelegate::GetInstance()->CheckAccess(localUserId, peerUserId, peerDeviceId, aclParams); + EXPECT_FALSE(result.first); } } // namespace DistributedDataTest } // 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 index b4c02ebd..0e746a73 100644 --- a/datamgr_service/services/distributeddataservice/service/test/rdb_asset_loader_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/rdb_asset_loader_test.cpp @@ -180,13 +180,13 @@ HWTEST_F(RdbAssetLoaderTest, RemoveLocalAssets, TestSize.Level0) } /** -* @tc.name: PostEvent -* @tc.desc: RdbAssetLoader PostEvent abnormal +* @tc.name: PostEvent001 +* @tc.desc: RdbAssetLoader PostEvent001 test * @tc.type: FUNC * @tc.require: * @tc.author: SQL */ -HWTEST_F(RdbAssetLoaderTest, PostEvent, TestSize.Level0) +HWTEST_F(RdbAssetLoaderTest, PostEvent001, TestSize.Level0) { BindAssets bindAssets; bindAssets.bindAssets = nullptr; @@ -201,6 +201,53 @@ HWTEST_F(RdbAssetLoaderTest, PostEvent, TestSize.Level0) EXPECT_EQ(result, DistributedDB::DBStatus::CLOUD_ERROR); } +/** +* @tc.name: PostEvent002 +* @tc.desc: RdbAssetLoader PostEvent002 test +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbAssetLoaderTest, PostEvent002, TestSize.Level0) +{ + DistributedData::Asset asset; + asset.name = ""; + asset.id = ""; + asset.path = ""; + asset.uri = ""; + asset.modifyTime = ""; + asset.createTime = ""; + asset.size = ""; + asset.hash = ""; + asset.status = DistributedData::Asset::STATUS_DELETE; + + DistributedData::Assets assets; + assets.push_back(asset); + BindAssets bindAssets; + bindAssets.bindAssets = nullptr; + std::shared_ptr assetLoader = std::make_shared(); + DistributedRdb::RdbAssetLoader rdbAssetLoader(assetLoader, &bindAssets); + std::set skipAssets; + std::set deleteAssets; + rdbAssetLoader.PostEvent(DistributedData::AssetEvent::DOWNLOAD, assets, skipAssets, deleteAssets); + EXPECT_EQ(deleteAssets.size(), 1); +} + +/** +* @tc.name: ConvertStatus +* @tc.desc: RdbAssetLoader ConvertStatus abnormal +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbAssetLoaderTest, ConvertStatus, TestSize.Level0) +{ + auto status = RdbAssetLoader::ConvertStatus(DistributedRdb::RdbAssetLoader::AssetStatus::STATUS_DOWNLOADING); + EXPECT_EQ(status, DistributedDB::DBStatus::OK); + status = RdbAssetLoader::ConvertStatus(DistributedRdb::RdbAssetLoader::AssetStatus::STATUS_BUTT); + EXPECT_EQ(status, DistributedDB::DBStatus::CLOUD_ERROR); +} + /** * @tc.name: RdbWatcher * @tc.desc: RdbWatcher function test. diff --git a/datamgr_service/services/distributeddataservice/service/test/rdb_cloud_test.cpp b/datamgr_service/services/distributeddataservice/service/test/rdb_cloud_test.cpp index cdfa288e..7f945e15 100644 --- a/datamgr_service/services/distributeddataservice/service/test/rdb_cloud_test.cpp +++ b/datamgr_service/services/distributeddataservice/service/test/rdb_cloud_test.cpp @@ -136,6 +136,30 @@ HWTEST_F(RdbCloudTest, RdbCloudTest003, TestSize.Level1) EXPECT_EQ(result, DBStatus::CLOUD_ERROR); } +/** +* @tc.name: RdbCloudTest004 +* @tc.desc: RdbCloud UnLockCloudDB LockCloudDB InnerUnLock test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbCloudTest, RdbCloudTest004, TestSize.Level1) +{ + BindAssets bindAssets; + std::shared_ptr cloudDB = std::make_shared(); + RdbCloud rdbCloud(cloudDB, &bindAssets); + + auto err = rdbCloud.UnLockCloudDB(OHOS::DistributedRdb::RdbCloud::FLAG::SYSTEM_ABILITY); + EXPECT_EQ(err, GeneralError::E_NOT_SUPPORT); + + auto result = rdbCloud.LockCloudDB(OHOS::DistributedRdb::RdbCloud::FLAG::SYSTEM_ABILITY); + EXPECT_EQ(result.first, GeneralError::E_NOT_SUPPORT); + + rdbCloud.flag_ = 1; + err = rdbCloud.InnerUnLock(static_cast(0)); + EXPECT_EQ(err, GeneralError::E_OK); +} + /** * @tc.name: ConvertStatus * @tc.desc: RdbCloud ConvertStatus function test. @@ -160,6 +184,16 @@ HWTEST_F(RdbCloudTest, ConvertStatus, TestSize.Level1) EXPECT_EQ(result, DBStatus::CLOUD_ASSET_SPACE_INSUFFICIENT); result = rdbCloud.ConvertStatus(GeneralError::E_RECORD_EXIST_CONFLICT); EXPECT_EQ(result, DBStatus::CLOUD_RECORD_EXIST_CONFLICT); + result = rdbCloud.ConvertStatus(GeneralError::E_VERSION_CONFLICT); + EXPECT_EQ(result, DBStatus::CLOUD_VERSION_CONFLICT); + result = rdbCloud.ConvertStatus(GeneralError::E_RECORD_NOT_FOUND); + EXPECT_EQ(result, DBStatus::CLOUD_RECORD_NOT_FOUND); + result = rdbCloud.ConvertStatus(GeneralError::E_RECORD_ALREADY_EXISTED); + EXPECT_EQ(result, DBStatus::CLOUD_RECORD_ALREADY_EXISTED); + result = rdbCloud.ConvertStatus(GeneralError::E_FILE_NOT_EXIST); + EXPECT_EQ(result, DBStatus::LOCAL_ASSET_NOT_FOUND); + result = rdbCloud.ConvertStatus(GeneralError::E_TIME_OUT); + EXPECT_EQ(result, DBStatus::TIME_OUT); } /** @@ -191,5 +225,38 @@ HWTEST_F(RdbCloudTest, BlobToAssets, TestSize.Level1) auto results = rdbTranslate.BlobToAssets(blob); EXPECT_EQ(results, assets); } + +/** +* @tc.name: ConvertQuery +* @tc.desc: RdbCloud ConvertQuery function test. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(RdbCloudTest, ConvertQuery, TestSize.Level1) +{ + RdbCloud::DBQueryNodes nodes; + DistributedDB::QueryNode node = { DistributedDB::QueryNodeType::IN, "", {int64_t(1)} }; + nodes.push_back(node); + node = { DistributedDB::QueryNodeType::OR, "", {int64_t(1)} }; + nodes.push_back(node); + node = { DistributedDB::QueryNodeType::AND, "", {int64_t(1)} }; + nodes.push_back(node); + node = { DistributedDB::QueryNodeType::EQUAL_TO, "", {int64_t(1)} }; + nodes.push_back(node); + node = { DistributedDB::QueryNodeType::BEGIN_GROUP, "", {int64_t(1)} }; + nodes.push_back(node); + node = { DistributedDB::QueryNodeType::END_GROUP, "", {int64_t(1)} }; + nodes.push_back(node); + + auto result = RdbCloud::ConvertQuery(std::move(nodes)); + EXPECT_EQ(result.size(), 6); + + nodes.clear(); + node = { DistributedDB::QueryNodeType::ILLEGAL, "", {int64_t(1)} }; + nodes.push_back(node); + result = RdbCloud::ConvertQuery(std::move(nodes)); + EXPECT_EQ(result.size(), 0); +} } // namespace DistributedRDBTest } // namespace OHOS::Test \ No newline at end of file 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 b89ab80f..5fa055cf 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/preprocess/preprocess_utils.cpp @@ -197,7 +197,6 @@ int32_t PreProcessUtils::SetRemoteUri(uint32_t tokenId, UnifiedData &data) BizScene::SET_DATA, SetDataStage::GERERATE_DFS_URI, StageRes::FAILED, 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; } } return E_OK; 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 cb0f3762..edbdc54e 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.cpp @@ -273,24 +273,23 @@ bool UdmfServiceImpl::IsReadAndKeep(const std::vector &privileges, co int32_t UdmfServiceImpl::ProcessUri(const QueryOption &query, UnifiedData &unifiedData) { std::string localDeviceId = PreProcessUtils::GetLocalDeviceId(); - auto records = unifiedData.GetRecords(); - if (unifiedData.GetRuntime() == nullptr) { - return E_DB_ERROR; - } - std::string sourceDeviceId = unifiedData.GetRuntime()->deviceId; - if (localDeviceId != sourceDeviceId) { - SetRemoteUri(query, records); + int32_t verifyRes = ProcessCrossDeviceData(unifiedData); + if (verifyRes != E_OK) { + ZLOGE("verify unifieddata fail, key=%{public}s, stauts=%{public}d", query.key.c_str(), verifyRes); + return verifyRes; } 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; } + std::string sourceDeviceId = unifiedData.GetRuntime()->deviceId; 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; + auto records = unifiedData.GetRecords(); for (auto record : records) { if (record != nullptr && PreProcessUtils::IsFileType(record->GetType())) { auto file = static_cast(record.get()); @@ -315,25 +314,36 @@ int32_t UdmfServiceImpl::ProcessUri(const QueryOption &query, UnifiedData &unifi RadarReporterAdapter::ReportFail(std::string(__FUNCTION__), BizScene::GET_DATA, GetDataStage::GRANT_URI_PERMISSION, StageRes::FAILED, E_NO_PERMISSION); ZLOGE("GrantUriPermission fail, bundleName=%{public}s, key=%{public}s.", - bundleName.c_str(), query.key.c_str()); + bundleName.c_str(), query.key.c_str()); return E_NO_PERMISSION; } return E_OK; } -void UdmfServiceImpl::SetRemoteUri(const QueryOption &query, std::vector> &records) +int32_t UdmfServiceImpl::ProcessCrossDeviceData(UnifiedData &unifiedData) { + if (unifiedData.GetRuntime() == nullptr) { + ZLOGE("Get runtime empty!"); + return E_DB_ERROR; + } + std::string localDeviceId = PreProcessUtils::GetLocalDeviceId(); + std::string sourceDeviceId = unifiedData.GetRuntime()->deviceId; + if (localDeviceId == sourceDeviceId) { + return E_OK; + } + auto records = unifiedData.GetRecords(); for (auto record : records) { if (record != nullptr && PreProcessUtils::IsFileType(record->GetType())) { auto file = static_cast(record.get()); std::string remoteUri = file->GetRemoteUri(); if (remoteUri.empty()) { - ZLOGW("Get remoteUri is empyt, key=%{public}s.", query.key.c_str()); - continue; + ZLOGE("when cross devices, remote uri is required!"); + return E_ERROR; } file->SetUri(remoteUri); // cross dev, need dis path. } } + return E_OK; } int32_t UdmfServiceImpl::GetBatchData(const QueryOption &query, std::vector &unifiedDataSet) 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 a3095c9c..f121fc99 100644 --- a/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.h +++ b/datamgr_service/services/distributeddataservice/service/udmf/udmf_service_impl.h @@ -59,9 +59,9 @@ private: int32_t RetrieveData(const QueryOption &query, UnifiedData &unifiedData); int32_t QueryDataCommon(const QueryOption &query, std::vector &dataSet, std::shared_ptr &store); int32_t ProcessUri(const QueryOption &query, UnifiedData &unifiedData); - void SetRemoteUri(const QueryOption &query, std::vector> &records); bool IsPermissionInCache(const QueryOption &query); bool IsReadAndKeep(const std::vector &privileges, const QueryOption &query); + int32_t ProcessCrossDeviceData(UnifiedData &unifiedData); class Factory { public: 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 2275f7c7..30a564ca 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 @@ -1195,37 +1195,6 @@ HWTEST_F(SingleKvStoreClientTest, UnSubscribeWithQuery001, TestSize.Level1) EXPECT_NE(unSubscribeStatus, Status::SUCCESS) << "sync device should not return success"; } -/** - * @tc.name: CloudSync001 - * desc: create kv store which supports cloud sync and execute CloudSync interface - * type: FUNC - * require: - * author:taoyuxin - */ -HWTEST_F(SingleKvStoreClientTest, CloudSync001, 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.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_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 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 b5f12015..e0bc7f58 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp +++ b/kv_store/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp @@ -57,13 +57,7 @@ SingleStoreImpl::SingleStoreImpl( uint32_t tokenId = IPCSkeleton::GetSelfTokenID(); if (AccessTokenKit::GetTokenTypeFlag(tokenId) == TOKEN_HAP) { isApplication_ = true; - HapTokenInfo hapTokenInfo; - auto ret = AccessTokenKit::GetHapTokenInfo(tokenId, hapTokenInfo); - if (ret == 0) { - apiVersion_ = hapTokenInfo.apiVersion; - } else { - ZLOGE("GetHapTokenInfo fail, tokenId:%{public}d, ret:%{public}d", tokenId, ret); - } + apiVersion_ = options.apiVersion; } } @@ -762,7 +756,7 @@ int32_t SingleStoreImpl::Close(bool isForce) Status SingleStoreImpl::Backup(const std::string &file, const std::string &baseDir) { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); - if (isApplication_ && (apiVersion_ >= INTEGRITY_CHECK_API_VERSION)) { + if (!isApplication_ || (isApplication_ && (apiVersion_ >= INTEGRITY_CHECK_API_VERSION))) { auto dbStatus = dbStore_->CheckIntegrity(); if (dbStatus != DistributedDB::DBStatus::OK) { ZLOGE("CheckIntegrity fail, dbStatus:%{public}d", dbStatus); @@ -786,7 +780,7 @@ Status SingleStoreImpl::Restore(const std::string &file, const std::string &base service->Close({ appId_ }, { storeId_ }); } bool isCheckIntegrity = false; - if (isApplication_ && (apiVersion_ >= INTEGRITY_CHECK_API_VERSION)) { + if (!isApplication_ || (isApplication_ && (apiVersion_ >= INTEGRITY_CHECK_API_VERSION))) { isCheckIntegrity = true; } BackupManager::BackupInfo info = { .name = file, .baseDir = baseDir, .appId = appId_, .storeId = storeId_ }; diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/test/BUILD.gn b/kv_store/frameworks/innerkitsimpl/kvdb/test/BUILD.gn index 40adf8a4..1634d3e3 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/test/BUILD.gn +++ b/kv_store/frameworks/innerkitsimpl/kvdb/test/BUILD.gn @@ -323,6 +323,56 @@ ohos_unittest("SecurityManagerTest") { ] } +ohos_unittest("SingleStorePerfPcTest") { + module_out_path = module_output_path + + sources = [ + "../../kvdb/src/kv_hiview_reporter_mock.cpp", + "single_store_perf_pc_test.cpp", + ] + + configs = [ ":module_private_config" ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_single", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", + ] + + deps = [ + ":kvdb_src_file", + "${kv_store_base_path}/frameworks/libs/distributeddb/:distributeddb", + "//third_party/googletest:gtest", + ] +} + +ohos_unittest("SingleStorePerfPhoneTest") { + module_out_path = module_output_path + + sources = [ + "../../kvdb/src/kv_hiview_reporter_mock.cpp", + "single_store_perf_phone_test.cpp", + ] + + configs = [ ":module_private_config" ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_single", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", + ] + + deps = [ + ":kvdb_src_file", + "${kv_store_base_path}/frameworks/libs/distributeddb/:distributeddb", + "//third_party/googletest:gtest", + ] +} + ############################################################################### group("unittest") { testonly = true @@ -338,6 +388,13 @@ group("unittest") { ":StoreUtilTest", ] + if (false) { + deps += [ + ":SingleStorePerfPcTest", + ":SingleStorePerfPhoneTest", + ] + } + if (!use_libfuzzer) { deps += [ ":SecurityManagerTest" ] } diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/test/dev_manager_mock_test.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/test/dev_manager_mock_test.cpp index fe825aad..c44a7cc0 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/test/dev_manager_mock_test.cpp +++ b/kv_store/frameworks/innerkitsimpl/kvdb/test/dev_manager_mock_test.cpp @@ -75,20 +75,6 @@ HWTEST_F(DevManagerMockTest, GetUnEncryptedUuid002, TestSize.Level1) EXPECT_EQ(uuid, ""); } -/** -* @tc.name: GetUnEncryptedUuid -* @tc.desc: test GetUnEncryptedUuid get uuid by networkid fail -* @tc.type: FUNC -* @tc.require: -* @tc.author: SQL -*/ -HWTEST_F(DevManagerMockTest, GetUnEncryptedUuid003, TestSize.Level1) -{ - ZLOGI("GetUnEncryptedUuid003 begin."); - auto uuid = DevManager::GetInstance().GetUnEncryptedUuid(); - EXPECT_EQ(uuid, ""); -} - /** * @tc.name: GetLocalDevice * @tc.desc: test GetLocalDevice get local device info fail diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/test/device_manager_mock.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/test/device_manager_mock.cpp index 321d5eb9..6249fa24 100644 --- a/kv_store/frameworks/innerkitsimpl/kvdb/test/device_manager_mock.cpp +++ b/kv_store/frameworks/innerkitsimpl/kvdb/test/device_manager_mock.cpp @@ -64,16 +64,8 @@ int32_t DeviceManager::GetLocalDeviceInfo(const std::string &pkgName, DmDeviceIn if (testDemo == 0) { testDemo = 1; return ERR_DM_IPC_SEND_REQUEST_FAILED; - } else if (testDemo == 1) { - testDemo = -1; - return DM_OK; } else { testDemo = 0; - DmDeviceInfo info; - info.networkId[0] = '1'; - info.networkId[1] = '1'; - DmDeviceInfo& infos = info; - deviceInfo = infos; return DM_OK; } } @@ -93,7 +85,6 @@ int32_t DeviceManager::RegisterDevStatusCallback(const std::string &pkgName, con int32_t DeviceManager::GetUuidByNetworkId(const std::string &pkgName, const std::string &netWorkId, std::string &uuid) { - uuid = ""; return ERR_DM_INPUT_PARA_INVALID; } diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/test/single_store_perf_pc_test.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/test/single_store_perf_pc_test.cpp new file mode 100644 index 00000000..1cae2361 --- /dev/null +++ b/kv_store/frameworks/innerkitsimpl/kvdb/test/single_store_perf_pc_test.cpp @@ -0,0 +1,250 @@ +/* + * 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 "block_data.h" +#include "dev_manager.h" +#include "distributed_kv_data_manager.h" +#include "file_ex.h" +#include "kv_store_nb_delegate.h" +#include "store_manager.h" +#include "sys/stat.h" +#include "types.h" +#include "log_print.h" +using namespace testing::ext; +using namespace OHOS::DistributedKv; +namespace OHOS::Test { +static constexpr int THUMBNBIL_MAX_SIZE = 130; +class SingleStorePerfPcTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + + std::shared_ptr CreateKVStore(std::string storeIdTest, KvStoreType type, bool encrypt, bool backup); + static std::shared_ptr CreateHashKVStore(std::string storeIdTest, KvStoreType type, + bool encrypt, bool backup); + static std::shared_ptr kvStore_; +}; + +std::shared_ptr SingleStorePerfPcTest::kvStore_; + +void SingleStorePerfPcTest::SetUpTestCase(void) +{ + printf("SetUpTestCase BEGIN\n"); + std::string baseDir = "/data/service/el1/public/database/SingleStorePerfPcTest"; + mkdir(baseDir.c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)); + kvStore_ = CreateHashKVStore("SingleKVStore", LOCAL_ONLY, false, false); + if (kvStore_ == nullptr) { + kvStore_ = CreateHashKVStore("SingleKVStore", LOCAL_ONLY, false, false); + } + EXPECT_NE(kvStore_, nullptr); + //kvstore Insert 1 million PC file management thumbnail data + std::string strKey(8, 'k'); // The length is 8 + std::string strValue(4592, 'v'); // The length is 4592 + int count = 1000000; + std::vector keyVec; + /// set key,value + for (int i = 0; i < count; ++i) { + std::string tmpKey = std::to_string(i); + tmpKey = strKey.replace(0, tmpKey.size(), tmpKey); + Key key(tmpKey); + Value value(strValue); + auto status = kvStore_->Put(key, value); + EXPECT_EQ(status, SUCCESS); + } + printf("SetUpTestCase END\n"); +} + +void SingleStorePerfPcTest::TearDownTestCase(void) +{ + printf("TearDownTestCase BEGIN\n"); + AppId appId = { "SingleStorePerfPcTest" }; + StoreId storeId = { "SingleKVStore" }; + kvStore_ = nullptr; + auto status = StoreManager::GetInstance().CloseKVStore(appId, storeId); + EXPECT_EQ(status, SUCCESS); + std::string baseDir = "/data/service/el1/public/database/SingleStorePerfPcTest"; + status = StoreManager::GetInstance().Delete(appId, storeId, baseDir); + EXPECT_EQ(status, SUCCESS); + + printf("remove key kvdb SingleStorePerfPcTest BEGIN\n"); + (void)remove("/data/service/el1/public/database/SingleStorePerfPcTest/key"); + (void)remove("/data/service/el1/public/database/SingleStorePerfPcTest/kvdb"); + (void)remove("/data/service/el1/public/database/SingleStorePerfPcTest"); + printf("remove key kvdb SingleStorePerfPcTest END\n"); + printf("TearDownTestCase END\n"); +} + +void SingleStorePerfPcTest::SetUp(void) +{ + printf("SetUp BEGIN\n"); + printf("SetUp END\n"); +} + +void SingleStorePerfPcTest::TearDown(void) +{ + printf("TearDown BEGIN\n"); + printf("TearDown END\n"); +} + +std::shared_ptr SingleStorePerfPcTest::CreateKVStore(std::string storeIdTest, KvStoreType type, + bool encrypt, bool backup) +{ + Options options; + options.kvStoreType = type; + options.securityLevel = S1; + options.encrypt = encrypt; + options.area = EL1; + options.backup = backup; + options.baseDir = "/data/service/el1/public/database/SingleStorePerfPcTest"; + + AppId appId = { "SingleStorePerfPcTest" }; + StoreId storeId = { storeIdTest }; + Status status = StoreManager::GetInstance().Delete(appId, storeId, options.baseDir); + return StoreManager::GetInstance().GetKVStore(appId, storeId, options, status); +} + +std::shared_ptr SingleStorePerfPcTest::CreateHashKVStore(std::string storeIdTest, KvStoreType type, + bool encrypt, bool backup) +{ + Options options; + options.kvStoreType = type; + options.securityLevel = S1; + options.encrypt = encrypt; + options.area = EL1; + options.backup = backup; + options.baseDir = "/data/service/el1/public/database/SingleStorePerfPcTest"; + options.config.type = HASH; + options.config.pageSize = 32u; + options.config.cacheSize = 4096u; + + AppId appId = { "SingleStorePerfPcTest" }; + StoreId storeId = { storeIdTest }; + Status status = StoreManager::GetInstance().Delete(appId, storeId, options.baseDir); + return StoreManager::GetInstance().GetKVStore(appId, storeId, options, status); +} + +static struct timespec GetTime(void) +{ + struct timespec now; + clock_gettime(CLOCK_REALTIME, &now); + return now; +} + +static double TimeDiff(const struct timespec *beg, const struct timespec *end) +{ + // 1000000000.0 to convert nanoseconds to seconds + return (end->tv_sec - beg->tv_sec) + ((end->tv_nsec - beg->tv_nsec) / 1000000000.0); +} + +/** + * @tc.name: HashIndexKVStoreTest001 + * @tc.desc: PC File Management simulation:1 threads use vector 2000 keys 500 batches one by one + * Get the value of the kv store, and the average delay of each key is calculated in 2000 keys. + * Then, the average delay of a screen is calculated by multiplying the delay by 130. + * @tc.type: PERF + * @tc.require: + * @tc.author: Gang Wang + */ +HWTEST_F(SingleStorePerfPcTest, HashIndexKVStoreTest001, TestSize.Level0) +{ + printf("HashIndexKVStoreTest001 BEGIN\n"); + std::string strKey(8, 'k'); + int count = 1000000; + // We can't divide 130. We use 2000 + int batchCount = 2000; + int failCount = 0; + std::vector keyVec; + double dur = 0; + double avrTime130 = 0; + + keyVec.clear(); + for (int j = 0; j < count / batchCount; j++) { + keyVec.clear(); + for (int i = j * batchCount; i < (j + 1) * batchCount; i++) { + std::string tmpKey = std::to_string(i); + tmpKey = strKey.replace(0, tmpKey.size(), tmpKey); + Key key(tmpKey); + keyVec.emplace_back(key); + } + timespec beg = GetTime(); + for (auto &item : keyVec) { + Value value; + kvStore_->Get(item, value); + } + timespec end = GetTime(); + double tmp = TimeDiff(&beg, &end); + dur += tmp; + avrTime130 = tmp * THUMBNBIL_MAX_SIZE * 1000 / keyVec.size(); + if (avrTime130 >= 3.0) { + failCount += 1; + } + printf("platform:HAD_OH_Native_innerKitAPI_Get index[%d] keyLen[%d] valueLen[%d],\n" + "batch_time[%lfs], avrTime130[%lfms], failCount[%u]\n", + j, 8, 4592, tmp, avrTime130, failCount); + } + avrTime130 = dur * THUMBNBIL_MAX_SIZE * 1000 / count; + printf("batchCount[%d] keyLen[%d] valueLen[%d], sum_time[%lfs], avrTime130[%lfms],\n" + "HashIndexKVStoreTest001 failCount[%u]\n", + batchCount, 8, 4592, dur, avrTime130, failCount); + EXPECT_LT(avrTime130, 3.0); + printf("HashIndexKVStoreTest001 END\n"); +} + +/** + * @tc.name: HashIndexKVStoreTest002 + * @tc.desc: PC File Management simulation:1 threads use vector 1000000 keys one by one Get the value of the kv store, + * and the average delay of each key is calculated. + * Then, the average delay of a screen is calculated by multiplying the delay by 130. + * @tc.type: PERF + * @tc.require: + * @tc.author: Gang Wang + */ +HWTEST_F(SingleStorePerfPcTest, HashIndexKVStoreTest002, TestSize.Level0) +{ + printf("HashIndexKVStoreTest002 BEGIN\n"); + std::string strKey(8, 'k'); + int count = 1000000; + + std::vector keyVec; + double dur = 0; + double avrTime130 = 0; + keyVec.clear(); + for (int i = 0; i < count; ++i) { + std::string tmpKey = std::to_string(i); + tmpKey = strKey.replace(0, tmpKey.size(), tmpKey); + Key key(tmpKey); + keyVec.emplace_back(key); + } + timespec beg = GetTime(); + for (auto &item : keyVec) { + Value value; + kvStore_->Get(item, value); + } + timespec end = GetTime(); + dur = TimeDiff(&beg, &end); + avrTime130 = dur * THUMBNBIL_MAX_SIZE * 1000 / count; + printf("count[%d] platform:HAD_OH_Native_innerKitAPI_Get keyLen[%d] valueLen[%d], time[%lfs],\n" + "avrTime130[%lfms]\n", + count, 8, 4592, dur, avrTime130); + EXPECT_LT(avrTime130, 3.0); + printf("HashIndexKVStoreTest002 END\n"); +} +} // namespace OHOS::Test diff --git a/kv_store/frameworks/innerkitsimpl/kvdb/test/single_store_perf_phone_test.cpp b/kv_store/frameworks/innerkitsimpl/kvdb/test/single_store_perf_phone_test.cpp new file mode 100644 index 00000000..2ac13432 --- /dev/null +++ b/kv_store/frameworks/innerkitsimpl/kvdb/test/single_store_perf_phone_test.cpp @@ -0,0 +1,333 @@ +/* + * 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 "SingleStorePerfPhoneTest" +#include "distributed_kv_data_manager.h" +#include +#include "log_print.h" +#include +#include +#include +#include +#include "store_manager.h" +#include "types.h" +#include "process_system_api_adapter_impl.h" + +#ifdef DB_DEBUG_ENV + +#include "system_time.h" + +#endif // DB_DEBUG_ENV + +using namespace testing::ext; +using namespace OHOS::DistributedKv; +using namespace std; +namespace OHOS::Test { +// define some variables to init a KvStoreDelegateManager object. +std::shared_ptr store1; +std::shared_ptr store2; +std::shared_ptr store3; + +class SingleStorePerfPhoneTest : public testing::Test { +public: + std::shared_ptr CreateKVStore(std::string storeIdTest, KvStoreType type, bool encrypt, bool backup); + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp() override; + void TearDown() override; +}; + +OHOS::DistributedKv::Key GenerateBytes(const string &str) +{ + DistributedDB::Key bytes; + const char *buffer = str.c_str(); + for (uint32_t i = 0; i < str.size(); i++) { + bytes.emplace_back(buffer[i]); + } + return bytes; +} + +string GenerateRandomString(long length) +{ + std::string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + std::string out; + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution<> dis(0, chars.size() - 1); + for (int i = 0; i < length; i++) { + out += chars[dis(gen)]; + } + return out; +} + +string GetDate(char *cType, int iDay) +{ + char cTimePARTNUMBER[256] = ""; + time_t rawtime; + struct tm timeinfo{}; + rawtime = time(NULL) + iDay * 24 * 3600; // 24 hours a day, 3600 seconds per hour + localtime_r(&rawtime, &timeinfo); + char buffer1[256]; + size_t n = strftime(cTimePARTNUMBER, sizeof(buffer1), cType, &timeinfo); //20180623 + if (n != 0) { + string strTimePARTNUMBER = cTimePARTNUMBER; + return strTimePARTNUMBER; + } else { + return ""; + } +} + +/** + * Presets data to a specified single-key value store. + * @param store Smart pointer of a single key-value store. + * @param batch The number of batches, representing the batch in which the data was inserted. + * @param count Number of pictures on a screen. + * @param size Size of the value in kilobytes for each key-value pair. + * @param ratio Ratio of compression + * @param firstKey An output parameter that receives the first key in the first batch + * @param lastKey An output parameter that receives the last key in the last batch + * @details This function is responsible for writing a preset set of data to a specified + * single-key value store based on a given batch, quantity, size, and ratio. + */ +void PresetData(std::shared_ptr &store, int batch, int count, int size, int ratio, + std::string &firstKey, std::string &lastKey) +{ + std::ostringstream s; + s << std::setw(16) << std::setfill('0') << 0; // 16 bytes + string strDate; + string ss = to_string(size) + "K"; // The batches are iterated backward to generate data for different dates + for (int i = batch; i >= 1; i--) { + strDate = GetDate((char*)"%Y%m%d", -i); + for (int index = 1; index <= count; index++) { + // Produces a unique key string containing date, size, and index information + string tmp = + s.str() + "_" + ss + "_" + strDate + string(3 - to_string(index).length(), '0') + to_string(index); + string val; + // Generate random value string based on ratio If the ratio is 0, an empty string is generated + if (ratio != 0) { + val = GenerateRandomString((long)(size * 1024) / ratio); // 1024 bytes per 1K + } else { + val = GenerateRandomString(0); + } + const DistributedDB::Key key = GenerateBytes(tmp); + const DistributedDB::Value value = GenerateBytes(val); + ASSERT_EQ(store->Put(key, value), SUCCESS); + if (i == batch && index == 1) { + // Convert the contents of the key to std::string and assign it to the firstKey + firstKey = std::string(key.begin(), key.end()); + } + if (i == 1 && index == count) { + lastKey = std::string(key.begin(), key.end()); + } + } + } + printf("put success! \n"); +} + +/** + * @brief Calculates the duration of a RangeResultSet. + * @param store Smart pointer of a single key-value store. + * @param batch The number of batches, representing the batch in which the data was inserted. + * @param size Size of the value in kilobytes for each key-value pair. + * @param count Number of pictures on a screen. + * @param firstKey An output parameter that receives the first key in the first batch + * @param lastKey An output parameter that receives the last key in the last batch + * @details This function is used to calculate the duration for obtaining data on a screen. + * Data is obtained through multiple cycles and the average time is calculated. + */ +void CalcRangeResultSetDuration(std::shared_ptr &store, int batch, int size, int count, + std::string firstKey, std::string lastKey) +{ + // batch = totolCnt / (448/ 112) size(4 8) count (448 112) + double dur = 0.0; + double totalTime = 0.0; + double avrTime = 0.0; + int failCount = 0; + // The outer loop is run 100 times to improve the accuracy of the test results + for (int n = 0; n < 100; ++n) { // 100 times + DataQuery query; + // The sequential query is carried out according to the actual business scenario + query.Between("", lastKey); + std::shared_ptr readResultSet; + ASSERT_EQ(store->GetResultSet(query, readResultSet), SUCCESS); + ASSERT_TRUE(readResultSet != nullptr); + for (int ind = batch; ind >= 1; ind--) { + struct timeval startTime{}; + struct timeval endTime{}; + (void) gettimeofday(&startTime, nullptr); + for (int i = 0; i < count; ++i) { // Loop through a screen of data + readResultSet->MoveToNext(); // Move the read position to the next row. + Entry entry; // Data is organized by entry definition. + readResultSet->GetEntry(entry); + } + (void) gettimeofday(&endTime, nullptr); + double startUsec = (double) (startTime.tv_sec * 1000 * 1000) + (double) startTime.tv_usec; + double endUsec = (double) (endTime.tv_sec * 1000 * 1000) + (double) endTime.tv_usec; + dur = endUsec - startUsec; + totalTime += dur; + avrTime = (dur / 1000); // 1000 is to convert ms + if (avrTime >= 3.0) { // 3.0 ms is upper bound on performance + failCount += 1; + } + } + EXPECT_EQ(store->CloseResultSet(readResultSet), SUCCESS); + readResultSet = nullptr; + } + if (batch != 0) { + // 100 is for unit conversion + avrTime = (((totalTime / batch) / 100) / 1000); // 1000 is to convert ms + cout << "Scan Range ResultSet avg cost = " << avrTime << " ms." << endl; + cout << "failCount: " << failCount << endl; + EXPECT_LT(avrTime, 3.0); // 3.0 ms is upper bound on performance + } else { + cout << "Error: Division by zero." << endl; + } +} + +void SingleStorePerfPhoneTest::SetUpTestCase() +{ + std::string baseDir = "/data/service/el1/public/database/SingleStorePerfPhoneTest"; + mkdir(baseDir.c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)); +} + +void SingleStorePerfPhoneTest::TearDownTestCase() +{ + std::string baseDir = "/data/service/el1/public/database/SingleStorePerfPhoneTest"; + StoreManager::GetInstance().Delete({ "SingleStorePerfPhoneTest" }, { "SingleKVStore" }, baseDir); + + (void)remove("/data/service/el1/public/database/SingleStorePerfPhoneTest/key"); + (void)remove("/data/service/el1/public/database/SingleStorePerfPhoneTest/kvdb"); + (void)remove("/data/service/el1/public/database/SingleStorePerfPhoneTest"); +} + +void SingleStorePerfPhoneTest::SetUp() +{ + store1 = CreateKVStore("SingleKVStore1", LOCAL_ONLY, false, false); + if (store1 == nullptr) { + store1 = CreateKVStore("SingleKVStore1", LOCAL_ONLY, false, false); + } + ASSERT_NE(store1, nullptr); + + store2 = CreateKVStore("SingleKVStore2", LOCAL_ONLY, false, false); + if (store2 == nullptr) { + store2 = CreateKVStore("SingleKVStore2", LOCAL_ONLY, false, false); + } + ASSERT_NE(store2, nullptr); + + store3 = CreateKVStore("SingleKVStore3", LOCAL_ONLY, false, false); + if (store3 == nullptr) { + store3 = CreateKVStore("SingleKVStore3", LOCAL_ONLY, false, false); + } + ASSERT_NE(store3, nullptr); +} + +void SingleStorePerfPhoneTest::TearDown() +{ + AppId appId = { "SingleStorePerfPhoneTest" }; + StoreId storeId1 = { "SingleKVStore1" }; + StoreId storeId2 = { "SingleKVStore2" }; + StoreId storeId3 = { "SingleKVStore3" }; + store1 = nullptr; + store2 = nullptr; + store3 = nullptr; + auto status = StoreManager::GetInstance().CloseKVStore(appId, storeId1); + ASSERT_EQ(status, SUCCESS); + status = StoreManager::GetInstance().CloseKVStore(appId, storeId2); + ASSERT_EQ(status, SUCCESS); + status = StoreManager::GetInstance().CloseKVStore(appId, storeId3); + ASSERT_EQ(status, SUCCESS); + auto baseDir = "/data/service/el1/public/database/SingleStorePerfPhoneTest"; + status = StoreManager::GetInstance().Delete(appId, storeId1, baseDir); + ASSERT_EQ(status, SUCCESS); + status = StoreManager::GetInstance().Delete(appId, storeId2, baseDir); + ASSERT_EQ(status, SUCCESS); + status = StoreManager::GetInstance().Delete(appId, storeId3, baseDir); + ASSERT_EQ(status, SUCCESS); +} + +std::shared_ptr SingleStorePerfPhoneTest::CreateKVStore(std::string storeIdTest, KvStoreType type, + bool encrypt, bool backup) +{ + Options options; + options.kvStoreType = type; + options.securityLevel = S1; + options.encrypt = encrypt; + options.area = EL1; + options.backup = backup; + options.baseDir = "/data/service/el1/public/database/SingleStorePerfPhoneTest"; + + AppId appId = { "SingleStorePerfPhoneTest" }; + StoreId storeId = { storeIdTest }; + Status status = StoreManager::GetInstance().Delete(appId, storeId, options.baseDir); + return StoreManager::GetInstance().GetKVStore(appId, storeId, options, status); +} + +/** + * @tc.name: Gallery1WThumbnailsKVStoreBetweenTest + * @tc.desc: Gallery 10,000 thumbnails High-performance KV database Native interface Between + * query performance less than 3 ms + * @tc.type: PERF + * @tc.require: + * @tc.author: Gang Wang + */ +HWTEST_F(SingleStorePerfPhoneTest, Gallery1WThumbnailsKVStoreBetweenTest, TestSize.Level0) +{ + int monthlyBatch = (int) (10000 / 112); + int annuallyBatch = (int) (10000 / 448); + int ratio = 1; + + printf("monthly start \n"); + std::string firstKey1; + std::string lastKey1; + PresetData(store1, monthlyBatch, 112, 8, ratio, firstKey1, lastKey1); + cout << "first key: " << firstKey1 << ", last key: " << lastKey1 << endl; + CalcRangeResultSetDuration(store1, monthlyBatch, 8, 112, firstKey1, lastKey1); + + printf("annually start \n"); + std::string firstKey2; + std::string lastKey2; + PresetData(store2, annuallyBatch, 448, 4, ratio, firstKey2, lastKey2); + cout << "first key: " << firstKey2 << ", last key: " << lastKey2 << endl; + CalcRangeResultSetDuration(store2, annuallyBatch, 4, 448, firstKey2, lastKey2); +} + +/** + * @tc.name: Gallery5WThumbnailsKVStoreBetweenTest + * @tc.desc: Gallery 50,000 thumbnails High-performance KV database Native interface Between + * query performance less than 3 ms + * @tc.type: PERF + * @tc.require: + * @tc.author: Gang Wang + */ +HWTEST_F(SingleStorePerfPhoneTest, Gallery5WThumbnailsKVStoreBetweenTest, TestSize.Level0) +{ + int monthlyBatch = (int) (50000 / 112); + int annuallyBatch = (int) (50000 / 448); + int ratio = 1; + + printf("monthly start \n"); + std::string firstKey1; + std::string lastKey1; + PresetData(store1, monthlyBatch, 112, 8, ratio, firstKey1, lastKey1); + cout << "first key: " << firstKey1 << ", last key: " << lastKey1 << endl; + CalcRangeResultSetDuration(store1, monthlyBatch, 8, 112, firstKey1, lastKey1); + + printf("annually start \n"); + std::string firstKey2; + std::string lastKey2; + PresetData(store2, annuallyBatch, 448, 4, ratio, firstKey2, lastKey2); + cout << "first key: " << firstKey2 << ", last key: " << lastKey2 << endl; + CalcRangeResultSetDuration(store2, annuallyBatch, 4, 448, firstKey2, lastKey2); +} +} // namespace OHOS::Test \ No newline at end of file diff --git a/kv_store/frameworks/jskitsimpl/distributeddata/src/napi_queue.cpp b/kv_store/frameworks/jskitsimpl/distributeddata/src/napi_queue.cpp index a59535c7..de35ddca 100644 --- a/kv_store/frameworks/jskitsimpl/distributeddata/src/napi_queue.cpp +++ b/kv_store/frameworks/jskitsimpl/distributeddata/src/napi_queue.cpp @@ -82,7 +82,8 @@ napi_value NapiQueue::AsyncWork(napi_env env, std::shared_ptr ctxt, aCtx->complete = std::move(complete); napi_value promise = nullptr; if (aCtx->ctx->callbackRef == nullptr) { - napi_create_promise(env, &aCtx->deferred, &promise); + auto ret = napi_create_promise(env, &aCtx->deferred, &promise); + CHECK_RETURN(ret == napi_ok, "napi_create_promise fail", nullptr); ZLOGD("create deferred promise"); } else { napi_get_undefined(env, &promise); diff --git a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_error_utils.cpp b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_error_utils.cpp index 1b0bef81..09816ebb 100644 --- a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_error_utils.cpp +++ b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_error_utils.cpp @@ -26,11 +26,12 @@ static constexpr JsErrorCode JS_ERROR_CODE_MSGS[] = { { Status::STORE_NOT_OPEN, 0, "" }, { Status::STORE_ALREADY_SUBSCRIBE, 0, "" }, { Status::STORE_NOT_SUBSCRIBE, 0, "" }, - { Status::NOT_FOUND, 15100004, "Not found." }, - { Status::STORE_META_CHANGED, 15100002, "Open existed database with changed options." }, + { Status::NOT_FOUND, 15100004, "Data not found." }, + { Status::STORE_META_CHANGED, 15100002, + "The options configuration changes when the API is called to obtain a KV store." }, { Status::PERMISSION_DENIED, 202, "Permission denied" }, { Status::CRYPT_ERROR, 15100006, "Unable to open the database." }, - { Status::OVER_MAX_LIMITS, 15100001, "Over max limits." }, + { Status::OVER_MAX_LIMITS, 15100001, "Upper limit exceeded." }, { Status::ALREADY_CLOSED, 15100005, "Database or result set already closed." }, { Status::DATA_CORRUPTED, 15100003, "Database corrupted" }, { Status::WAL_OVER_LIMITS, 14800047, "the WAL file size exceeds the default limit."}, diff --git a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_kv_manager.cpp b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_kv_manager.cpp index 2b0941c2..f5bccd20 100644 --- a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_kv_manager.cpp +++ b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/js_kv_manager.cpp @@ -143,6 +143,7 @@ napi_value JsKVManager::GetKVStore(napi_env env, napi_callback_info info) ctxt->options.baseDir = kvm->param_->baseDir; ctxt->options.area = kvm->param_->area + 1; ctxt->options.hapName = kvm->param_->hapName; + ctxt->options.apiVersion = kvm->param_->apiVersion; ZLOGD("Options area:%{public}d dir:%{public}s", ctxt->options.area, ctxt->options.baseDir.c_str()); std::shared_ptr kvStore; Status status = kvm->kvDataManager_.GetSingleKvStore(ctxt->options, appId, storeId, kvStore); diff --git a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/napi_queue.cpp b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/napi_queue.cpp index 6a09ea45..e9412457 100644 --- a/kv_store/frameworks/jskitsimpl/distributedkvstore/src/napi_queue.cpp +++ b/kv_store/frameworks/jskitsimpl/distributedkvstore/src/napi_queue.cpp @@ -82,7 +82,8 @@ napi_value NapiQueue::AsyncWork(napi_env env, std::shared_ptr ctxt, aCtx->complete = std::move(complete); napi_value promise = nullptr; if (aCtx->ctx->callbackRef == nullptr) { - napi_create_promise(env, &aCtx->deferred, &promise); + auto ret = napi_create_promise(env, &aCtx->deferred, &promise); + ASSERT(ret == napi_ok, "napi_create_promise fail", nullptr); ZLOGD("create deferred promise"); } else { napi_get_undefined(env, &promise); diff --git a/kv_store/frameworks/libs/CMakeLists.txt b/kv_store/frameworks/libs/CMakeLists.txt index ae863153..b2bfe55f 100644 --- a/kv_store/frameworks/libs/CMakeLists.txt +++ b/kv_store/frameworks/libs/CMakeLists.txt @@ -9,7 +9,7 @@ set(MOCK_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../mock) add_definitions(-DUSE_HARMONY_SQLITE -DUSING_HILOG_LOGGER -DOMIT_FLATBUFFER -DOMIT_MULTI_VER -DEVLOOP_TIMER_ONLY) #-DOMIT_JSON add_definitions(-DUSING_DB_JSON_EXTRACT_AUTOMATICALLY -DSQLITE_ENABLE_JSON1 -DRELATIONAL_STORE -DOMIT_ZLIB) add_definitions(-DWINDOWS_PLATFORM -DSQLITE_HAS_CODEC -DJSONCPP_USE_BUILDER -DEKEYREVOKED=128 -DSQLITE_ENABLE_DROPTABLE_CALLBACK) -add_definitions(-Dfseeko64=fseeko) +add_definitions(-Dfseeko64=fseeko -D__XSI_VISIBLE=0) add_definitions(-DSQLITE_DISTRIBUTE_RELATIONAL) aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/distributeddb/common/src/evloop/src distributeddbSrc) 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 7a11c7f5..72268adf 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 @@ -36,6 +36,8 @@ public: const CloudSyncAction &action); static AssetOperationUtils::AssetOpType CalAssetOperation(const std::string &colName, const Asset &cacheAsset, const VBucket &dbAssets, const CloudSyncAction &action); + static AssetOperationUtils::AssetOpType CalAssetRemoveOperation(const std::string &colName, + const Asset &cacheAsset, const VBucket &assets); static uint32_t EraseBitMask(uint32_t status); static void UpdateAssetsFlag(std::vector &from, std::vector &target); static void FilterDeleteAsset(VBucket &record); 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 89a9f308..4158ab9c 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/db_common.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/db_common.h @@ -44,7 +44,7 @@ public: static inline std::string GetMetaTableName() { - return DBConstant::RELATIONAL_PREFIX + DBConstant::META_TABLE_POSTFIX; + return std::string(DBConstant::RELATIONAL_PREFIX) + DBConstant::META_TABLE_POSTFIX; } static std::string VectorToHexString(const std::vector &inVec, const std::string &separator = ""); 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 1d37bbf3..b0576bf5 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/db_constant.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/db_constant.h @@ -154,7 +154,8 @@ public: // For relational static const std::string SYSTEM_TABLE_PREFIX; - static const std::string RELATIONAL_PREFIX; + static constexpr const char *RELATIONAL_PREFIX = "naturalbase_rdb_aux_"; + static constexpr size_t RELATIONAL_PREFIX_SIZE = 20; static const std::string TIMESTAMP_ALIAS; static constexpr const char *LOG_POSTFIX = "_log"; static constexpr const char *META_TABLE_POSTFIX = "metadata"; @@ -191,10 +192,10 @@ public: static constexpr const char *STORAGE_TYPE_LONG = "long"; + static constexpr const uint64_t INVALID_CURSOR = UINT64_MAX; + static constexpr const char *KV_SYNC_TABLE_NAME = "sync_data"; static constexpr const char *KV_LOCAL_TABLE_NAME = "local_data"; - - static constexpr uint64_t INVALID_CURSOR = UINT64_MAX; }; } // namespace DistributedDB #endif // DISTRIBUTEDDB_CONSTANT_H diff --git a/kv_store/frameworks/libs/distributeddb/common/include/relational/tracker_table.h b/kv_store/frameworks/libs/distributeddb/common/include/relational/tracker_table.h index df376ab2..0e1e9f7b 100644 --- a/kv_store/frameworks/libs/distributeddb/common/include/relational/tracker_table.h +++ b/kv_store/frameworks/libs/distributeddb/common/include/relational/tracker_table.h @@ -52,6 +52,7 @@ public: void SetExtendName(const std::string &colName); void SetTrackerNames(const std::set &trackerNames); bool IsEmpty() const; + bool IsTableNameEmpty() const; bool IsChanging(const TrackerSchema &schema); int ReBuildTempTrigger(sqlite3 *db, TriggerMode::TriggerModeEnum mode, const AfterBuildAction &action); void SetTrackerAction(bool isTrackerAction); 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 3fcfda78..97f26ffa 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 @@ -66,6 +66,24 @@ AssetOperationUtils::AssetOpType AssetOperationUtils::CalAssetOperation(const st return reaction(cacheAsset, GetAssets(colName, dbAssets)); } +AssetOperationUtils::AssetOpType AssetOperationUtils::CalAssetRemoveOperation(const std::string &colName, + const Asset &cacheAsset, const VBucket &assets) +{ + Assets dbAssets = GetAssets(colName, assets); + for (const auto &dbAsset : dbAssets) { + if (dbAsset.name != cacheAsset.name) { + continue; + } + if (EraseBitMask(dbAsset.status) == AssetStatus::DOWNLOADING || + EraseBitMask(dbAsset.status) == AssetStatus::ABNORMAL) { + return AssetOpType::HANDLE; + } + return AssetOpType::NOT_HANDLE; + } + return cacheAsset.flag == static_cast(DistributedDB::AssetOpType::DELETE) ? + AssetOpType::HANDLE : AssetOpType::NOT_HANDLE; +} + uint32_t AssetOperationUtils::EraseBitMask(uint32_t status) { return ((status << BIT_MASK_COUNT) >> BIT_MASK_COUNT); 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 03f1294b..5caa2b80 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/db_common.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/db_common.cpp @@ -391,10 +391,10 @@ void DBCommon::GetDeviceFromName(const std::string &deviceTableName, std::string { std::size_t found = deviceTableName.rfind('_'); if (found != std::string::npos && found + 1 < deviceTableName.length() && - found > DBConstant::RELATIONAL_PREFIX.length()) { + found > DBConstant::RELATIONAL_PREFIX_SIZE) { deviceHash = deviceTableName.substr(found + 1); - tableName = deviceTableName.substr(DBConstant::RELATIONAL_PREFIX.length(), - found - DBConstant::RELATIONAL_PREFIX.length()); + tableName = deviceTableName.substr(DBConstant::RELATIONAL_PREFIX_SIZE, + found - DBConstant::RELATIONAL_PREFIX_SIZE); } } @@ -810,7 +810,7 @@ bool DBCommon::CheckCloudSyncConfigValid(const CloudSyncConfig &config) std::string DBCommon::GetCursorKey(const std::string &tableName) { - return DBConstant::RELATIONAL_PREFIX + "cursor_" + ToLowerCase(tableName); + return std::string(DBConstant::RELATIONAL_PREFIX) + "cursor_" + ToLowerCase(tableName); } bool DBCommon::ConvertToUInt64(const std::string &str, uint64_t &value) 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 d9af352f..b24c170d 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/db_constant.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/db_constant.cpp @@ -23,7 +23,6 @@ const std::string DBConstant::MAINDB_DIR = "main"; const std::string DBConstant::METADB_DIR = "meta"; const std::string DBConstant::CACHEDB_DIR = "cache"; const std::string DBConstant::SYSTEM_TABLE_PREFIX = "naturalbase_rdb_"; -const std::string DBConstant::RELATIONAL_PREFIX = "naturalbase_rdb_aux_"; const std::string DBConstant::RELATIONAL_SCHEMA_KEY = "relational_schema"; const std::string DBConstant::RELATIONAL_TRACKER_SCHEMA_KEY = "relational_tracker_schema"; 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 ab56e407..a207b4da 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 @@ -83,38 +83,38 @@ void DBDfxAdapter::Dump(int fd, const std::vector &args) #ifdef USE_DFX_ABILITY void DBDfxAdapter::ReportBehavior(const ReportTask &reportTask) { - int dbDfxErrCode = -(reportTask.errCode - E_BASE) + E_DB_DFX_BASE; - struct HiSysEventParam params[] = { - {.name = {"ORG_PKG"}, - .t = HISYSEVENT_STRING, - .v = {.s = const_cast(ORG_PKG_NAME.c_str())}, - .arraySize = 0}, - {.name = {"FUNC"}, - .t = HISYSEVENT_STRING, - .v = {.s = const_cast(reportTask.funcName.c_str())}, - .arraySize = 0}, - {.name = {"BIZ_SCENE"}, - .t = HISYSEVENT_INT32, - .v = {.i32 = static_cast(reportTask.scene)}, - .arraySize = 0}, - {.name = {"BIZ_STATE"}, - .t = HISYSEVENT_INT32, - .v = {.i32 = static_cast(reportTask.state)}, - .arraySize = 0}, - {.name = {"BIZ_STAGE"}, - .t = HISYSEVENT_INT32, - .v = {.i32 = static_cast(reportTask.stage)}, - .arraySize = 0}, - {.name = {"STAGE_RES"}, - .t = HISYSEVENT_INT32, - .v = {.i32 = static_cast(reportTask.result)}, - .arraySize = 0}, - {.name = {"ERROR_CODE"}, - .t = HISYSEVENT_INT32, - .v = {.i32 = static_cast(dbDfxErrCode)}, - .arraySize = 0}, - }; RuntimeContext::GetInstance()->ScheduleTask([=]() { + int dbDfxErrCode = -(reportTask.errCode - E_BASE) + E_DB_DFX_BASE; + struct HiSysEventParam params[] = { + {.name = {"ORG_PKG"}, + .t = HISYSEVENT_STRING, + .v = {.s = const_cast(ORG_PKG_NAME.c_str())}, + .arraySize = 0}, + {.name = {"FUNC"}, + .t = HISYSEVENT_STRING, + .v = {.s = const_cast(reportTask.funcName.c_str())}, + .arraySize = 0}, + {.name = {"BIZ_SCENE"}, + .t = HISYSEVENT_INT32, + .v = {.i32 = static_cast(reportTask.scene)}, + .arraySize = 0}, + {.name = {"BIZ_STATE"}, + .t = HISYSEVENT_INT32, + .v = {.i32 = static_cast(reportTask.state)}, + .arraySize = 0}, + {.name = {"BIZ_STAGE"}, + .t = HISYSEVENT_INT32, + .v = {.i32 = static_cast(reportTask.stage)}, + .arraySize = 0}, + {.name = {"STAGE_RES"}, + .t = HISYSEVENT_INT32, + .v = {.i32 = static_cast(reportTask.result)}, + .arraySize = 0}, + {.name = {"ERROR_CODE"}, + .t = HISYSEVENT_INT32, + .v = {.i32 = static_cast(dbDfxErrCode)}, + .arraySize = 0}, + }; // call hievent here OH_HiSysEvent_Write(OHOS::HiviewDFX::HiSysEvent::Domain::DISTRIBUTED_DATAMGR, DISTRIBUTED_DB_BEHAVIOR.c_str(), diff --git a/kv_store/frameworks/libs/distributeddb/common/src/relational/tracker_table.cpp b/kv_store/frameworks/libs/distributeddb/common/src/relational/tracker_table.cpp index aaeca8b1..c498bdc7 100644 --- a/kv_store/frameworks/libs/distributeddb/common/src/relational/tracker_table.cpp +++ b/kv_store/frameworks/libs/distributeddb/common/src/relational/tracker_table.cpp @@ -157,9 +157,9 @@ const std::string TrackerTable::GetTempTriggerName(TriggerMode::TriggerModeEnum const std::string TrackerTable::GetTempInsertTriggerSql(bool incFlag) const { // This trigger is built on the log table - std::string sql = "CREATE TEMP TRIGGER IF NOT EXISTS " + DBConstant::RELATIONAL_PREFIX + tableName_; - sql += "_ON_INSERT_TEMP AFTER INSERT ON " + DBConstant::RELATIONAL_PREFIX + tableName_ + "_log"; - sql += " WHEN (SELECT 1 FROM " + DBConstant::RELATIONAL_PREFIX + "metadata" + + std::string sql = "CREATE TEMP TRIGGER IF NOT EXISTS " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName_; + sql += "_ON_INSERT_TEMP AFTER INSERT ON " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName_ + "_log"; + sql += " WHEN (SELECT 1 FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + "metadata" + " WHERE key = 'log_trigger_switch' AND value = 'false')\n"; sql += "BEGIN\n"; if (incFlag) { @@ -167,10 +167,10 @@ const std::string TrackerTable::GetTempInsertTriggerSql(bool incFlag) const } else { sql += CloudStorageUtils::GetCursorIncSql(tableName_) + "\n"; } - sql += "UPDATE " + DBConstant::RELATIONAL_PREFIX + tableName_ + "_log" + " SET "; + sql += "UPDATE " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName_ + "_log" + " SET "; if (incFlag) { - sql += "cursor= case when (select 1 from " + - DBConstant::RELATIONAL_PREFIX + "metadata where key='cursor_inc_flag' AND value = 'true') then " + + sql += "cursor= case when (select 1 from " + std::string(DBConstant::RELATIONAL_PREFIX) + + "metadata where key='cursor_inc_flag' AND value = 'true') then " + CloudStorageUtils::GetSelectIncCursorSql(tableName_) + " else cursor end WHERE"; } else { sql += "cursor=" + CloudStorageUtils::GetSelectIncCursorSql(tableName_) + " WHERE"; @@ -185,9 +185,9 @@ const std::string TrackerTable::GetTempInsertTriggerSql(bool incFlag) const const std::string TrackerTable::GetTempUpdateTriggerSql(bool incFlag) const { - std::string sql = "CREATE TEMP TRIGGER IF NOT EXISTS " + DBConstant::RELATIONAL_PREFIX + tableName_; + std::string sql = "CREATE TEMP TRIGGER IF NOT EXISTS " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName_; sql += "_ON_UPDATE_TEMP AFTER UPDATE ON " + tableName_; - sql += " WHEN (SELECT 1 FROM " + DBConstant::RELATIONAL_PREFIX + "metadata" + + sql += " WHEN (SELECT 1 FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + "metadata" + " WHERE key = 'log_trigger_switch' AND value = 'false')\n"; sql += "BEGIN\n"; if (incFlag) { @@ -195,13 +195,13 @@ const std::string TrackerTable::GetTempUpdateTriggerSql(bool incFlag) const } else { sql += CloudStorageUtils::GetCursorIncSql(tableName_) + "\n"; } - sql += "UPDATE " + DBConstant::RELATIONAL_PREFIX + tableName_ + "_log" + " SET "; + sql += "UPDATE " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName_ + "_log" + " SET "; if (!IsEmpty()) { sql += "extend_field=" + GetAssignValSql() + ","; } if (incFlag) { - sql += "cursor= case when (select 1 from " + - DBConstant::RELATIONAL_PREFIX + "metadata where key='cursor_inc_flag' AND value = 'true') then " + + sql += "cursor= case when (select 1 from " + std::string(DBConstant::RELATIONAL_PREFIX) + + "metadata where key='cursor_inc_flag' AND value = 'true') then " + CloudStorageUtils::GetSelectIncCursorSql(tableName_) + " else cursor end WHERE"; } else { sql += "cursor=" + CloudStorageUtils::GetSelectIncCursorSql(tableName_) + " WHERE"; @@ -216,9 +216,9 @@ const std::string TrackerTable::GetTempUpdateTriggerSql(bool incFlag) const const std::string TrackerTable::GetTempDeleteTriggerSql(bool incFlag) const { - std::string sql = "CREATE TEMP TRIGGER IF NOT EXISTS " + DBConstant::RELATIONAL_PREFIX + tableName_; + std::string sql = "CREATE TEMP TRIGGER IF NOT EXISTS " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName_; sql += "_ON_DELETE_TEMP AFTER DELETE ON " + tableName_ + - " WHEN (SELECT 1 FROM " + DBConstant::RELATIONAL_PREFIX + "metadata" + + " WHEN (SELECT 1 FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + "metadata" + " WHERE key = 'log_trigger_switch' AND value = 'false')\n"; sql += "BEGIN\n"; if (IsEmpty() && incFlag) { @@ -229,7 +229,7 @@ const std::string TrackerTable::GetTempDeleteTriggerSql(bool incFlag) const if (!incFlag) { sql += CloudStorageUtils::GetCursorIncSql(tableName_) + "\n"; } - sql += "UPDATE " + DBConstant::RELATIONAL_PREFIX + tableName_ + "_log" + " SET "; + sql += "UPDATE " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName_ + "_log" + " SET "; if (!IsEmpty()) { sql += "extend_field=" + GetAssignValSql(true) + ","; } @@ -267,6 +267,11 @@ bool TrackerTable::IsEmpty() const return trackerColNames_.empty() && !isTrackerAction_; } +bool TrackerTable::IsTableNameEmpty() const +{ + return tableName_.empty(); +} + bool TrackerTable::IsChanging(const TrackerSchema &schema) { if (tableName_ != schema.tableName || extendColName_ != schema.extendColName) { 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 10bf1f48..113caa42 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 @@ -530,11 +530,6 @@ int RuntimeContextImpl::SetSecurityOption(const std::string &filePath, const Sec return -E_NOT_SUPPORT; } - if (option == SecurityOption()) { - LOGD("SecurityOption is NOT_SET,Not need to set security option!"); - return E_OK; - } - std::string fileRealPath; int errCode = OS::GetRealPath(filePath, fileRealPath); if (errCode != E_OK) { diff --git a/kv_store/frameworks/libs/distributeddb/communicator/include/communicator_type_define.h b/kv_store/frameworks/libs/distributeddb/communicator/include/communicator_type_define.h index af35a296..bedab08e 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/include/communicator_type_define.h +++ b/kv_store/frameworks/libs/distributeddb/communicator/include/communicator_type_define.h @@ -25,7 +25,7 @@ namespace DistributedDB { using LabelType = std::vector; using Finalizer = std::function; -using OnSendEnd = std::function; +using OnSendEnd = std::function; using OnConnectCallback = std::function; constexpr unsigned int COMM_LABEL_LENGTH = 32; // Using SHA256 which length is 32 constexpr uint32_t MAX_TOTAL_LEN = 104857600; // 100M Limitation For Max Total Length diff --git a/kv_store/frameworks/libs/distributeddb/communicator/include/iadapter.h b/kv_store/frameworks/libs/distributeddb/communicator/include/iadapter.h index 9945c8d4..b3560e81 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/include/iadapter.h +++ b/kv_store/frameworks/libs/distributeddb/communicator/include/iadapter.h @@ -28,7 +28,7 @@ namespace DistributedDB { using BytesReceiveCallback = std::function; using TargetChangeCallback = std::function; -using SendableCallback = std::function; +using SendableCallback = std::function; class IAdapter { public: diff --git a/kv_store/frameworks/libs/distributeddb/communicator/include/send_task_scheduler.h b/kv_store/frameworks/libs/distributeddb/communicator/include/send_task_scheduler.h index 4f624700..94040f23 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/include/send_task_scheduler.h +++ b/kv_store/frameworks/libs/distributeddb/communicator/include/send_task_scheduler.h @@ -78,6 +78,7 @@ public: uint32_t GetNoDelayTaskCount() const; void InvalidSendTask(const std::string &target); + void SetSoftBusErrCode(const std::string &target, int softBusErrCode); private: int ScheduleDelayTask(SendTask &outTask, SendTaskInfo &outTaskInfo); @@ -101,6 +102,8 @@ private: bool scheduledFlag_ = false; std::string lastScheduleTarget_; Priority lastSchedulePriority_ = Priority::LOW; + + std::map softBusErrCodeMap_; }; } 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 61af65e2..ab137ca3 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_aggregator.cpp +++ b/kv_store/frameworks/libs/distributeddb/communicator/src/communicator_aggregator.cpp @@ -281,7 +281,7 @@ void DoOnSendEndByTaskIfNeed(const OnSendEnd &onEnd, int result) if (onEnd) { // LCOV_EXCL_BR_LINE TaskAction onSendEndTask = [onEnd, result]() { LOGD("[CommAggr][SendEndTask] Before On Send End."); - onEnd(result); + onEnd(result, true); LOGD("[CommAggr][SendEndTask] After On Send End."); }; int errCode = RuntimeContext::GetInstance()->ScheduleTask(onSendEndTask); @@ -452,7 +452,7 @@ void CommunicatorAggregator::TaskFinalizer(const SendTask &inTask, int result) // Call the OnSendEnd if need if (inTask.onEnd) { LOGD("[CommAggr][TaskFinal] On Send End."); - inTask.onEnd(result); + inTask.onEnd(result, true); } // Finalize the task that just scheduled int errCode = scheduler_.FinalizeLastScheduleTask(); @@ -738,10 +738,13 @@ int CommunicatorAggregator::RegCallbackToAdapter() } RefObject::IncObjRef(this); // Reference to be hold by adapter - errCode = adapterHandle_->RegSendableCallback([this](const std::string &target) { - LOGI("[CommAggr] Send able dev=%.3s", target.c_str()); - (void)IncreaseSendSequenceId(target); - OnSendable(target); + errCode = adapterHandle_->RegSendableCallback([this](const std::string &target, int softBusErrCode) { + LOGI("[CommAggr] Send able dev=%.3s, softBusErrCode=%d", target.c_str(), softBusErrCode); + if (softBusErrCode == E_OK) { + (void)IncreaseSendSequenceId(target); + OnSendable(target); + } + scheduler_.SetSoftBusErrCode(target, softBusErrCode); }, [this]() { RefObject::DecObjRef(this); }); if (errCode != E_OK) { 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 1aaa35da..f1a7e355 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/src/network_adapter.cpp +++ b/kv_store/frameworks/libs/distributeddb/communicator/src/network_adapter.cpp @@ -84,9 +84,9 @@ int NetworkAdapter::StartAdapter() LOGI("[NAdapt][Start] ROLLBACK: Stop errCode=%d.", static_cast(errCode)); return -E_PERIPHERAL_INTERFACE_FAIL; } - processCommunicator_->RegOnSendAble([this](const DeviceInfos &devInfo) { + processCommunicator_->RegOnSendAble([this](const DeviceInfos &devInfo, int softBusErrCode) { if (onSendableHandle_ != nullptr) { - onSendableHandle_(devInfo.identifier); + onSendableHandle_(devInfo.identifier, softBusErrCode); } }); // These code is compensation for the probable defect of IProcessCommunicator implementation. diff --git a/kv_store/frameworks/libs/distributeddb/communicator/src/send_task_scheduler.cpp b/kv_store/frameworks/libs/distributeddb/communicator/src/send_task_scheduler.cpp index 39f39b0c..5c3cb936 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/src/send_task_scheduler.cpp +++ b/kv_store/frameworks/libs/distributeddb/communicator/src/send_task_scheduler.cpp @@ -300,7 +300,22 @@ void SendTaskScheduler::InvalidSendTask(const std::string &target) for (auto &sendTask : taskGroupByPrio_[priority][target]) { sendTask.isValid = false; LOGI("[Scheduler][InvalidSendTask] invalid frameId=%" PRIu32, sendTask.frameId); + if ((softBusErrCodeMap_.count(target) == 0) || (softBusErrCodeMap_[target] == E_OK)) { + continue; + } + LOGE("[Scheduler][InvalidSendTask] target=%.3s, errCode=%d", target.c_str(), softBusErrCodeMap_[target]); + if (sendTask.onEnd) { + LOGI("[Scheduler][InvalidSendTask] On Send End."); + sendTask.onEnd(softBusErrCodeMap_[target], false); + sendTask.onEnd = nullptr; + } } } + softBusErrCodeMap_.erase(target); +} + +void SendTaskScheduler::SetSoftBusErrCode(const std::string &target, int softBusErrCode) +{ + softBusErrCodeMap_[target] = softBusErrCode; } } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/communicator/src/serial_buffer.cpp b/kv_store/frameworks/libs/distributeddb/communicator/src/serial_buffer.cpp index 1e60c6df..43821cb6 100644 --- a/kv_store/frameworks/libs/distributeddb/communicator/src/serial_buffer.cpp +++ b/kv_store/frameworks/libs/distributeddb/communicator/src/serial_buffer.cpp @@ -129,7 +129,7 @@ SerialBuffer *SerialBuffer::Clone(int &outErrorNo) errno_t errCode = memcpy_s(twinBuffer->bytes_, totalLen_, bytes_, totalLen_); if (errCode != EOK) { outErrorNo = -E_SECUREC_ERROR; - delete twinBuffer->bytes_; + delete[] twinBuffer->bytes_; twinBuffer->bytes_ = nullptr; delete twinBuffer; twinBuffer = nullptr; diff --git a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/base/grd_db_api.cpp b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/base/grd_db_api.cpp index 10d2d10a..07e5a1e8 100644 --- a/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/base/grd_db_api.cpp +++ b/kv_store/frameworks/libs/distributeddb/gaussdb_rd/src/executor/base/grd_db_api.cpp @@ -99,4 +99,4 @@ GRD_API int32_t GRD_IndexPreload(GRD_DB *db, const char *collectionName) return GRD_INNER_ERR; } return GRD_DBApiInfo.IndexPreloadApi(db, collectionName); -} \ No newline at end of file +} diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/include/iprocess_communicator.h b/kv_store/frameworks/libs/distributeddb/interfaces/include/iprocess_communicator.h index 414dd361..5cc6d11b 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/include/iprocess_communicator.h +++ b/kv_store/frameworks/libs/distributeddb/interfaces/include/iprocess_communicator.h @@ -67,7 +67,7 @@ using OnDeviceChange = std::function; -using OnSendAble = std::function; +using OnSendAble = std::function; // For all functions with returnType DBStatus: // return DBStatus::OK if successful, otherwise DBStatus::DB_ERROR if anything wrong. 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 96e9ea66..da91b56d 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/include/store_types.h +++ b/kv_store/frameworks/libs/distributeddb/interfaces/include/store_types.h @@ -82,7 +82,7 @@ enum DBStatus { PROPERTY_CHANGED, // reference property changed CLOUD_VERSION_CONFLICT, // cloud failed to update version CLOUD_RECORD_EXIST_CONFLICT, // this error happen in Download/BatchInsert/BatchUpdate - REMOTE_ASSETS_FAIL, // remove local assets failed + REMOVE_ASSETS_FAIL, // remove local assets failed WITH_INVENTORY_DATA, // inventory data exists when setTracker for the first time WAIT_COMPENSATED_SYNC, // need to do compensated sync CLOUD_SYNC_TASK_MERGED, // sync task is merged 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 1a18a433..aa14598b 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 @@ -46,128 +46,124 @@ std::shared_ptr KvStoreDelegateManager::processCommunicato std::mutex KvStoreDelegateManager::multiUserMutex_; namespace { - const int GET_CONNECT_RETRY = 3; - const int RETRY_GET_CONN_INTER = 30; +const int GET_CONNECT_RETRY = 3; +const int RETRY_GET_CONN_INTER = 30; - IKvDBConnection *GetOneConnectionWithRetry(const KvDBProperties &properties, int &errCode) - { - for (int i = 0; i < GET_CONNECT_RETRY; i++) { - auto conn = KvDBManager::GetDatabaseConnection(properties, errCode); - if (conn != nullptr) { - return conn; - } - if (errCode == -E_STALE) { - std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_GET_CONN_INTER)); - } else { - return nullptr; - } +IKvDBConnection *GetOneConnectionWithRetry(const KvDBProperties &properties, int &errCode) +{ + for (int i = 0; i < GET_CONNECT_RETRY; i++) { + auto conn = KvDBManager::GetDatabaseConnection(properties, errCode); + if (conn != nullptr) { + return conn; + } + if (errCode == -E_STALE) { + std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_GET_CONN_INTER)); + } else { + return nullptr; } - return nullptr; } + return nullptr; +} - DBStatus CheckAndGetSchema(bool isMemoryDb, const std::string &schema, SchemaObject &schemaObj) - { - if (isMemoryDb && !schema.empty()) { - LOGW("[KvStoreDelegateManager] memory database doesn't support the schema."); - return NOT_SUPPORT; - } - if (schema.empty()) { - return OK; - } - schemaObj.ParseFromSchemaString(schema); - if (!schemaObj.IsSchemaValid()) { - return INVALID_SCHEMA; - } +DBStatus CheckAndGetSchema(bool isMemoryDb, const std::string &schema, SchemaObject &schemaObj) +{ + if (isMemoryDb && !schema.empty()) { + LOGW("[KvStoreDelegateManager] memory database doesn't support the schema."); + return NOT_SUPPORT; + } + if (schema.empty()) { return OK; } + schemaObj.ParseFromSchemaString(schema); + if (!schemaObj.IsSchemaValid()) { + return INVALID_SCHEMA; + } + return OK; +} - void InitPropWithNbOption(KvDBProperties &properties, const std::string &storePath, - const SchemaObject &schema, const KvStoreNbDelegate::Option &option) - { - properties.SetBoolProp(KvDBProperties::CREATE_IF_NECESSARY, option.createIfNecessary); - properties.SetIntProp(KvDBProperties::DATABASE_TYPE, option.storageEngineType == GAUSSDB_RD ? - KvDBProperties::SINGLE_VER_TYPE_RD_KERNAL : KvDBProperties::SINGLE_VER_TYPE_SQLITE); - properties.SetBoolProp(KvDBProperties::MEMORY_MODE, option.isMemoryDb); - properties.SetBoolProp(KvDBProperties::ENCRYPTED_MODE, option.isEncryptedDb); - if (!option.isMemoryDb) { // memory db ignore store path - properties.SetStringProp(KvDBProperties::DATA_DIR, storePath); - } - properties.SetBoolProp(KvDBProperties::CREATE_DIR_BY_STORE_ID_ONLY, option.createDirByStoreIdOnly); - properties.SetSchema(schema); - properties.SetBoolProp(KvDBProperties::CHECK_INTEGRITY, option.isNeedIntegrityCheck); - properties.SetBoolProp(KvDBProperties::RM_CORRUPTED_DB, option.isNeedRmCorruptedDb); - if (RuntimeContext::GetInstance()->IsProcessSystemApiAdapterValid()) { - properties.SetIntProp(KvDBProperties::SECURITY_LABEL, option.secOption.securityLabel); - properties.SetIntProp(KvDBProperties::SECURITY_FLAG, option.secOption.securityFlag); - } - properties.SetIntProp(KvDBProperties::CONFLICT_RESOLVE_POLICY, option.conflictResolvePolicy); - - if (option.isEncryptedDb) { - properties.SetPassword(option.cipher, option.passwd); - } - properties.SetBoolProp(KvDBProperties::COMPRESS_ON_SYNC, option.isNeedCompressOnSync); - if (option.isNeedCompressOnSync) { - properties.SetIntProp(KvDBProperties::COMPRESSION_RATE, - ParamCheckUtils::GetValidCompressionRate(option.compressionRate)); - } - properties.SetBoolProp(KvDBProperties::SYNC_DUAL_TUPLE_MODE, option.syncDualTupleMode); - properties.SetBoolProp(KvDBProperties::LOCAL_ONLY, option.localOnly); - properties.SetBoolProp(KvDBProperties::READ_ONLY_MODE, option.rdconfig.readOnly); - bool sharedMode = (option.storageEngineType == GAUSSDB_RD); - properties.SetBoolProp(KvDBProperties::SHARED_MODE, sharedMode); - properties.SetUIntProp(KvDBProperties::PAGE_SIZE1, option.rdconfig.pageSize); - properties.SetUIntProp(KvDBProperties::CACHE_SIZE, option.rdconfig.cacheSize); - properties.SetIntProp(KvDBProperties::INDEX_TYPE, option.rdconfig.type); +void InitPropWithNbOption(KvDBProperties &properties, const std::string &storePath, const SchemaObject &schema, + const KvStoreNbDelegate::Option &option) +{ + properties.SetBoolProp(KvDBProperties::CREATE_IF_NECESSARY, option.createIfNecessary); + properties.SetIntProp(KvDBProperties::DATABASE_TYPE, + option.storageEngineType == GAUSSDB_RD ? KvDBProperties::SINGLE_VER_TYPE_RD_KERNAL + : KvDBProperties::SINGLE_VER_TYPE_SQLITE); + properties.SetBoolProp(KvDBProperties::MEMORY_MODE, option.isMemoryDb); + properties.SetBoolProp(KvDBProperties::ENCRYPTED_MODE, option.isEncryptedDb); + if (!option.isMemoryDb) { // memory db ignore store path + properties.SetStringProp(KvDBProperties::DATA_DIR, storePath); + } + properties.SetBoolProp(KvDBProperties::CREATE_DIR_BY_STORE_ID_ONLY, option.createDirByStoreIdOnly); + properties.SetSchema(schema); + properties.SetBoolProp(KvDBProperties::CHECK_INTEGRITY, option.isNeedIntegrityCheck); + properties.SetBoolProp(KvDBProperties::RM_CORRUPTED_DB, option.isNeedRmCorruptedDb); + if (RuntimeContext::GetInstance()->IsProcessSystemApiAdapterValid()) { + properties.SetIntProp(KvDBProperties::SECURITY_LABEL, option.secOption.securityLabel); + properties.SetIntProp(KvDBProperties::SECURITY_FLAG, option.secOption.securityFlag); } + properties.SetIntProp(KvDBProperties::CONFLICT_RESOLVE_POLICY, option.conflictResolvePolicy); - bool CheckObserverConflictParam(const KvStoreNbDelegate::Option &option) - { - if ((option.notifier && !ParamCheckUtils::CheckConflictNotifierType(option.conflictType)) || - (!option.notifier && option.conflictType != 0)) { - LOGE("Invalid conflict type, conflict type is [%d]", option.conflictType); - return false; - } - if ((option.observer != nullptr && !ParamCheckUtils::CheckObserver(option.key, option.mode)) || - (option.observer == nullptr && (!option.key.empty() || option.mode != 0))) { - LOGE("Invalid observer param, observer mode is [%u]", option.mode); - return false; - } - return true; + if (option.isEncryptedDb) { + properties.SetPassword(option.cipher, option.passwd); + } + properties.SetBoolProp(KvDBProperties::COMPRESS_ON_SYNC, option.isNeedCompressOnSync); + if (option.isNeedCompressOnSync) { + properties.SetIntProp( + KvDBProperties::COMPRESSION_RATE, ParamCheckUtils::GetValidCompressionRate(option.compressionRate)); + } + properties.SetBoolProp(KvDBProperties::SYNC_DUAL_TUPLE_MODE, option.syncDualTupleMode); + properties.SetBoolProp(KvDBProperties::LOCAL_ONLY, option.localOnly); + properties.SetBoolProp(KvDBProperties::READ_ONLY_MODE, option.rdconfig.readOnly); + bool sharedMode = (option.storageEngineType == GAUSSDB_RD); + properties.SetBoolProp(KvDBProperties::SHARED_MODE, sharedMode); + properties.SetUIntProp(KvDBProperties::PAGE_SIZE1, option.rdconfig.pageSize); + properties.SetUIntProp(KvDBProperties::CACHE_SIZE, option.rdconfig.cacheSize); + properties.SetIntProp(KvDBProperties::INDEX_TYPE, option.rdconfig.type); +} + +bool CheckObserverConflictParam(const KvStoreNbDelegate::Option &option) +{ + if ((option.notifier && !ParamCheckUtils::CheckConflictNotifierType(option.conflictType)) || + (!option.notifier && option.conflictType != 0)) { + LOGE("Invalid conflict type, conflict type is [%d]", option.conflictType); + return false; + } + if ((option.observer != nullptr && !ParamCheckUtils::CheckObserver(option.key, option.mode)) || + (option.observer == nullptr && (!option.key.empty() || option.mode != 0))) { + LOGE("Invalid observer param, observer mode is [%u]", option.mode); + return false; } + return true; +} #ifndef OMIT_MULTI_VER - void InitPropWithOption(KvDBProperties &properties, const std::string &storePath, - const KvStoreDelegate::Option &option) - { - properties.SetBoolProp(KvDBProperties::CREATE_IF_NECESSARY, option.createIfNecessary); - properties.SetBoolProp(KvDBProperties::CREATE_DIR_BY_STORE_ID_ONLY, option.createDirByStoreIdOnly); - properties.SetIntProp(KvDBProperties::DATABASE_TYPE, - ((option.localOnly == true) ? KvDBProperties::LOCAL_TYPE_SQLITE : KvDBProperties::MULTI_VER_TYPE_SQLITE)); - properties.SetBoolProp(KvDBProperties::MEMORY_MODE, false); - properties.SetBoolProp(KvDBProperties::ENCRYPTED_MODE, option.isEncryptedDb); - properties.SetStringProp(KvDBProperties::DATA_DIR, storePath); - if (option.isEncryptedDb) { - properties.SetPassword(option.cipher, option.passwd); - } +void InitPropWithOption(KvDBProperties &properties, const std::string &storePath, const KvStoreDelegate::Option &option) +{ + properties.SetBoolProp(KvDBProperties::CREATE_IF_NECESSARY, option.createIfNecessary); + properties.SetBoolProp(KvDBProperties::CREATE_DIR_BY_STORE_ID_ONLY, option.createDirByStoreIdOnly); + properties.SetIntProp(KvDBProperties::DATABASE_TYPE, + ((option.localOnly == true) ? KvDBProperties::LOCAL_TYPE_SQLITE : KvDBProperties::MULTI_VER_TYPE_SQLITE)); + properties.SetBoolProp(KvDBProperties::MEMORY_MODE, false); + properties.SetBoolProp(KvDBProperties::ENCRYPTED_MODE, option.isEncryptedDb); + properties.SetStringProp(KvDBProperties::DATA_DIR, storePath); + if (option.isEncryptedDb) { + properties.SetPassword(option.cipher, option.passwd); } -#endif } +#endif +} // namespace KvStoreDelegateManager::KvStoreDelegateManager(const std::string &appId, const std::string &userId, int32_t instanceId) - : appId_(appId), - userId_(userId), - instanceId_(instanceId) + : appId_(appId), userId_(userId), 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( + 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() {} +KvStoreDelegateManager::~KvStoreDelegateManager() +{} DBStatus KvStoreDelegateManager::SetKvStoreConfig(const KvStoreConfig &kvStoreConfig) { @@ -210,7 +206,7 @@ void KvStoreDelegateManager::GetKvStore(const std::string &storeId, const KvStor KvDBProperties properties; InitPropWithOption(properties, GetKvStorePath(), option); - DbIdParam dbIdParam = { appId_, userId_, storeId }; + DbIdParam dbIdParam = {appId_, userId_, storeId}; DBCommon::SetDatabaseIds(properties, dbIdParam); int errCode; @@ -236,8 +232,8 @@ void KvStoreDelegateManager::GetKvStore(const std::string &storeId, const KvStor #endif } -DBStatus KvStoreDelegateManager::SetObserverNotifier(KvStoreNbDelegate *kvStore, - const KvStoreNbDelegate::Option &option) +DBStatus KvStoreDelegateManager::SetObserverNotifier( + KvStoreNbDelegate *kvStore, const KvStoreNbDelegate::Option &option) { DBStatus status; if (option.observer != nullptr) { @@ -294,8 +290,7 @@ bool KvStoreDelegateManager::GetKvStoreParamCheck(const std::string &storeId, co return false; } } else { - if (option.secOption.securityLabel != SecurityLabel::NOT_SET || - option.secOption.securityFlag != 0) { + if (option.secOption.securityLabel != SecurityLabel::NOT_SET || option.secOption.securityFlag != 0) { LOGE("Memory db has no physical files, Is not controlled by security labels, so not support set labels"); callback(INVALID_ARGS, nullptr); return false; @@ -331,7 +326,7 @@ void KvStoreDelegateManager::GetKvStore(const std::string &storeId, const KvStor } KvDBProperties properties; InitPropWithNbOption(properties, GetKvStorePath(), schema, tmpOption); - DbIdParam dbIdParam = { appId_, userId_, storeId, subUser_, instanceId_ }; + DbIdParam dbIdParam = {appId_, userId_, storeId, subUser_, instanceId_}; DBCommon::SetDatabaseIds(properties, dbIdParam); int errCode; @@ -416,7 +411,7 @@ DBStatus KvStoreDelegateManager::DeleteKvStore(const std::string &storeId) KvDBProperties properties; properties.SetStringProp(KvDBProperties::DATA_DIR, GetKvStorePath()); - DbIdParam dbIdParam = { appId_, userId_, storeId, subUser_ }; + DbIdParam dbIdParam = {appId_, userId_, storeId, subUser_}; DBCommon::SetDatabaseIds(properties, dbIdParam); int errCode = KvDBManager::RemoveDatabase(properties); if (errCode == E_OK) { @@ -486,7 +481,7 @@ DBStatus KvStoreDelegateManager::GetKvStoreDiskSize(const std::string &storeId, } KvDBProperties properties; properties.SetStringProp(KvDBProperties::DATA_DIR, dataDir); - DbIdParam dbIdParam = { appId_, userId_, storeId, subUser_ }; + DbIdParam dbIdParam = {appId_, userId_, storeId, subUser_}; DBCommon::SetDatabaseIds(properties, dbIdParam); int errCode = KvDBManager::CalculateKvStoreSize(properties, size); if (errCode != E_OK) { @@ -505,8 +500,8 @@ void KvStoreDelegateManager::SetKvStoreCorruptionHandler(const KvStoreCorruption KvDBManager::SetDatabaseCorruptionHandler(handler); } -DBStatus KvStoreDelegateManager::GetDatabaseDir(const std::string &storeId, const std::string &appId, - const std::string &userId, std::string &directory) +DBStatus KvStoreDelegateManager::GetDatabaseDir( + const std::string &storeId, const std::string &appId, const std::string &userId, std::string &directory) { if (!ParamCheckUtils::CheckStoreParameter(storeId, appId, userId)) { return INVALID_ARGS; @@ -587,8 +582,8 @@ DBStatus KvStoreDelegateManager::EnableKvStoreAutoLaunch(const std::string &user return OK; } -DBStatus KvStoreDelegateManager::DisableKvStoreAutoLaunch(const std::string &userId, const std::string &appId, - const std::string &storeId) +DBStatus KvStoreDelegateManager::DisableKvStoreAutoLaunch( + const std::string &userId, const std::string &appId, const std::string &storeId) { if (RuntimeContext::GetInstance() == nullptr) { return DB_ERROR; @@ -611,8 +606,8 @@ void KvStoreDelegateManager::SetAutoLaunchRequestCallback(const AutoLaunchReques RuntimeContext::GetInstance()->SetAutoLaunchRequestCallback(callback, DBTypeInner::DB_KV); } -std::string KvStoreDelegateManager::GetKvStoreIdentifier(const std::string &userId, const std::string &appId, - const std::string &storeId, bool syncDualTupleMode) +std::string KvStoreDelegateManager::GetKvStoreIdentifier( + const std::string &userId, const std::string &appId, const std::string &storeId, bool syncDualTupleMode) { return RuntimeConfig::GetStoreIdentifier(userId, appId, storeId, syncDualTupleMode); } diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_errno.cpp b/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_errno.cpp index 06ac08db..b2d889cb 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_errno.cpp +++ b/kv_store/frameworks/libs/distributeddb/interfaces/src/kv_store_errno.cpp @@ -78,7 +78,7 @@ namespace { { -E_TABLE_REFERENCE_CHANGED, PROPERTY_CHANGED }, { -E_CLOUD_VERSION_CONFLICT, CLOUD_VERSION_CONFLICT }, { -E_CLOUD_RECORD_EXIST_CONFLICT, CLOUD_RECORD_EXIST_CONFLICT }, - { -E_REMOVE_ASSETS_FAILED, REMOTE_ASSETS_FAIL }, + { -E_REMOVE_ASSETS_FAILED, REMOVE_ASSETS_FAIL }, { -E_WITH_INVENTORY_DATA, WITH_INVENTORY_DATA }, { -E_WAIT_COMPENSATED_SYNC, WAIT_COMPENSATED_SYNC }, { -E_CLOUD_SYNC_TASK_MERGED, CLOUD_SYNC_TASK_MERGED }, 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 cdcbb30a..96a1a628 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 @@ -1280,7 +1280,7 @@ int HandleDropLogicDeleteData(sqlite3 *db, const std::string &tableName, uint64_ LOGI("DropLogicDeleteData on table:%s length:%d cursor:%" PRIu64, DBCommon::StringMiddleMasking(tableName).c_str(), tableName.size(), cursor); std::string logTblName = DBCommon::GetLogTableName(tableName); - std::string sql = "INSERT OR REPLACE INTO " + DBConstant::RELATIONAL_PREFIX + "metadata" + + std::string sql = "INSERT OR REPLACE INTO " + std::string(DBConstant::RELATIONAL_PREFIX) + "metadata" + " VALUES ('log_trigger_switch', 'false')"; int errCode = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr); if (errCode != SQLITE_OK) { @@ -1301,7 +1301,7 @@ int HandleDropLogicDeleteData(sqlite3 *db, const std::string &tableName, uint64_ LOGE("delete logic delete log failed. %d", errCode); return errCode; } - sql = "INSERT OR REPLACE INTO " + DBConstant::RELATIONAL_PREFIX + "metadata" + + sql = "INSERT OR REPLACE INTO " + std::string(DBConstant::RELATIONAL_PREFIX) + "metadata" + " VALUES ('log_trigger_switch', 'true')"; errCode = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr); if (errCode != SQLITE_OK) { 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 aaf08ced..dee39e70 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/include/db_properties.h +++ b/kv_store/frameworks/libs/distributeddb/storage/include/db_properties.h @@ -75,4 +75,4 @@ protected: std::map uintProperties_; }; } -#endif \ No newline at end of file +#endif 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 fc0c08c3..3625b9ab 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 @@ -1485,8 +1485,9 @@ std::string CloudStorageUtils::GetCursorIncSql(const std::string &tableName) std::string CloudStorageUtils::GetCursorIncSqlWhenAllow(const std::string &tableName) { - return "UPDATE " + DBConstant::RELATIONAL_PREFIX + "metadata" + " SET value= case when (select 1 from " + - DBConstant::RELATIONAL_PREFIX + "metadata" + " where key='cursor_inc_flag' AND value = 'true') then value + 1" + + std::string prefix = DBConstant::RELATIONAL_PREFIX; + return "UPDATE " + prefix + "metadata" + " SET value= case when (select 1 from " + + prefix + "metadata" + " where key='cursor_inc_flag' AND value = 'true') then value + 1" + " else value end WHERE key=x'" + DBCommon::TransferStringToHex(DBCommon::GetCursorKey(tableName)) + "';"; } 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 6748d004..4b6865ce 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 @@ -165,8 +165,8 @@ void SchemaMgr::SetCloudDbSchema(const DataBaseSchema &schema, RelationalSchemaO // remove the fields that are not found in local schema from cloud schema for (auto it = table.fields.begin(); it != table.fields.end();) { if (localFields.find((*it).colName) == localFields.end()) { + LOGW("Column mismatch, colName: %s", (*it).colName.c_str()); it = table.fields.erase(it); - LOGI("Column name mismatch between local and cloud schema, colName: %s", (*it).colName.c_str()); } else { ++it; } 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 88eb0d8d..4dc8f24f 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 @@ -312,7 +312,7 @@ int RdSingleVerNaturalStore::PreCheckRdImport(std::string &storePath) } int RdSingleVerNaturalStore::Import(const std::string &filePath, const CipherPassword &passwd, - bool isNeedIntegrityCheck) + [[gnu::unused]] bool isNeedIntegrityCheck) { int errCode = E_OK; std::string storePath; 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 d14fecc9..968f82a6 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 @@ -146,6 +146,8 @@ protected: virtual ICloudSyncStorageInterface *GetICloudSyncInterface() const; int CleanAllWaterMark(); + + CloudSyncer *GetAndIncCloudSyncer(); protected: virtual std::map GetDataBaseSchemas(); @@ -162,8 +164,6 @@ private: int CheckSyncOption(const CloudSyncOption &option, const CloudSyncer &syncer); - CloudSyncer *GetAndIncCloudSyncer(); - SyncerProxy syncer_; std::atomic started_; std::atomic closed_; 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 2dce6720..ac754ca9 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 @@ -1762,7 +1762,7 @@ int RelationalSyncAbleStorage::UpsertData(RecordStatus status, const std::string { int errCode = E_OK; auto *handle = GetHandle(true, errCode); - if (errCode != E_OK) { + if (handle == nullptr || errCode != E_OK) { return errCode; } handle->SetPutDataMode(SQLiteSingleVerRelationalStorageExecutor::PutDataMode::USER); @@ -1943,7 +1943,7 @@ int RelationalSyncAbleStorage::GetCompensatedSyncQuery(std::vectorStartTransaction(TransactType::IMMEDIATE); @@ -2202,7 +2202,7 @@ int RelationalSyncAbleStorage::GetLocalDataCount(const std::string &tableName, i { int errCode = E_OK; auto *handle = GetHandle(false, errCode); - if (errCode != E_OK) { + if (handle == nullptr || errCode != E_OK) { LOGE("[RelationalSyncAbleStorage] Get handle failed when get local data count: %d", errCode); return errCode; } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/relational/relational_sync_data_inserter.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/relational/relational_sync_data_inserter.cpp index a83a6e80..0edb9c65 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/relational/relational_sync_data_inserter.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/relational/relational_sync_data_inserter.cpp @@ -175,7 +175,8 @@ int RelationalSyncDataInserter::BindInsertStatement(sqlite3_stmt *stmt, const Da int RelationalSyncDataInserter::GetDeleteLogStmt(sqlite3 *db, sqlite3_stmt *&stmt) { - std::string sql = "DELETE FROM " + DBConstant::RELATIONAL_PREFIX + localTable_.GetTableName() + "_log "; + std::string sql = "DELETE FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + localTable_.GetTableName() + + "_log "; if (mode_ == DistributedTableMode::COLLABORATION) { sql += "WHERE hash_key=?"; } else { 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 79e89304..6e6d930e 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 @@ -95,7 +95,7 @@ std::string CloudSyncLogTableManager::GetInsertTrigger(const TableInfo &table, c std::string insertTrigger = "CREATE TRIGGER IF NOT EXISTS "; insertTrigger += "naturalbase_rdb_" + tableName + "_ON_INSERT AFTER INSERT \n"; insertTrigger += "ON '" + tableName + "'\n"; - insertTrigger += "WHEN (SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + "metadata "; + insertTrigger += "WHEN (SELECT count(*) FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + "metadata "; insertTrigger += "WHERE key = 'log_trigger_switch' AND value = 'true')\n"; insertTrigger += "BEGIN\n"; insertTrigger += CloudStorageUtils::GetCursorIncSql(tableName) + "\n"; @@ -116,7 +116,7 @@ std::string CloudSyncLogTableManager::GetInsertTrigger(const TableInfo &table, c insertTrigger += CloudStorageUtils::GetTableRefUpdateSql(table, OpType::INSERT); insertTrigger += "SELECT client_observer('" + tableName + "', NEW." + std::string(DBConstant::SQLITE_INNER_ROWID); insertTrigger += ", 0, "; - insertTrigger += (table.GetTrackerTable().GetTrackerColNames().empty() ? "0" : "1"); + insertTrigger += (table.GetTrackerTable().IsEmpty() ? "0" : "1"); insertTrigger += ");\n"; insertTrigger += "END;"; return insertTrigger; @@ -130,13 +130,13 @@ std::string CloudSyncLogTableManager::GetUpdateTrigger(const TableInfo &table, c std::string updateTrigger = "CREATE TRIGGER IF NOT EXISTS "; updateTrigger += "naturalbase_rdb_" + tableName + "_ON_UPDATE AFTER UPDATE \n"; updateTrigger += "ON '" + tableName + "'\n"; - updateTrigger += "WHEN (SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + "metadata "; + updateTrigger += "WHEN (SELECT count(*) FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + "metadata "; updateTrigger += "WHERE key = 'log_trigger_switch' AND value = 'true')\n"; updateTrigger += "BEGIN\n"; // if user change the primary key, we can still use gid to identify which one is updated updateTrigger += CloudStorageUtils::GetCursorIncSql(tableName) + "\n"; updateTrigger += "\t UPDATE " + logTblName; updateTrigger += " SET timestamp=get_raw_sys_time(), device='', flag=0x02|0x20"; - if (!table.GetTrackerTable().GetTrackerColNames().empty()) { + if (!table.GetTrackerTable().IsEmpty()) { updateTrigger += table.GetTrackerTable().GetExtendAssignValSql(); } updateTrigger += ", cursor=" + CloudStorageUtils::GetSelectIncCursorSql(tableName) + ", "; @@ -159,7 +159,7 @@ std::string CloudSyncLogTableManager::GetDeleteTrigger(const TableInfo &table, c std::string deleteTrigger = "CREATE TRIGGER IF NOT EXISTS "; deleteTrigger += "naturalbase_rdb_" + tableName + "_ON_DELETE BEFORE DELETE \n"; deleteTrigger += "ON '" + tableName + "'\n"; - deleteTrigger += "WHEN (SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + "metadata "; + deleteTrigger += "WHEN (SELECT count(*) FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + "metadata "; deleteTrigger += "WHERE key = 'log_trigger_switch' AND VALUE = 'true')\n"; deleteTrigger += "BEGIN\n"; deleteTrigger += CloudStorageUtils::GetCursorIncSql(tableName) + "\n"; @@ -171,7 +171,7 @@ std::string CloudSyncLogTableManager::GetDeleteTrigger(const TableInfo &table, c std::to_string(localDeleteFlag | static_cast(LogInfoFlag::FLAG_DEVICE_CLOUD_INCONSISTENCY)) + " END),"; deleteTrigger += "timestamp=get_raw_sys_time()"; - if (!table.GetTrackerTable().GetTrackerColNames().empty()) { + if (!table.GetTrackerTable().IsEmpty()) { deleteTrigger += table.GetTrackerTable().GetExtendAssignValSql(true); } deleteTrigger += ", cursor=" + CloudStorageUtils::GetSelectIncCursorSql(tableName) + ", "; @@ -180,7 +180,7 @@ std::string CloudSyncLogTableManager::GetDeleteTrigger(const TableInfo &table, c deleteTrigger += CloudStorageUtils::GetTableRefUpdateSql(table, OpType::DELETE); // -1 is rowid when data is deleted, 2 means change type is delete(ClientChangeType) deleteTrigger += "SELECT client_observer('" + tableName + "', -1, 2, "; - deleteTrigger += table.GetTrackerTable().GetTrackerColNames().empty() ? "0" : "1"; + deleteTrigger += table.GetTrackerTable().IsEmpty() ? "0" : "1"; deleteTrigger += ");\n"; deleteTrigger += "END;"; return deleteTrigger; @@ -196,7 +196,7 @@ std::vector CloudSyncLogTableManager::GetDropTriggers(const TableIn dropTriggers.emplace_back(insertTrigger); dropTriggers.emplace_back(updateTrigger); dropTriggers.emplace_back(deleteTrigger); - if (table.GetTrackerTable().GetTrackerColNames().empty()) { + if (table.GetTrackerTable().IsEmpty()) { std::string clearExtendSql = "UPDATE " + GetLogTableName(table) + " SET extend_field = '';"; dropTriggers.emplace_back(clearExtendSql); } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/collaboration_log_table_manager.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/collaboration_log_table_manager.cpp index a8951893..501a50b6 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/collaboration_log_table_manager.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/collaboration_log_table_manager.cpp @@ -51,7 +51,7 @@ std::string CollaborationLogTableManager::GetInsertTrigger(const TableInfo &tabl std::string insertTrigger = "CREATE TRIGGER IF NOT EXISTS "; insertTrigger += "naturalbase_rdb_" + table.GetTableName() + "_ON_INSERT AFTER INSERT \n"; insertTrigger += "ON '" + table.GetTableName() + "'\n"; - insertTrigger += "WHEN (SELECT count(*) from " + DBConstant::RELATIONAL_PREFIX + "metadata "; + insertTrigger += "WHEN (SELECT count(*) from " + std::string(DBConstant::RELATIONAL_PREFIX) + "metadata "; insertTrigger += "WHERE key = 'log_trigger_switch' AND value = 'true')\n"; insertTrigger += "BEGIN\n"; insertTrigger += "\t INSERT OR REPLACE INTO " + logTblName; @@ -71,12 +71,12 @@ std::string CollaborationLogTableManager::GetUpdateTrigger(const TableInfo &tabl std::string updateTrigger = "CREATE TRIGGER IF NOT EXISTS "; updateTrigger += "naturalbase_rdb_" + table.GetTableName() + "_ON_UPDATE AFTER UPDATE \n"; updateTrigger += "ON '" + table.GetTableName() + "'\n"; - updateTrigger += "WHEN (SELECT count(*) from " + DBConstant::RELATIONAL_PREFIX + "metadata "; + updateTrigger += "WHEN (SELECT count(*) from " + std::string(DBConstant::RELATIONAL_PREFIX) + "metadata "; updateTrigger += "WHERE key = 'log_trigger_switch' AND value = 'true')\n"; updateTrigger += "BEGIN\n"; if (table.GetIdentifyKey().size() == 1u && table.GetIdentifyKey().at(0) == "rowid") { // primary key is rowid, it can't be changed - updateTrigger += "\t UPDATE " + DBConstant::RELATIONAL_PREFIX + table.GetTableName() + "_log"; + updateTrigger += "\t UPDATE " + std::string(DBConstant::RELATIONAL_PREFIX) + table.GetTableName() + "_log"; updateTrigger += " SET timestamp=get_sys_time(0), device='', flag=0x22"; updateTrigger += " WHERE data_key = OLD." + std::string(DBConstant::SQLITE_INNER_ROWID) + ";"; } else { @@ -103,10 +103,10 @@ std::string CollaborationLogTableManager::GetDeleteTrigger(const TableInfo &tabl std::string deleteTrigger = "CREATE TRIGGER IF NOT EXISTS "; deleteTrigger += "naturalbase_rdb_" + table.GetTableName() + "_ON_DELETE BEFORE DELETE \n"; deleteTrigger += "ON '" + table.GetTableName() + "'\n"; - deleteTrigger += "WHEN (SELECT count(*) from " + DBConstant::RELATIONAL_PREFIX + "metadata "; + deleteTrigger += "WHEN (SELECT count(*) from " + std::string(DBConstant::RELATIONAL_PREFIX) + "metadata "; deleteTrigger += "WHERE key = 'log_trigger_switch' AND VALUE = 'true')\n"; deleteTrigger += "BEGIN\n"; - deleteTrigger += "\t UPDATE " + DBConstant::RELATIONAL_PREFIX + table.GetTableName() + "_log"; + deleteTrigger += "\t UPDATE " + std::string(DBConstant::RELATIONAL_PREFIX) + table.GetTableName() + "_log"; deleteTrigger += " SET data_key=-1,flag=0x03,timestamp=get_sys_time(0)"; deleteTrigger += " WHERE data_key = OLD." + std::string(DBConstant::SQLITE_INNER_ROWID) + ";"; deleteTrigger += "END;"; @@ -121,8 +121,8 @@ std::string CollaborationLogTableManager::GetPrimaryKeySql(const TableInfo &tabl void CollaborationLogTableManager::GetIndexSql(const TableInfo &table, std::vector &schema) { SqliteLogTableManager::GetIndexSql(table, schema); - std::string dataKeyIndex = "CREATE INDEX IF NOT EXISTS " + DBConstant::RELATIONAL_PREFIX + "datakey_index ON " + - GetLogTableName(table) + "(data_key);"; + std::string dataKeyIndex = "CREATE INDEX IF NOT EXISTS " + std::string(DBConstant::RELATIONAL_PREFIX) + + "datakey_index ON " + GetLogTableName(table) + "(data_key);"; schema.emplace_back(dataKeyIndex); } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/split_device_log_table_manager.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/split_device_log_table_manager.cpp index e0f1ef13..db6145dd 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/split_device_log_table_manager.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/split_device_log_table_manager.cpp @@ -62,7 +62,7 @@ std::string SplitDeviceLogTableManager::GetUpdateTrigger(const TableInfo &table, updateTrigger += "BEGIN\n"; if (table.GetPrimaryKey().size() == 1 && table.GetPrimaryKey().at(0) == "rowid") { // primary key is rowid, it can't be changed - updateTrigger += "\t UPDATE " + DBConstant::RELATIONAL_PREFIX + table.GetTableName() + "_log"; + updateTrigger += "\t UPDATE " + std::string(DBConstant::RELATIONAL_PREFIX) + table.GetTableName() + "_log"; updateTrigger += " SET timestamp=get_sys_time(0), device='', flag=0x22"; updateTrigger += " WHERE hash_key=" + CalcPrimaryKeyHash("OLD.", table, identity) + " AND flag&0x02=0x02;\n"; @@ -89,7 +89,7 @@ std::string SplitDeviceLogTableManager::GetDeleteTrigger(const TableInfo &table, deleteTrigger += "naturalbase_rdb_" + table.GetTableName() + "_ON_DELETE BEFORE DELETE \n"; deleteTrigger += "ON '" + table.GetTableName() + "'\n"; deleteTrigger += "BEGIN\n"; - deleteTrigger += "\t UPDATE " + DBConstant::RELATIONAL_PREFIX + table.GetTableName() + "_log"; + deleteTrigger += "\t UPDATE " + std::string(DBConstant::RELATIONAL_PREFIX) + table.GetTableName() + "_log"; deleteTrigger += " SET data_key=-1,flag=0x03,timestamp=get_sys_time(0)"; deleteTrigger += " WHERE hash_key=" + CalcPrimaryKeyHash("OLD.", table, identity) + " AND flag&0x02=0x02;\n"; 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 b51bb93f..b81e8bac 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 @@ -432,7 +432,7 @@ int SQLiteRelationalUtils::QueryCount(sqlite3 *db, const std::string &tableName, int SQLiteRelationalUtils::GetCursor(sqlite3 *db, const std::string &tableName, uint64_t &cursor) { cursor = DBConstant::INVALID_CURSOR; - std::string sql = "SELECT value FROM " + DBConstant::RELATIONAL_PREFIX + "metadata where key = ?;"; + std::string sql = "SELECT value FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + "metadata where key = ?;"; sqlite3_stmt *stmt = nullptr; int errCode = SQLiteUtils::GetStatement(db, sql, stmt); if (errCode != E_OK) { 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 6bee8fb4..c5729e09 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 @@ -122,15 +122,15 @@ int SQLiteSingleRelationalStorageEngine::CreateNewExecutor(bool isWrite, Storage return errCode; } -int SQLiteSingleRelationalStorageEngine::ReleaseExecutor(SQLiteSingleVerRelationalStorageExecutor *&handle) +void SQLiteSingleRelationalStorageEngine::ReleaseExecutor(SQLiteSingleVerRelationalStorageExecutor *&handle, + bool isExternal) { if (handle == nullptr) { - return E_OK; + return; } StorageExecutor *databaseHandle = handle; - Recycle(databaseHandle); + Recycle(databaseHandle, isExternal); handle = nullptr; - return E_OK; } void SQLiteSingleRelationalStorageEngine::SetSchema(const RelationalSchemaObject &schema) @@ -192,9 +192,8 @@ int SaveSyncTableTypeAndDropFlagToMeta(SQLiteSingleVerRelationalStorageExecutor errCode = handle->DeleteMetaData({ key }); if (errCode != E_OK) { LOGE("Save table drop flag to meta table failed. %d", errCode); - return errCode; } - return handle->InitCursorToMeta(tableName); + return errCode; } } @@ -309,14 +308,19 @@ int SQLiteSingleRelationalStorageEngine::CreateDistributedTable(SQLiteSingleVerR auto mode = static_cast(properties_.GetIntProp( RelationalDBProperties::DISTRIBUTED_TABLE_MODE, DistributedTableMode::SPLIT_BY_DEVICE)); TableSyncType tableSyncType = table.GetTableSyncType(); - int errCode = handle->CreateDistributedTable(mode, isUpgraded, identity, table, tableSyncType); + std::string tableName = table.GetTableName(); + int errCode = handle->InitCursorToMeta(tableName); + if (errCode != E_OK) { + LOGE("init cursor to meta failed. %d", errCode); + return errCode; + } + errCode = handle->CreateDistributedTable(mode, isUpgraded, identity, table, tableSyncType); if (errCode != E_OK) { LOGE("create distributed table failed. %d", errCode); return errCode; } schema.SetTableMode(mode); - std::string tableName = table.GetTableName(); // update table if tableName changed schema.RemoveRelationalTable(tableName); schema.AddRelationalTable(table); @@ -442,7 +446,7 @@ void SQLiteSingleRelationalStorageEngine::SetProperties(const RelationalDBProper int SQLiteSingleRelationalStorageEngine::CreateRelationalMetaTable(sqlite3 *db) { std::string sql = - "CREATE TABLE IF NOT EXISTS " + DBConstant::RELATIONAL_PREFIX + "metadata(" \ + "CREATE TABLE IF NOT EXISTS " + std::string(DBConstant::RELATIONAL_PREFIX) + "metadata(" \ "key BLOB PRIMARY KEY NOT NULL," \ "value BLOB);"; int errCode = SQLiteUtils::ExecuteRawSQL(db, sql); @@ -473,9 +477,9 @@ int SQLiteSingleRelationalStorageEngine::SetTrackerTable(const TrackerSchema &sc LOGW("tracker schema is no change."); return E_OK; } - bool isCheckData = tracker.GetTrackerTable(schema.tableName).GetTableName().empty() || schema.isForceUpgrade; + bool isFirstCreate = tracker.GetTrackerTable(schema.tableName).GetTableName().empty(); tracker.InsertTrackerSchema(schema); - int ret = handle->CreateTrackerTable(tracker.GetTrackerTable(schema.tableName), isCheckData); + int ret = handle->CreateTrackerTable(tracker.GetTrackerTable(schema.tableName), isFirstCreate); if (ret != E_OK && ret != -E_WITH_INVENTORY_DATA) { (void)handle->Rollback(); ReleaseExecutor(handle); @@ -531,7 +535,8 @@ int SQLiteSingleRelationalStorageEngine::CheckAndCacheTrackerSchema(const Tracke return errCode; } - if (schema.trackerColNames.empty()) { + if (!schema.isTrackAction && schema.trackerColNames.empty()) { + // if isTrackAction be false and trackerColNames is empty, will remove the tracker schema. tracker.RemoveTrackerSchema(schema); } @@ -600,16 +605,12 @@ int SQLiteSingleRelationalStorageEngine::ExecuteSql(const SqlCondition &conditio { int errCode = E_OK; auto *handle = static_cast(FindExecutor(!condition.readOnly, - OperatePerm::NORMAL_PERM, errCode)); + OperatePerm::NORMAL_PERM, errCode, true)); if (handle == nullptr) { return errCode; } errCode = handle->ExecuteSql(condition, records); - if (errCode != E_OK) { - ReleaseExecutor(handle); - return errCode; - } - ReleaseExecutor(handle); + ReleaseExecutor(handle, true); return errCode; } @@ -698,7 +699,14 @@ int SQLiteSingleRelationalStorageEngine::CleanTrackerData(const std::string &tab if (handle == nullptr) { // LCOV_EXCL_BR_LINE return errCode; } - errCode = handle->CleanTrackerData(tableName, cursor); + TrackerTable trackerTable = GetTrackerSchema().GetTrackerTable(tableName); + bool isOnlyTrackTable = false; + RelationalSchemaObject schema = GetSchema(); + if (!trackerTable.IsTableNameEmpty() && + !DBCommon::CaseInsensitiveCompare(schema.GetTable(tableName).GetTableName(), tableName)) { + isOnlyTrackTable = true; + } + errCode = handle->CleanTrackerData(tableName, cursor, isOnlyTrackTable); ReleaseExecutor(handle); return errCode; } diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.h b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.h index e1e32df7..9647b6a5 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.h @@ -66,7 +66,7 @@ protected: int CreateNewExecutor(bool isWrite, StorageExecutor *&handle) override; private: // For executor. - int ReleaseExecutor(SQLiteSingleVerRelationalStorageExecutor *&handle); + void ReleaseExecutor(SQLiteSingleVerRelationalStorageExecutor *&handle, bool isExternal = false); // For db. int RegisterFunction(sqlite3 *db) const; 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 27e5d1c4..263b3ec9 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 @@ -208,6 +208,60 @@ int SQLiteSingleVerRelationalStorageExecutor::GeneLogInfoForExistedData(sqlite3 return errCode; } +int SQLiteSingleVerRelationalStorageExecutor::ResetLogStatus(std::string &tableName) +{ + int errCode = SetLogTriggerStatus(false); + if (errCode != E_OK) { + LOGE("Fail to set log trigger on when reset log status, %d", errCode); + return errCode; + } + std::string logTable = DBConstant::RELATIONAL_PREFIX + tableName + "_log"; + std::string sql = "UPDATE " + logTable + " SET status = 0;"; + errCode = SQLiteUtils::ExecuteRawSQL(dbHandle_, sql); + if (errCode != E_OK) { + LOGE("Failed to initialize cloud type log data.%d", errCode); + } + return errCode; +} + +int SQLiteSingleVerRelationalStorageExecutor::CreateRelationalLogTable(DistributedTableMode mode, bool isUpgraded, + const std::string &identity, TableInfo &table, TableSyncType syncType) +{ + // create log table + auto tableManager = LogTableManagerFactory::GetTableManager(mode, syncType); + if (tableManager == nullptr) { + LOGE("[CreateRelationalLogTable] get table manager failed"); + return -E_INVALID_DB; + } + int errCode = tableManager->CreateRelationalLogTable(dbHandle_, table); + if (errCode != E_OK) { + LOGE("[CreateDistributedTable] create log table failed"); + return errCode; + } + + std::string tableName = table.GetTableName(); + if ((!isUpgraded) && table.GetTrackerTable().GetTableName().empty()) { + std::string calPrimaryKeyHash = tableManager->CalcPrimaryKeyHash("a.", table, identity); + errCode = GeneLogInfoForExistedData(dbHandle_, tableName, calPrimaryKeyHash, table); + if (errCode != E_OK) { + return errCode; + } + } else if (!isUpgraded) { + errCode = ResetLogStatus(tableName); + if (errCode != E_OK) { + return errCode; + } + } + + // add trigger + errCode = tableManager->AddRelationalLogTableTrigger(dbHandle_, table, identity); + if (errCode != E_OK) { + LOGE("[CreateDistributedTable] Add relational log table trigger failed."); + return errCode; + } + return SetLogTriggerStatus(true); +} + int SQLiteSingleVerRelationalStorageExecutor::CreateDistributedTable(DistributedTableMode mode, bool isUpgraded, const std::string &identity, TableInfo &table, TableSyncType syncType) { @@ -242,29 +296,7 @@ int SQLiteSingleVerRelationalStorageExecutor::CreateDistributedTable(Distributed return errCode; } - // create log table - auto tableManager = LogTableManagerFactory::GetTableManager(mode, syncType); - errCode = tableManager->CreateRelationalLogTable(dbHandle_, table); - if (errCode != E_OK) { - LOGE("[CreateDistributedTable] create log table failed"); - return errCode; - } - - if (!isUpgraded) { - std::string calPrimaryKeyHash = tableManager->CalcPrimaryKeyHash("a.", table, identity); - errCode = GeneLogInfoForExistedData(dbHandle_, tableName, calPrimaryKeyHash, table); - if (errCode != E_OK) { - return errCode; - } - } - - // add trigger - errCode = tableManager->AddRelationalLogTableTrigger(dbHandle_, table, identity); - if (errCode != E_OK) { - LOGE("[CreateDistributedTable] Add relational log table trigger failed."); - return errCode; - } - return SetLogTriggerStatus(true); + return CreateRelationalLogTable(mode, isUpgraded, identity, table, syncType); } int SQLiteSingleVerRelationalStorageExecutor::UpgradeDistributedTable(const std::string &tableName, @@ -650,7 +682,7 @@ static size_t GetDataItemSerialSize(DataItem &item, size_t appendLen) int SQLiteSingleVerRelationalStorageExecutor::GetKvData(const Key &key, Value &value) const { - static const std::string SELECT_META_VALUE_SQL = "SELECT value FROM " + DBConstant::RELATIONAL_PREFIX + + static const std::string SELECT_META_VALUE_SQL = "SELECT value FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + "metadata WHERE key=?;"; sqlite3_stmt *statement = nullptr; int errCode = SQLiteUtils::GetStatement(dbHandle_, SELECT_META_VALUE_SQL, statement); @@ -679,7 +711,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetKvData(const Key &key, Value &v int SQLiteSingleVerRelationalStorageExecutor::PutKvData(const Key &key, const Value &value) const { - static const std::string INSERT_META_SQL = "INSERT OR REPLACE INTO " + DBConstant::RELATIONAL_PREFIX + + static const std::string INSERT_META_SQL = "INSERT OR REPLACE INTO " + std::string(DBConstant::RELATIONAL_PREFIX) + "metadata VALUES(?,?);"; sqlite3_stmt *statement = nullptr; int errCode = SQLiteUtils::GetStatement(dbHandle_, INSERT_META_SQL, statement); @@ -709,7 +741,7 @@ ERROR: int SQLiteSingleVerRelationalStorageExecutor::DeleteMetaData(const std::vector &keys) const { - static const std::string REMOVE_META_VALUE_SQL = "DELETE FROM " + DBConstant::RELATIONAL_PREFIX + + static const std::string REMOVE_META_VALUE_SQL = "DELETE FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + "metadata WHERE key=?;"; sqlite3_stmt *statement = nullptr; int errCode = SQLiteUtils::GetStatement(dbHandle_, REMOVE_META_VALUE_SQL, statement); @@ -736,8 +768,8 @@ int SQLiteSingleVerRelationalStorageExecutor::DeleteMetaData(const std::vector=? AND key<=?;"; + static const std::string REMOVE_META_VALUE_BY_KEY_PREFIX_SQL = "DELETE FROM " + + std::string(DBConstant::RELATIONAL_PREFIX) + "metadata WHERE key>=? AND key<=?;"; sqlite3_stmt *statement = nullptr; int errCode = SQLiteUtils::GetStatement(dbHandle_, REMOVE_META_VALUE_BY_KEY_PREFIX_SQL, statement); if (errCode != E_OK) { @@ -757,7 +789,8 @@ int SQLiteSingleVerRelationalStorageExecutor::DeleteMetaDataByPrefixKey(const Ke int SQLiteSingleVerRelationalStorageExecutor::GetAllMetaKeys(std::vector &keys) const { - static const std::string SELECT_ALL_META_KEYS = "SELECT key FROM " + DBConstant::RELATIONAL_PREFIX + "metadata;"; + static const std::string SELECT_ALL_META_KEYS = "SELECT key FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + + "metadata;"; sqlite3_stmt *statement = nullptr; int errCode = SQLiteUtils::GetStatement(dbHandle_, SELECT_ALL_META_KEYS, statement); if (errCode != E_OK) { @@ -1241,7 +1274,7 @@ int SQLiteSingleVerRelationalStorageExecutor::DeleteDistributedDeviceTable(const int SQLiteSingleVerRelationalStorageExecutor::DeleteDistributedAllDeviceTableLog(const std::string &tableName) { std::string deleteLogSql = - "DELETE FROM " + DBConstant::RELATIONAL_PREFIX + tableName + + "DELETE FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName + "_log WHERE flag&0x02=0 AND (cloud_gid = '' OR cloud_gid IS NULL)"; return SQLiteUtils::ExecuteRawSQL(dbHandle_, deleteLogSql); } @@ -1249,7 +1282,8 @@ int SQLiteSingleVerRelationalStorageExecutor::DeleteDistributedAllDeviceTableLog int SQLiteSingleVerRelationalStorageExecutor::DeleteDistributedDeviceTableLog(const std::string &device, const std::string &tableName) { - std::string deleteLogSql = "DELETE FROM " + DBConstant::RELATIONAL_PREFIX + tableName + "_log WHERE device = ?"; + std::string deleteLogSql = "DELETE FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName + + "_log WHERE device = ?"; sqlite3_stmt *deleteLogStmt = nullptr; int errCode = SQLiteUtils::GetStatement(dbHandle_, deleteLogSql, deleteLogStmt); if (errCode != E_OK) { @@ -1466,7 +1500,8 @@ int SQLiteSingleVerRelationalStorageExecutor::GetMaxTimestamp(const std::vector< { maxTimestamp = 0; for (const auto &tableName : tableNames) { - const std::string sql = "SELECT MAX(timestamp) FROM " + DBConstant::RELATIONAL_PREFIX + tableName + "_log;"; + const std::string sql = "SELECT MAX(timestamp) FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName + + "_log;"; sqlite3_stmt *stmt = nullptr; int errCode = SQLiteUtils::GetStatement(dbHandle_, sql, stmt); if (errCode != E_OK) { @@ -1490,7 +1525,7 @@ int SQLiteSingleVerRelationalStorageExecutor::SetLogTriggerStatus(bool status) { const std::string key = "log_trigger_switch"; std::string val = status ? "true" : "false"; - std::string sql = "INSERT OR REPLACE INTO " + DBConstant::RELATIONAL_PREFIX + "metadata" + + std::string sql = "INSERT OR REPLACE INTO " + std::string(DBConstant::RELATIONAL_PREFIX) + "metadata" + " VALUES ('" + key + "', '" + val + "')"; int errCode = SQLiteUtils::ExecuteRawSQL(dbHandle_, sql); if (errCode != E_OK) { 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 2374572a..551c96b4 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 @@ -57,6 +57,11 @@ public: // Delete the copy and assign constructors DISABLE_COPY_ASSIGN_MOVE(SQLiteSingleVerRelationalStorageExecutor); + int ResetLogStatus(std::string &tableName); + + int CreateRelationalLogTable(DistributedTableMode mode, bool isUpgraded, const std::string &identity, + TableInfo &table, TableSyncType syncType); + // The parameter "identity" is a hash string that identifies a device int CreateDistributedTable(DistributedTableMode mode, bool isUpgraded, const std::string &identity, TableInfo &table, TableSyncType syncType); @@ -157,7 +162,7 @@ public: int CreateTempSyncTrigger(const TrackerTable &trackerTable, bool flag); int GetAndResetServerObserverData(const std::string &tableName, ChangeProperties &changeProperties); int ClearAllTempSyncTrigger(); - int CleanTrackerData(const std::string &tableName, int64_t cursor); + int CleanTrackerData(const std::string &tableName, int64_t cursor, bool isOnlyTrackTable); int CreateSharedTable(const TableSchema &schema); int DeleteTable(const std::vector &tableNames); int UpdateSharedTable(const std::map> &updateTableNames); @@ -441,10 +446,11 @@ private: int UpdateAssetsIdForOneRecord(const TableSchema &tableSchema, const std::string &sql, const std::vector &assetOfOneRecord, const std::vector &assetsOfOneRecord); - bool IsNeedUpdateAssetId(const TableSchema &tableSchema, int64_t dataKey, const VBucket &vBucket); + bool IsNeedUpdateAssetId(const TableSchema &tableSchema, int64_t dataKey, const VBucket &vBucket, + bool &isNotIncCursor); bool IsNeedUpdateAssetIdInner(sqlite3_stmt *selectStmt, const VBucket &vBucket, const Field &field, - VBucket &assetInfo); + VBucket &assetInfo, bool &isNotIncCursor); int UpdateAssetId(const TableSchema &tableSchema, int64_t dataKey, const VBucket &vBucket); 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 ba6e5fd5..2b48b933 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 @@ -237,7 +237,8 @@ int SQLiteSingleVerRelationalStorageExecutor::GetQueryLogSql(const std::string & return -E_CLOUD_ERROR; } std::string sql = "SELECT data_key, device, ori_device, timestamp, wtimestamp, flag, hash_key, cloud_gid," - " sharing_resource, status, version FROM " + DBConstant::RELATIONAL_PREFIX + tableName + "_log WHERE "; + " sharing_resource, status, version FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName + + "_log WHERE "; if (!cloudGid.empty()) { sql += "cloud_gid = ? OR "; } @@ -389,7 +390,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetCursor(const std::string &table int SQLiteSingleVerRelationalStorageExecutor::SetCursor(const std::string &tableName, uint64_t cursor) { - std::string sql = "UPDATE " + DBConstant::RELATIONAL_PREFIX + "metadata SET VALUE = ? where KEY = ?;"; + std::string sql = "UPDATE " + std::string(DBConstant::RELATIONAL_PREFIX) + "metadata SET VALUE = ? where KEY = ?;"; sqlite3_stmt *stmt = nullptr; int errCode = SQLiteUtils::GetStatement(dbHandle_, sql, stmt); if (errCode != E_OK) { @@ -566,7 +567,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetCloudAssets(const std::string & int SQLiteSingleVerRelationalStorageExecutor::SetCursorIncFlag(bool flag) { - std::string sql = "INSERT OR REPLACE INTO " + DBConstant::RELATIONAL_PREFIX + "metadata" + + std::string sql = "INSERT OR REPLACE INTO " + std::string(DBConstant::RELATIONAL_PREFIX) + "metadata" + " VALUES ('cursor_inc_flag', "; if (flag) { sql += "'true'"; @@ -1249,7 +1250,7 @@ int SQLiteSingleVerRelationalStorageExecutor::ReviseLocalModTime(const std::stri } bool SQLiteSingleVerRelationalStorageExecutor::IsNeedUpdateAssetIdInner(sqlite3_stmt *selectStmt, - const VBucket &vBucket, const Field &field, VBucket &assetInfo) + const VBucket &vBucket, const Field &field, VBucket &assetInfo, bool &isNotIncCursor) { if (field.type == TYPE_INDEX) { Asset asset; @@ -1258,8 +1259,12 @@ bool SQLiteSingleVerRelationalStorageExecutor::IsNeedUpdateAssetIdInner(sqlite3_ if (assetDBPtr == nullptr) { return true; } - Asset &assetDB = *assetDBPtr; - if (assetDB.assetId != asset.assetId || asset.status != AssetStatus::NORMAL) { + const Asset &assetDB = *assetDBPtr; + if (assetDB.assetId != asset.assetId) { + return true; + } + if (asset.status != AssetStatus::NORMAL) { + isNotIncCursor = true; return true; } } @@ -1275,7 +1280,11 @@ bool SQLiteSingleVerRelationalStorageExecutor::IsNeedUpdateAssetIdInner(sqlite3_ return true; } for (uint32_t i = 0; i < assets.size(); ++i) { - if (assets[i].assetId != assetsDB[i].assetId || assets[i].status != AssetStatus::NORMAL) { + if (assets[i].assetId != assetsDB[i].assetId) { + return true; + } + if (assets[i].status != AssetStatus::NORMAL) { + isNotIncCursor = true; return true; } } @@ -1284,7 +1293,7 @@ bool SQLiteSingleVerRelationalStorageExecutor::IsNeedUpdateAssetIdInner(sqlite3_ } bool SQLiteSingleVerRelationalStorageExecutor::IsNeedUpdateAssetId(const TableSchema &tableSchema, int64_t dataKey, - const VBucket &vBucket) + const VBucket &vBucket, bool &isNotIncCursor) { std::vector assetFields; for (const auto &field : tableSchema.fields) { @@ -1324,12 +1333,9 @@ bool SQLiteSingleVerRelationalStorageExecutor::IsNeedUpdateAssetId(const TableSc if (errCode != E_OK) { return true; } - for (const auto &field : assetFields) { - if (IsNeedUpdateAssetIdInner(selectStmt, vBucket, field, assetInfo)) { - return true; - } - } - return false; + return std::any_of(assetFields.begin(), assetFields.end(), [&](const Field &field) { + return IsNeedUpdateAssetIdInner(selectStmt, vBucket, field, assetInfo, isNotIncCursor); + }); } int SQLiteSingleVerRelationalStorageExecutor::MarkFlagAsConsistent(const std::string &tableName, 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 c6715ae4..a8d1137a 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 @@ -154,7 +154,7 @@ int SQLiteSingleVerRelationalStorageExecutor::IncreaseCursorOnAssetData(const st return errCode; } cursor++; - std::string sql = "UPDATE " + DBConstant::RELATIONAL_PREFIX + tableName + "_log"; + std::string sql = "UPDATE " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName + "_log"; sql += " SET cursor = ? where cloud_gid = ?;"; sqlite3_stmt *statement = nullptr; errCode = SQLiteUtils::GetStatement(dbHandle_, sql, statement); @@ -582,10 +582,16 @@ int SQLiteSingleVerRelationalStorageExecutor::ClearAllTempSyncTrigger() return errCode == -E_FINISHED ? (ret == E_OK ? E_OK : ret) : errCode; } -int SQLiteSingleVerRelationalStorageExecutor::CleanTrackerData(const std::string &tableName, int64_t cursor) +int SQLiteSingleVerRelationalStorageExecutor::CleanTrackerData(const std::string &tableName, int64_t cursor, + bool isOnlyTrackTable) { - std::string sql = "UPDATE " + DBConstant::RELATIONAL_PREFIX + tableName + "_log"; - sql += " SET extend_field = NULL where data_key = -1 and cursor <= ?;"; + std::string sql; + if (isOnlyTrackTable) { + sql = "DELETE FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName + "_log"; + } else { + sql = "UPDATE " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName + "_log SET extend_field = NULL"; + } + sql += " where data_key = -1 and cursor <= ?;"; sqlite3_stmt *statement = nullptr; int errCode = SQLiteUtils::GetStatement(dbHandle_, sql, statement); if (errCode != E_OK) { // LCOV_EXCL_BR_LINE @@ -774,7 +780,7 @@ int SQLiteSingleVerRelationalStorageExecutor::CleanShareTable(const std::string return errCode; } statement = nullptr; - std::string delLogSql = "DELETE FROM '" + DBConstant::RELATIONAL_PREFIX + tableName + "_log';"; + std::string delLogSql = "DELETE FROM '" + std::string(DBConstant::RELATIONAL_PREFIX) + tableName + "_log';"; errCode = SQLiteUtils::GetStatement(dbHandle_, delLogSql, statement); if (errCode != E_OK) { LOGE("get clean shared log stmt failed %d.", errCode); @@ -1044,7 +1050,7 @@ int SQLiteSingleVerRelationalStorageExecutor::GetCloudDeleteSql(const std::strin if (errCode == E_OK) { sql += ", cursor = " + std::to_string(cursor + 1) + " "; } else { - LOGE("[RDBExecutor] Increase cursor failed when delete log: %d", errCode); + LOGE("[RDBExecutor] Increase cursor failed when delete log: %d.", errCode); return errCode; } } @@ -1511,13 +1517,26 @@ int SQLiteSingleVerRelationalStorageExecutor::OnlyUpdateAssetId(const std::strin // this is shared table, not need to update asset id. return E_OK; } - if (!IsNeedUpdateAssetId(tableSchema, dataKey, vBucket)) { + bool isNotIncCursor = false; // if isNotIncCursor is false, will increase cursor + if (!IsNeedUpdateAssetId(tableSchema, dataKey, vBucket, isNotIncCursor)) { return E_OK; } + int error = SetCursorIncFlag(!isNotIncCursor); + if (error != E_OK) { + LOGE("[Storage Executor] failed to set cursor_inc_flag, %d.", error); + return error; + } int errCode = UpdateAssetId(tableSchema, dataKey, vBucket); if (errCode != E_OK) { LOGE("[Storage Executor] failed to update assetId on table, %d.", errCode); } + if (isNotIncCursor) { + error = SetCursorIncFlag(true); + if (error != E_OK) { + LOGE("[Storage Executor] failed to set cursor_inc_flag true, %d.", error); + return error; + } + } return errCode; } 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 acac0f44..e854890e 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 @@ -105,11 +105,11 @@ void SqliteLogTableManager::GetIndexSql(const TableInfo &table, std::vector= SecurityLabel::S2) ? - SecurityLabel::S2 : secOption.securityLabel); - errCode = SetPathSecOptWithCheck(metaDbPath, metaSecOpt, DBConstant::SINGLE_VER_META_STORE, false); - if (errCode != E_OK) { - LOGE("[SQLiteSingleVerDatabaseUpgrader] metaDb SetSecurityOption failed."); - return errCode; - } + std::string mainDbPath = path + "/" + DBConstant::MAINDB_DIR; + std::string cacheDbPath = path + "/" + DBConstant::CACHEDB_DIR; + std::string metaDbPath = path + "/" + DBConstant::METADB_DIR; + errCode = SetPathSecOptWithCheck(mainDbPath, secOption, DBConstant::SINGLE_VER_DATA_STORE, isWithChecked); + if (errCode != E_OK) { + return errCode; + } + errCode = SetPathSecOptWithCheck(cacheDbPath, secOption, DBConstant::SINGLE_VER_CACHE_STORE, isWithChecked); + if (errCode != E_OK) { + LOGE("[SQLiteSingleVerDatabaseUpgrader] cacheDb SetSecurityOption failed."); + return errCode; + } + SecurityOption metaSecOpt; + metaSecOpt.securityLabel = ((secOption.securityLabel >= SecurityLabel::S2) ? + SecurityLabel::S2 : secOption.securityLabel); + errCode = SetPathSecOptWithCheck(metaDbPath, metaSecOpt, DBConstant::SINGLE_VER_META_STORE, false); + if (errCode != E_OK) { + LOGE("[SQLiteSingleVerDatabaseUpgrader] metaDb SetSecurityOption failed."); + return errCode; } if (OS::CheckPathExistence(secOptUpgradeFile) && (OS::RemoveFile(secOptUpgradeFile) != E_OK)) { return -E_SYSTEM_API_FAIL; diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_database_upgrader.h b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_database_upgrader.h index e929839a..d963cae8 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_database_upgrader.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_database_upgrader.h @@ -34,7 +34,8 @@ public: void SetSubdir(const std::string &subDir); static int SetPathSecOptWithCheck(const std::string &path, const SecurityOption &secOption, const std::string &dbStore, bool isWithChecked = false); - static int SetSecOption(const std::string &path, const SecurityOption &secOption, bool isWithChecked); + static int SetSecOption(const std::string &path, const SecurityOption &secOption, SecurityOption existedSecOpt, + bool isWithChecked); bool IsValueNeedUpgrade() const override; protected: 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 73985539..e10b01f8 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 @@ -1011,23 +1011,68 @@ int SQLiteSingleVerNaturalStore::RemoveDeviceData(const std::string &deviceName, if (!hash) { // LCOV_EXCL_BR_LINE hashDeviceId = DBCommon::TransferHashString(deviceName); } - - return RemoveDeviceDataInner(hashDeviceId, isNeedNotify); + auto removeFunc = RemoveDeviceDataInner(hashDeviceId, isNeedNotify); + int errCode = E_OK; + auto syncer = GetAndIncCloudSyncer(); + if (syncer == nullptr) { + errCode = removeFunc(); + } else { + errCode = syncer->CleanKvCloudData(removeFunc); + DecObjRef(syncer); + } + if (errCode != E_OK) { + LOGE("[SingleVerNStore] CleanKvCloudData with notify failed:%d", errCode); + } + return errCode; } // In sync procedure, call this function int SQLiteSingleVerNaturalStore::RemoveDeviceData(const std::string &deviceName, ClearMode mode) { + auto removeFunc = RemoveDeviceDataInner(DBCommon::TransferHashString(deviceName), mode); + int errCode = E_OK; + auto syncer = GetAndIncCloudSyncer(); + if (syncer == nullptr) { + errCode = removeFunc(); + } else { + errCode = syncer->CleanKvCloudData(removeFunc); + DecObjRef(syncer); + } + if (errCode != E_OK) { + LOGE("[SingleVerNStore] CleanKvCloudData with mode [%d] failed:%d", mode, errCode); + return errCode; + } CleanAllWaterMark(); - return RemoveDeviceDataInner(DBCommon::TransferHashString(deviceName), mode); + errCode = EraseAllDeviceWaterMark(DBCommon::TransferHashString(deviceName)); + if (errCode != E_OK) { + LOGE("[SingleVerNStore] Erase all device water mark failed %d with mode [%d]", errCode, mode); + } + return errCode; } // In sync procedure, call this function int SQLiteSingleVerNaturalStore::RemoveDeviceData(const std::string &deviceName, const std::string &user, ClearMode mode) { + auto removeFunc = RemoveDeviceDataInner(DBCommon::TransferHashString(deviceName), user, mode); + int errCode = E_OK; + auto syncer = GetAndIncCloudSyncer(); + if (syncer == nullptr) { + errCode = removeFunc(); + } else { + errCode = syncer->CleanKvCloudData(removeFunc); + DecObjRef(syncer); + } + if (errCode != E_OK) { + LOGE("[SingleVerNStore] CleanKvCloudData with user and mode [%d] failed:%d", mode, errCode); + return errCode; + } CleanAllWaterMark(); - return RemoveDeviceDataInner(DBCommon::TransferHashString(deviceName), user, mode); + errCode = EraseAllDeviceWaterMark(DBCommon::TransferHashString(deviceName)); + if (errCode != E_OK) { + LOGE("[SingleVerNStore] Erase all device water mark failed %d with user and mode [%d]", errCode, mode); + } + return errCode; } int SQLiteSingleVerNaturalStore::RemoveDeviceDataInCacheMode(const std::string &hashDev, bool isNeedNotify) const @@ -1385,13 +1430,17 @@ uint64_t SQLiteSingleVerNaturalStore::GetTimestampFromDB() } uint64_t currentSysTime = TimeHelper::GetSysCurrentTime(); if (localTimeOffset < 0 && currentSysTime >= static_cast(std::abs(localTimeOffset))) { - return currentSysTime - static_cast(std::abs(localTimeOffset)); + currentSysTime -= static_cast(std::abs(localTimeOffset)); } else if (localTimeOffset >= 0 && (UINT64_MAX - currentSysTime >= static_cast(localTimeOffset))) { - return currentSysTime + static_cast(localTimeOffset); + currentSysTime += static_cast(localTimeOffset); } else { LOGW("[GetTimestampFromDB] localTimeOffset plus currentSysTime overflow"); - return currentSysTime; } + if (currentSysTime <= lastLocalSysTime_) { + currentSysTime = lastLocalSysTime_ + 1; + } + lastLocalSysTime_ = currentSysTime; + return currentSysTime; } Timestamp SQLiteSingleVerNaturalStore::GetCurrentTimestamp(bool needStartSync) 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 9c202175..15ebd342 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 @@ -308,11 +308,13 @@ private: int GetExistsDeviceList(std::set &devices) const; - int RemoveDeviceDataInner(const std::string &hashDev, bool isNeedNotify); + int EraseAllDeviceWaterMark(const std::string &hashDev); - int RemoveDeviceDataInner(const std::string &hashDev, ClearMode mode); + std::function RemoveDeviceDataInner(const std::string &hashDev, bool isNeedNotify); - int RemoveDeviceDataInner(const std::string &hashDev, const std::string &user, ClearMode mode); + std::function RemoveDeviceDataInner(const std::string &hashDev, ClearMode mode); + + std::function RemoveDeviceDataInner(const std::string &hashDev, const std::string &user, ClearMode mode); void GetAndResizeLocalIdentity(std::string &outTarget) const; @@ -344,6 +346,8 @@ private: mutable std::mutex cloudStoreMutex_; SqliteCloudKvStore *sqliteCloudKvStore_; + + Timestamp lastLocalSysTime_ = 0ULL; }; } // namespace DistributedDB #endif // SQLITE_SINGLE_VER_NATURAL_STORE_H 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 c140adf1..cf1374db 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 @@ -510,7 +510,7 @@ int SQLiteSingleVerNaturalStoreConnection::Export(const std::string &filePath, c } int SQLiteSingleVerNaturalStoreConnection::Import(const std::string &filePath, const CipherPassword &passwd, - bool isNeedIntegrityCheck) + [[gnu::unused]] bool isNeedIntegrityCheck) { if (IsFileAccessControlled()) { LOGE("Forbid Import when screen locked and security label [%d]!", kvDB_->GetMyProperties().GetSecLabel()); 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 5be85e44..208b67b1 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 @@ -458,21 +458,9 @@ int SQLiteSingleVerNaturalStore::IsSupportSubscribe() const return E_OK; } -int SQLiteSingleVerNaturalStore::RemoveDeviceDataInner(const std::string &hashDev, bool isNeedNotify) +int SQLiteSingleVerNaturalStore::EraseAllDeviceWaterMark(const std::string &hashDev) { int errCode = E_OK; - SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode); - if (handle == nullptr) { - LOGE("[SingleVerNStore] RemoveDeviceData get handle failed:%d", errCode); - return errCode; - } - uint64_t logFileSize = handle->GetLogFileSize(); - ReleaseHandle(handle); - if (logFileSize > GetMaxLogSize()) { - LOGW("[SingleVerNStore] RmDevData log size[%" PRIu64 "] over the limit", logFileSize); - return -E_LOG_OVER_LIMITS; - } - std::set removeDevices; if (hashDev.empty()) { errCode = GetExistsDeviceList(removeDevices); @@ -493,75 +481,104 @@ int SQLiteSingleVerNaturalStore::RemoveDeviceDataInner(const std::string &hashDe return errCode; } } - - CleanAllWaterMark(); - if (IsExtendedCacheDBMode()) { - errCode = RemoveDeviceDataInCacheMode(hashDev, isNeedNotify); - } else { - errCode = RemoveDeviceDataNormally(hashDev, isNeedNotify); - } - if (errCode != E_OK) { - LOGE("[SingleVerNStore] RemoveDeviceData failed:%d", errCode); - } - return errCode; } -int SQLiteSingleVerNaturalStore::RemoveDeviceDataInner(const std::string &hashDev, ClearMode mode) +std::function SQLiteSingleVerNaturalStore::RemoveDeviceDataInner(const std::string &hashDev, + bool isNeedNotify) { - int errCode = E_OK; - SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode); - if (handle == nullptr) { - LOGE("[SingleVerNStore] RemoveDeviceData with mode get handle failed:%d", errCode); - return errCode; - } - errCode = handle->StartTransaction(TransactType::IMMEDIATE); - if (errCode != E_OK) { - LOGE("Start transaction failed %d in RemoveDeviceData.", errCode); + return [this, hashDev, isNeedNotify]()->int { + int errCode = E_OK; + SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode); + if (handle == nullptr) { + LOGE("[SingleVerNStore] RemoveDeviceData get handle failed:%d", errCode); + return errCode; + } + uint64_t logFileSize = handle->GetLogFileSize(); ReleaseHandle(handle); - return errCode; - } - errCode = handle->RemoveDeviceData(hashDev, mode); - if (errCode != E_OK) { - LOGE("RemoveDeviceData failed: %d", errCode); - (void)handle->Rollback(); - } else { - errCode = handle->Commit(); + if (logFileSize > GetMaxLogSize()) { + LOGW("[SingleVerNStore] RmDevData log size[%" PRIu64 "] over the limit", logFileSize); + return -E_LOG_OVER_LIMITS; + } + + errCode = EraseAllDeviceWaterMark(hashDev); if (errCode != E_OK) { - LOGE("Transaction commit failed %d in RemoveDeviceData.", errCode); + LOGE("[SingleVerNStore] Erase all device water mark with notify failed: %d", errCode); + return errCode; } - } - ReleaseHandle(handle); - return errCode; + + CleanAllWaterMark(); + if (IsExtendedCacheDBMode()) { + errCode = RemoveDeviceDataInCacheMode(hashDev, isNeedNotify); + } else { + errCode = RemoveDeviceDataNormally(hashDev, isNeedNotify); + } + if (errCode != E_OK) { + LOGE("[SingleVerNStore] RemoveDeviceData failed:%d", errCode); + } + return errCode; + }; } -int SQLiteSingleVerNaturalStore::RemoveDeviceDataInner(const std::string &hashDev, const std::string &user, - ClearMode mode) +std::function SQLiteSingleVerNaturalStore::RemoveDeviceDataInner(const std::string &hashDev, ClearMode mode) { - int errCode = E_OK; - SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode); - if (handle == nullptr) { - LOGE("[SingleVerNStore] RemoveDeviceData with user and mode get handle failed:%d", errCode); - return errCode; - } - errCode = handle->StartTransaction(TransactType::IMMEDIATE); - if (errCode != E_OK) { - LOGE("Start transaction failed %d in RemoveDeviceData.", errCode); + return [this, hashDev, mode]()->int { + int errCode = E_OK; + SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode); + if (handle == nullptr) { + LOGE("[SingleVerNStore] RemoveDeviceData with mode get handle failed:%d", errCode); + return errCode; + } + errCode = handle->StartTransaction(TransactType::IMMEDIATE); + if (errCode != E_OK) { + LOGE("Start transaction failed %d in RemoveDeviceData.", errCode); + ReleaseHandle(handle); + return errCode; + } + errCode = handle->RemoveDeviceData(hashDev, mode); + if (errCode != E_OK) { + LOGE("RemoveDeviceData failed: %d", errCode); + (void)handle->Rollback(); + } else { + errCode = handle->Commit(); + if (errCode != E_OK) { + LOGE("Transaction commit failed %d in RemoveDeviceData.", errCode); + } + } ReleaseHandle(handle); return errCode; - } - errCode = handle->RemoveDeviceData(hashDev, user, mode); - if (errCode != E_OK) { - LOGE("RemoveDeviceData failed: %d", errCode); - (void)handle->Rollback(); - } else { - errCode = handle->Commit(); + }; +} + +std::function SQLiteSingleVerNaturalStore::RemoveDeviceDataInner(const std::string &hashDev, + const std::string &user, ClearMode mode) +{ + return [this, hashDev, user, mode]()->int { + int errCode = E_OK; + SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode); + if (handle == nullptr) { + LOGE("[SingleVerNStore] RemoveDeviceData with user and mode get handle failed:%d", errCode); + return errCode; + } + errCode = handle->StartTransaction(TransactType::IMMEDIATE); if (errCode != E_OK) { - LOGE("Transaction commit failed %d in RemoveDeviceData.", errCode); + LOGE("Start transaction failed %d in RemoveDeviceData.", errCode); + ReleaseHandle(handle); + return errCode; } - } - ReleaseHandle(handle); - return errCode; + errCode = handle->RemoveDeviceData(hashDev, user, mode); + if (errCode != E_OK) { + LOGE("RemoveDeviceData failed: %d", errCode); + (void)handle->Rollback(); + } else { + errCode = handle->Commit(); + if (errCode != E_OK) { + LOGE("Transaction commit failed %d in RemoveDeviceData.", errCode); + } + } + ReleaseHandle(handle); + return errCode; + }; } void SQLiteSingleVerNaturalStore::AbortHandle() 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 d1f7ede4..0cc51e10 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 @@ -774,13 +774,14 @@ int SQLiteSingleVerStorageEngine::PreCreateExecutor(bool isWrite, SecurityOption return E_OK; } -int SQLiteSingleVerStorageEngine::EndCreateExecutor(sqlite3 *db, bool isWrite, bool isDetachMeta) +int SQLiteSingleVerStorageEngine::EndCreateExecutor(sqlite3 *db, SecurityOption existedSecOpt, bool isWrite, + bool isDetachMeta) { if (option_.isMemDb || !isWrite) { return E_OK; } - int errCode = SQLiteSingleVerDatabaseUpgrader::SetSecOption(option_.subdir, option_.securityOpt, + int errCode = SQLiteSingleVerDatabaseUpgrader::SetSecOption(option_.subdir, option_.securityOpt, existedSecOpt, isNeedUpdateSecOpt_); if (errCode != E_OK) { if (errCode == -E_NOT_SUPPORT) { @@ -857,7 +858,7 @@ int SQLiteSingleVerStorageEngine::CreateNewExecutor(bool isWrite, StorageExecuto return errCode; } - errCode = EndCreateExecutor(dbHandle, isWrite, isDetachMeta); + errCode = EndCreateExecutor(dbHandle, existedSecOpt, isWrite, isDetachMeta); if (errCode != E_OK) { LOGE("After create executor, set security option incomplete!"); (void)sqlite3_close_v2(dbHandle); diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_engine.h b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_engine.h index ef7d66ef..763a56fb 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_engine.h +++ b/kv_store/frameworks/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_engine.h @@ -74,7 +74,7 @@ protected: private: // For executor. int PreCreateExecutor(bool isWrite, SecurityOption &existedSecOpt); - int EndCreateExecutor(sqlite3 *db, bool isWrite, bool isDetachMeta); + int EndCreateExecutor(sqlite3 *db, SecurityOption existedSecOpt, bool isWrite, bool isDetachMeta); int ReInit() override; int ReleaseExecutor(SQLiteSingleVerStorageExecutor *&handle); int ReleaseHandleTransiently(SQLiteSingleVerStorageExecutor *&handle, uint64_t idleTime, 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 e7a72908..a66a0f8c 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 @@ -643,7 +643,7 @@ int SQLiteUtils::CreateMetaDatabase(const std::string &metaDbPath) return errCode; } -int SQLiteUtils::CheckIntegrity(const std::string dbFile, CipherType type, const CipherPassword &passwd) +int SQLiteUtils::CheckIntegrity(const std::string &dbFile, CipherType type, const CipherPassword &passwd) { std::vector createTableSqls; OpenDbProperties option = {dbFile, true, false, createTableSqls, type, passwd}; @@ -1625,7 +1625,7 @@ int SQLiteUtils::GetRelationalSchema(sqlite3 *db, std::string &schema, const std } sqlite3_stmt *statement = nullptr; - std::string sql = "SELECT value FROM " + DBConstant::RELATIONAL_PREFIX + "metadata WHERE key=?;"; + std::string sql = "SELECT value FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + "metadata WHERE key=?;"; int errCode = GetStatement(db, sql, statement); if (errCode != E_OK) { return errCode; @@ -1666,7 +1666,7 @@ int SQLiteUtils::GetLogTableVersion(sqlite3 *db, std::string &version) } sqlite3_stmt *statement = nullptr; - std::string sql = "SELECT value FROM " + DBConstant::RELATIONAL_PREFIX + "metadata WHERE key=?;"; + std::string sql = "SELECT value FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + "metadata WHERE key=?;"; int errCode = GetStatement(db, sql, statement); if (errCode != E_OK) { return errCode; 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 6d4a6afa..9bfb2934 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 @@ -142,7 +142,7 @@ public: static int CreateMetaDatabase(const std::string &metaDbPath); - static int CheckIntegrity(const std::string dbFile, CipherType type, const CipherPassword &passwd); + static int CheckIntegrity(const std::string &dbFile, CipherType type, const CipherPassword &passwd); static int CheckIntegrity(sqlite3 *db, const std::string &sql); #ifdef RELATIONAL_STORE diff --git a/kv_store/frameworks/libs/distributeddb/storage/src/storage_engine.cpp b/kv_store/frameworks/libs/distributeddb/storage/src/storage_engine.cpp index baee1606..5e40a9d1 100644 --- a/kv_store/frameworks/libs/distributeddb/storage/src/storage_engine.cpp +++ b/kv_store/frameworks/libs/distributeddb/storage/src/storage_engine.cpp @@ -84,7 +84,7 @@ int StorageEngine::InitReadWriteExecutors() if (errCode != E_OK) { return errCode; } - AddStorageExecutor(handle); + AddStorageExecutor(handle, false); } for (uint32_t i = 0; i < engineAttr_.minReadNum; i++) { @@ -93,7 +93,7 @@ int StorageEngine::InitReadWriteExecutors() if (errCode != E_OK) { return errCode; } - AddStorageExecutor(handle); + AddStorageExecutor(handle, false); } return E_OK; } @@ -131,7 +131,8 @@ int StorageEngine::ReInit() return E_OK; } -StorageExecutor *StorageEngine::FindExecutor(bool writable, OperatePerm perm, int &errCode, int waitTime) +StorageExecutor *StorageEngine::FindExecutor(bool writable, OperatePerm perm, int &errCode, bool isExternal, + int waitTime) { if (GetEngineState() == EngineState::ENGINE_BUSY) { LOGI("Storage engine is busy!"); @@ -152,13 +153,13 @@ StorageExecutor *StorageEngine::FindExecutor(bool writable, OperatePerm perm, in } if (writable) { - return FindWriteExecutor(perm, errCode, waitTime); + return FindWriteExecutor(perm, errCode, waitTime, isExternal); } - return FindReadExecutor(perm, errCode, waitTime); + return FindReadExecutor(perm, errCode, waitTime, isExternal); } -StorageExecutor *StorageEngine::FindWriteExecutor(OperatePerm perm, int &errCode, int waitTime) +StorageExecutor *StorageEngine::FindWriteExecutor(OperatePerm perm, int &errCode, int waitTime, bool isExternal) { LOGD("[FindWriteExecutor]Finding WriteExecutor"); std::unique_lock lock(writeMutex_); @@ -167,18 +168,20 @@ StorageExecutor *StorageEngine::FindWriteExecutor(OperatePerm perm, int &errCode LOGI("Not permitted to get the executor[%u]", static_cast(perm_)); return nullptr; } + std::list &writeUsingList = isExternal ? externalWriteUsingList_ : writeUsingList_; + std::list &writeIdleList = isExternal ? externalWriteIdleList_ : writeIdleList_; if (waitTime <= 0) { // non-blocking. - if (writeIdleList_.empty() && - writeIdleList_.size() + writeUsingList_.size() == engineAttr_.maxWriteNum) { + if (writeUsingList.empty() && + writeIdleList.size() + writeUsingList.size() == engineAttr_.maxWriteNum) { return nullptr; } - return FetchStorageExecutor(true, writeIdleList_, writeUsingList_, errCode); + return FetchStorageExecutor(true, writeIdleList, writeUsingList, errCode, isExternal); } // Not prohibited and there is an available handle bool result = writeCondition_.wait_for(lock, std::chrono::seconds(waitTime), - [this, &perm]() { - return (perm_ == OperatePerm::NORMAL_PERM || perm_ == perm) && (!writeIdleList_.empty() || - (writeIdleList_.size() + writeUsingList_.size() < engineAttr_.maxWriteNum) || + [this, &perm, &writeUsingList, &writeIdleList]() { + return (perm_ == OperatePerm::NORMAL_PERM || perm_ == perm) && (!writeIdleList.empty() || + (writeIdleList.size() + writeUsingList.size() < engineAttr_.maxWriteNum) || operateAbort_); }); if (operateAbort_) { @@ -187,14 +190,14 @@ StorageExecutor *StorageEngine::FindWriteExecutor(OperatePerm perm, int &errCode } if (!result) { LOGI("Get write handle result[%d], permissType[%u], operType[%u], write[%zu-%zu-%" PRIu32 "]", result, - static_cast(perm_), static_cast(perm), writeIdleList_.size(), writeUsingList_.size(), + static_cast(perm_), static_cast(perm), writeIdleList.size(), writeUsingList.size(), engineAttr_.maxWriteNum); return nullptr; } - return FetchStorageExecutor(true, writeIdleList_, writeUsingList_, errCode); + return FetchStorageExecutor(true, writeIdleList, writeUsingList, errCode, isExternal); } -StorageExecutor *StorageEngine::FindReadExecutor(OperatePerm perm, int &errCode, int waitTime) +StorageExecutor *StorageEngine::FindReadExecutor(OperatePerm perm, int &errCode, int waitTime, bool isExternal) { std::unique_lock lock(readMutex_); errCode = -E_BUSY; @@ -203,19 +206,22 @@ StorageExecutor *StorageEngine::FindReadExecutor(OperatePerm perm, int &errCode, return nullptr; } + std::list &readUsingList = isExternal ? externalReadUsingList_ : readUsingList_; + std::list &readIdleList = isExternal ? externalReadIdleList_ : readIdleList_; if (waitTime <= 0) { // non-blocking. - if (readIdleList_.empty() && - readIdleList_.size() + readUsingList_.size() == engineAttr_.maxReadNum) { + if (readIdleList.empty() && + readIdleList.size() + readUsingList.size() == engineAttr_.maxReadNum) { return nullptr; } - return FetchStorageExecutor(false, readIdleList_, readUsingList_, errCode); + return FetchStorageExecutor(false, readIdleList, readUsingList, errCode, isExternal); } // Not prohibited and there is an available handle + uint32_t maxReadHandleNum = isExternal ? 1 : engineAttr_.maxReadNum; bool result = readCondition_.wait_for(lock, std::chrono::seconds(waitTime), - [this, &perm]() { + [this, &perm, &readUsingList, &readIdleList, &maxReadHandleNum]() { return (perm_ == OperatePerm::NORMAL_PERM || perm_ == perm) && - (!readIdleList_.empty() || (readIdleList_.size() + readUsingList_.size() < engineAttr_.maxReadNum) || + (!readIdleList.empty() || (readIdleList.size() + readUsingList.size() < maxReadHandleNum) || operateAbort_); }); if (operateAbort_) { @@ -224,14 +230,14 @@ StorageExecutor *StorageEngine::FindReadExecutor(OperatePerm perm, int &errCode, } if (!result) { LOGI("Get read handle result[%d], permissType[%u], operType[%u], read[%zu-%zu-%" PRIu32 "]", result, - static_cast(perm_), static_cast(perm), readIdleList_.size(), readUsingList_.size(), + static_cast(perm_), static_cast(perm), readIdleList.size(), readUsingList.size(), engineAttr_.maxReadNum); return nullptr; } - return FetchStorageExecutor(false, readIdleList_, readUsingList_, errCode); + return FetchStorageExecutor(false, readIdleList, readUsingList, errCode, isExternal); } -void StorageEngine::Recycle(StorageExecutor *&handle) +void StorageEngine::Recycle(StorageExecutor *&handle, bool isExternal) { if (handle == nullptr) { return; @@ -239,33 +245,37 @@ void StorageEngine::Recycle(StorageExecutor *&handle) if (!isEnhance_) { LOGD("Recycle executor[%d] for id[%.6s]", handle->GetWritable(), hashIdentifier_.c_str()); } + std::list &writeUsingList = isExternal ? externalWriteUsingList_ : writeUsingList_; + std::list &writeIdleList = isExternal ? externalWriteIdleList_ : writeIdleList_; + std::list &readUsingList = isExternal ? externalReadUsingList_ : readUsingList_; + std::list &readIdleList = isExternal ? externalReadIdleList_ : readIdleList_; if (handle->GetWritable()) { std::unique_lock lock(writeMutex_); - auto iter = std::find(writeUsingList_.begin(), writeUsingList_.end(), handle); - if (iter != writeUsingList_.end()) { - writeUsingList_.remove(handle); - if (writeIdleList_.size() >= 1) { + auto iter = std::find(writeUsingList.begin(), writeUsingList.end(), handle); + if (iter != writeUsingList.end()) { + writeUsingList.remove(handle); + if (!writeIdleList.empty()) { delete handle; handle = nullptr; return; } handle->Reset(); - writeIdleList_.push_back(handle); + writeIdleList.push_back(handle); writeCondition_.notify_one(); idleCondition_.notify_all(); } } else { std::unique_lock lock(readMutex_); - auto iter = std::find(readUsingList_.begin(), readUsingList_.end(), handle); - if (iter != readUsingList_.end()) { - readUsingList_.remove(handle); - if (readIdleList_.size() >= 1) { + auto iter = std::find(readUsingList.begin(), readUsingList.end(), handle); + if (iter != readUsingList.end()) { + readUsingList.remove(handle); + if (!readIdleList.empty()) { delete handle; handle = nullptr; return; } handle->Reset(); - readIdleList_.push_back(handle); + readIdleList.push_back(handle); readCondition_.notify_one(); } } @@ -306,7 +316,8 @@ int StorageEngine::TryToDisable(bool isNeedCheckAll, OperatePerm disableType) goto END; } - if (!writeUsingList_.empty() || !readUsingList_.empty()) { + if (!writeUsingList_.empty() || !readUsingList_.empty() || !externalWriteUsingList_.empty() || + !externalReadUsingList_.empty()) { LOGE("Database handle used"); return -E_BUSY; } @@ -399,46 +410,49 @@ int StorageEngine::CheckEngineOption(const KvDBProperties &kvdbOption) const return E_OK; } -void StorageEngine::AddStorageExecutor(StorageExecutor *handle) +void StorageEngine::AddStorageExecutor(StorageExecutor *handle, bool isExternal) { if (handle == nullptr) { return; } + std::list &writeIdleList = isExternal ? externalWriteIdleList_ : writeIdleList_; + std::list &readIdleList = isExternal ? externalReadIdleList_ : readIdleList_; if (handle->GetWritable()) { - writeIdleList_.push_back(handle); + writeIdleList.push_back(handle); } else { - readIdleList_.push_back(handle); + readIdleList.push_back(handle); } } +void ClearHandleList(std::list &handleList) +{ + for (auto &item : handleList) { + if (item != nullptr) { + delete item; + item = nullptr; + } + } + handleList.clear(); +} + void StorageEngine::CloseExecutor() { { std::lock_guard lock(writeMutex_); - for (auto &item : writeIdleList_) { - if (item != nullptr) { - delete item; - item = nullptr; - } - } - writeIdleList_.clear(); + ClearHandleList(writeIdleList_); + ClearHandleList(externalWriteIdleList_); } { std::lock_guard lock(readMutex_); - for (auto &item : readIdleList_) { - if (item != nullptr) { - delete item; - item = nullptr; - } - } - readIdleList_.clear(); + ClearHandleList(readIdleList_); + ClearHandleList(externalReadIdleList_); } } StorageExecutor *StorageEngine::FetchStorageExecutor(bool isWrite, std::list &idleList, - std::list &usingList, int &errCode) + std::list &usingList, int &errCode, bool isExternal) { if (idleList.empty()) { StorageExecutor *handle = nullptr; @@ -455,7 +469,7 @@ StorageExecutor *StorageEngine::FetchStorageExecutor(bool isWrite, std::list &idleList, - std::list &usingList, int &errCode); + std::list &usingList, int &errCode, bool isExternal = false); - StorageExecutor *FindWriteExecutor(OperatePerm perm, int &errCode, int waitTime); - StorageExecutor *FindReadExecutor(OperatePerm perm, int &errCode, int waitTime); + StorageExecutor *FindWriteExecutor(OperatePerm perm, int &errCode, int waitTime, bool isExternal = false); + StorageExecutor *FindReadExecutor(OperatePerm perm, int &errCode, int waitTime, bool isExternal = false); virtual void ClearCorruptedFlag(); @@ -157,6 +158,10 @@ private: std::list writeIdleList_; std::list readUsingList_; std::list readIdleList_; + std::list externalWriteUsingList_; + std::list externalWriteIdleList_; + std::list externalReadUsingList_; + std::list externalReadIdleList_; std::atomic isExistConnection_; std::mutex idleMutex_; 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 aaa8be06..36318036 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 @@ -718,45 +718,88 @@ void CloudDBProxy::SetPrepareTraceId(const std::string &traceId) const int CloudDBProxy::BatchDownload(const std::string &tableName, std::vector &downloadAssets) { - if (IsEmptyAssetRecord(downloadAssets)) { - return E_OK; - } - std::shared_lock readLock(assetLoaderMutex_); - if (iAssetLoader_ == nullptr) { - LOGE("[CloudDBProxy] Asset loader has not been set %d", -E_NOT_SET); - return -E_NOT_SET; - } - iAssetLoader_->BatchDownload(tableName, downloadAssets); - return E_OK; + return BatchOperateAssetsWithAllRecords(tableName, downloadAssets, CloudDBProxy::BATCH_DOWNLOAD); } int CloudDBProxy::BatchRemoveLocalAssets(const std::string &tableName, std::vector &removeAssets) { - if (IsEmptyAssetRecord(removeAssets)) { + return BatchOperateAssetsWithAllRecords(tableName, removeAssets, CloudDBProxy::BATCH_REMOVE_LOCAL); +} + +int CloudDBProxy::BatchOperateAssetsWithAllRecords(const std::string &tableName, + std::vector &allRecords, const InnerBatchOpType operationType) +{ + std::vector nonEmptyRecords; + auto indexes = GetNotEmptyAssetRecords(allRecords, nonEmptyRecords); + if (nonEmptyRecords.empty()) { return E_OK; } + + int errCode = BatchOperateAssetsInner(tableName, nonEmptyRecords, operationType); + + CopyAssetsBack(allRecords, indexes, nonEmptyRecords); + return errCode; +} + +int CloudDBProxy::BatchOperateAssetsInner(const std::string &tableName, + std::vector &necessaryRecords, const InnerBatchOpType operationType) +{ std::shared_lock readLock(assetLoaderMutex_); if (iAssetLoader_ == nullptr) { LOGE("[CloudDBProxy] Asset loader has not been set %d", -E_NOT_SET); return -E_NOT_SET; } - iAssetLoader_->BatchRemoveLocalAssets(tableName, removeAssets); + if (operationType == CloudDBProxy::BATCH_DOWNLOAD) { + iAssetLoader_->BatchDownload(tableName, necessaryRecords); + } else if (operationType == CloudDBProxy::BATCH_REMOVE_LOCAL) { + iAssetLoader_->BatchRemoveLocalAssets(tableName, necessaryRecords); + } else { + LOGE("[CloudDBProxy][BatchOperateAssetsInner] Internal error! Operation type is invalid: %d", operationType); + return -E_NOT_SET; + } return E_OK; } -bool CloudDBProxy::IsEmptyAssetRecord(const std::vector &assets) +std::vector CloudDBProxy::GetNotEmptyAssetRecords(std::vector &originalRecords, + std::vector &nonEmptyRecords) { - if (assets.empty()) { - return true; + std::vector indexes; + if (originalRecords.empty()) { + return indexes; } - for (const auto &record : assets) { + + int index = 0; + for (auto &record : originalRecords) { + bool isEmpty = true; for (const auto &recordAssets : record.assets) { if (!recordAssets.second.empty()) { - return false; + isEmpty = false; + break; } } + if (!isEmpty) { + indexes.push_back(index); + IAssetLoader::AssetRecord newRecord = { + record.gid, + record.prefix, + std::move(record.assets) + }; + nonEmptyRecords.emplace_back(newRecord); + } + index++; + } + return indexes; +} + +void CloudDBProxy::CopyAssetsBack(std::vector &originalRecords, + const std::vector indexes, std::vector &newRecords) +{ + int i = 0; + for (const auto index : indexes) { + originalRecords[index].status = newRecords[i].status; + originalRecords[index].assets = std::move(newRecords[i].assets); + i++; } - return true; } } 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 dd5fc1ef..f706c90e 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 @@ -156,6 +156,12 @@ protected: // add action code before INVALID_ACTION INVALID_ACTION }; + + enum InnerBatchOpType : uint8_t { + BATCH_DOWNLOAD = 0, + BATCH_REMOVE_LOCAL + }; + static int InnerAction(const std::shared_ptr &context, const std::shared_ptr &cloudDb, InnerActionCode action); @@ -174,7 +180,19 @@ protected: static DBStatus QueryAction(const std::shared_ptr &context, const std::shared_ptr &cloudDb); - static bool IsEmptyAssetRecord(const std::vector &assets); + int BatchOperateAssetsWithAllRecords(const std::string &tableName, + std::vector &allRecords, const InnerBatchOpType operationType); + + int BatchOperateAssetsInner(const std::string &tableName, + std::vector &necessaryRecords, const InnerBatchOpType operationType); + + // save record with assets in nonEmptyRecords, return the indexes of these records in the original vector + std::vector GetNotEmptyAssetRecords(std::vector &originalRecords, + std::vector &nonEmptyRecords); + + // copy newRecords's assets and status back to originalRecords, based on indexes + void CopyAssetsBack(std::vector &originalRecords, const std::vector indexes, + std::vector &newRecords); mutable std::shared_mutex cloudMutex_; mutable std::shared_mutex assetLoaderMutex_; 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 170429e2..c4fd7917 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 @@ -46,7 +46,7 @@ bool CloudSyncStrategy::JudgeUpload() return false; } -bool CloudSyncStrategy::JudgeKvScene() +bool CloudSyncStrategy::JudgeKvScene() const { return isKvScene_; } diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_strategy.h b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_strategy.h index df9dae1a..10db3373 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_strategy.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/cloud/cloud_sync_strategy.h @@ -38,7 +38,7 @@ public: virtual bool JudgeUpload(); - bool JudgeKvScene(); + bool JudgeKvScene() const; static bool IsDelete(const LogInfo &info); 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 d7b51387..82397022 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 @@ -421,6 +421,9 @@ int CloudSyncUtils::SaveChangedData(ICloudSyncer::SyncParam ¶m, size_t dataI param.info.retryInfo.downloadBatchOpCount++; return CloudSyncUtils::SaveChangedDataByType(param.downloadData.data[dataIndex], param.changedData, dataInfo.localInfo, ChangeType::OP_DELETE); + case OpType::UPDATE_TIMESTAMP: + param.info.retryInfo.downloadBatchOpCount++; + return E_OK; default: return E_OK; } 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 249e3f2a..bcd5d5d6 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 @@ -40,6 +40,7 @@ CloudSyncer::CloudSyncer( storageProxy_(std::move(storageProxy)), queuedManualSyncLimit_(DBConstant::QUEUED_SYNC_LIMIT_DEFAULT), closed_(false), + hasKvRemoveTask(false), timerId_(0u), isKvScene_(isKvScene), policy_(policy) @@ -81,6 +82,10 @@ int CloudSyncer::Sync(const CloudTaskInfo &taskInfo) LOGE("[CloudSyncer] DB is closed!"); return -E_DB_CLOSED; } + if (hasKvRemoveTask) { + LOGE("[CloudSyncer] has remove task, stop sync task!"); + return -E_CLOUD_ERROR; + } CloudTaskInfo info = taskInfo; info.status = ProcessStatus::PREPARED; errCode = TryToAddSyncTask(std::move(info)); @@ -133,29 +138,6 @@ void CloudSyncer::Close() storageProxy_->Close(); } -void CloudSyncer::StopAllTasks() -{ - CloudSyncer::TaskId currentTask; - { - std::lock_guard autoLock(dataLock_); - 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 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); - } -} - int CloudSyncer::TriggerSync() { if (closed_) { @@ -479,7 +461,7 @@ void CloudSyncer::DoFinished(TaskId taskId, int errCode) resumeTaskInfos_[taskId].context.locker = nullptr; ClearCurrentContextWithoutLock(); } - contextCv_.notify_one(); + contextCv_.notify_all(); return; } { @@ -974,11 +956,6 @@ int CloudSyncer::SaveDataInTransaction(CloudSyncer::TaskId taskId, SyncParam &pa LOGE("[CloudSyncer] Cannot start a transaction: %d.", ret); return ret; } - if (!IsModeForcePush(taskId)) { - param.changedData.tableName = param.info.tableName; - param.changedData.field = param.pkColNames; - param.changedData.type = ChangedDataType::DATA; - } uint64_t cursor = DBConstant::INVALID_CURSOR; std::string maskStoreId = DBCommon::StringMiddleMasking(GetStoreIdByTask(taskId)); std::string maskTableName = DBCommon::StringMiddleMasking(param.info.tableName); @@ -1484,6 +1461,9 @@ int CloudSyncer::CheckQueueSizeWithNoLock(bool priorityTask) int CloudSyncer::PrepareSync(TaskId taskId) { std::lock_guard autoLock(dataLock_); + if (hasKvRemoveTask) { + return -E_CLOUD_ERROR; + } if (closed_ || cloudTaskInfos_.find(taskId) == cloudTaskInfos_.end()) { LOGW("[CloudSyncer] Abort sync because syncer is closed"); return -E_DB_CLOSED; @@ -1895,7 +1875,7 @@ void CloudSyncer::ClearContextAndNotify(TaskId taskId, int errCode) ClearCurrentContextWithoutLock(); if (cloudTaskInfos_.find(taskId) == cloudTaskInfos_.end()) { // should not happen LOGW("[CloudSyncer] taskId %" PRIu64 " has been finished!", taskId); - contextCv_.notify_one(); + contextCv_.notify_all(); return; } info = std::move(cloudTaskInfos_[taskId]); @@ -1907,7 +1887,7 @@ void CloudSyncer::ClearContextAndNotify(TaskId taskId, int errCode) // if clear unlocking failed, no return to avoid affecting the entire process LOGW("[CloudSyncer] clear unlocking status failed! errCode = %d", err); } - contextCv_.notify_one(); + contextCv_.notify_all(); if (info.errCode == E_OK) { info.errCode = errCode; } @@ -1915,6 +1895,7 @@ void CloudSyncer::ClearContextAndNotify(TaskId taskId, int errCode) info.errCode); info.status = ProcessStatus::FINISHED; if (notifier != nullptr) { + notifier->UpdateAllTablesFinally(); notifier->NotifyProcess(info, {}, true); } // generate compensated sync @@ -1992,7 +1973,6 @@ int CloudSyncer::DownloadOneAssetRecord(const std::set &dupHashKeySet, cons changedAssets.primaryData[ChangeType::OP_UPDATE].push_back(downloadItem.primaryKeyValList); } } - return errorCode; } @@ -2030,16 +2010,25 @@ int CloudSyncer::GetSyncParamForDownload(TaskId taskId, SyncParam ¶m) currentContext_.assetFields[currentContext_.tableName] = assetFields; } param.isSinglePrimaryKey = CloudSyncUtils::IsSinglePrimaryKey(param.pkColNames); - if (!IsModeForcePull(taskId) && !(IsPriorityTask(taskId) && !IsQueryListEmpty(taskId))) { + if (!IsModeForcePull(taskId) && (!IsPriorityTask(taskId) || IsQueryListEmpty(taskId))) { ret = storageProxy_->GetCloudWaterMark(param.tableName, param.cloudWaterMark); if (ret != E_OK) { LOGE("[CloudSyncer] Cannot get cloud water level from cloud meta data: %d.", ret); } + if (!IsCurrentTaskResume(taskId)) { + ReloadCloudWaterMarkIfNeed(param.tableName, param.cloudWaterMark); + } } currentContext_.notifier->GetDownloadInfoByTableName(param.info); return ret; } +bool CloudSyncer::IsCurrentTaskResume(TaskId taskId) +{ + std::lock_guard autoLock(dataLock_); + return cloudTaskInfos_[taskId].resume; +} + bool CloudSyncer::IsCurrentTableResume(TaskId taskId, bool upload) { std::lock_guard autoLock(dataLock_); @@ -2125,7 +2114,7 @@ CloudSyncer::InnerProcessInfo CloudSyncer::GetInnerProcessInfo(const std::string InnerProcessInfo info; info.tableName = tableName; info.tableStatus = ProcessStatus::PROCESSING; - ReloadUploadInfoIfNeed(uploadParam.taskId, uploadParam, info); + ReloadUploadInfoIfNeed(uploadParam, info); return info; } 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 bc2cfd56..c37540fd 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 @@ -58,13 +58,15 @@ public: int CleanCloudData(ClearMode mode, const std::vector &tableNameList, const RelationalSchemaObject &localSchema); + int CleanKvCloudData(std::function &removeFunc); + int CleanWaterMarkInMemory(const std::set &tableNameList); int32_t GetCloudSyncTaskCount(); void Close(); - void StopAllTasks(); + void StopAllTasks(int errCode = -E_USER_CHANGE); std::string GetIdentify() const override; @@ -323,6 +325,8 @@ protected: int GetSyncParamForDownload(TaskId taskId, SyncParam ¶m); + bool IsCurrentTaskResume(TaskId taskId); + bool IsCurrentTableResume(TaskId taskId, bool upload); int DownloadDataFromCloud(TaskId taskId, SyncParam ¶m, bool &abort, bool isFirstDownload); @@ -341,7 +345,7 @@ protected: void ReloadCloudWaterMarkIfNeed(const std::string &tableName, std::string &cloudWaterMark); - void ReloadUploadInfoIfNeed(TaskId taskId, const UploadParam ¶m, InnerProcessInfo &info); + void ReloadUploadInfoIfNeed(const UploadParam ¶m, InnerProcessInfo &info); void GetLastUploadInfo(const std::string &tableName, Info &lastUploadInfo, UploadRetryInfo &retryInfo); @@ -444,10 +448,6 @@ protected: std::string GetStoreIdByTask(TaskId taskId); - void CheckDataAfterDownload(const std::string &tableName); - - void CheckQueryCloudData(std::string &traceId, DownloadData &downloadData, std::vector &pkColNames); - int CloudDbBatchDownloadAssets(TaskId taskId, const DownloadList &downloadList, const std::set &dupHashKeySet, InnerProcessInfo &info, ChangedData &changedAssets); @@ -471,6 +471,10 @@ protected: static void AddNotifyDataFromDownloadAssets(const std::set &dupHashKeySet, DownloadItem &downloadItem, ChangedData &changedAssets); + void CheckDataAfterDownload(const std::string &tableName); + + void CheckQueryCloudData(std::string &traceId, DownloadData &downloadData, std::vector &pkColNames); + mutable std::mutex dataLock_; TaskId lastTaskId_; std::list taskQueue_; @@ -488,7 +492,7 @@ protected: std::atomic queuedManualSyncLimit_; std::atomic closed_; - + std::atomic hasKvRemoveTask; std::atomic timerId_; std::mutex heartbeatMutex_; std::condition_variable heartbeatCv_; 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 e0361b6d..cc3ef7ff 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 @@ -47,7 +47,7 @@ void CloudSyncer::ReloadCloudWaterMarkIfNeed(const std::string &tableName, std:: cloudWaterMark = cacheCloudWaterMark.empty() ? cloudWaterMark : cacheCloudWaterMark; } -void CloudSyncer::ReloadUploadInfoIfNeed(TaskId taskId, const UploadParam ¶m, InnerProcessInfo &info) +void CloudSyncer::ReloadUploadInfoIfNeed(const UploadParam ¶m, InnerProcessInfo &info) { info.upLoadInfo.total = static_cast(param.count); Info lastUploadInfo; @@ -407,8 +407,8 @@ void GetAssetsToRemove(std::map &downloadAssets, VBucket &d for (auto &[col, assets] : downloadAssets) { for (auto &asset : assets) { if (asset.flag == static_cast(AssetOpType::DELETE) && - AssetOperationUtils::CalAssetOperation(col, asset, dbAssets, - AssetOperationUtils::CloudSyncAction::START_DOWNLOAD) == AssetOperationUtils::AssetOpType::HANDLE) { + AssetOperationUtils::CalAssetRemoveOperation(col, asset, dbAssets) == + AssetOperationUtils::AssetOpType::HANDLE) { asset.status = static_cast(AssetStatus::DELETE); assetsToRemove[col].push_back(asset); } @@ -1224,8 +1224,8 @@ bool CloudSyncer::IsTableFinishInUpload(const std::string &table) void CloudSyncer::MarkUploadFinishIfNeed(const std::string &table) { - // table exist reference should upload every times - if (storageProxy_->IsTableExistReference(table)) { + // table exist reference or reference by should upload every times + if (storageProxy_->IsTableExistReferenceOrReferenceBy(table)) { return; } std::lock_guard autoLock(dataLock_); @@ -1325,37 +1325,51 @@ std::string CloudSyncer::GetStoreIdByTask(TaskId taskId) return cloudTaskInfos_[taskId].storeId; } -void CloudSyncer::CheckDataAfterDownload(const std::string &tableName) +int CloudSyncer::CleanKvCloudData(std::function &removeFunc) { - int dataCount = 0; - int logicDeleteDataCount = 0; - int errCode = storageProxy_->GetLocalDataCount(tableName, dataCount, logicDeleteDataCount); - if (errCode == E_OK) { - LOGI("[CloudSyncer] Check local data after download[%s[%u]], data count: %d, logic delete data count: %d", - DBCommon::StringMiddleMasking(tableName).c_str(), tableName.length(), dataCount, logicDeleteDataCount); - } else { - LOGW("[CloudSyncer] Get local data after download fail: %d", errCode); + hasKvRemoveTask = true; + CloudSyncer::TaskId currentTask; + { + // stop task if exist + std::lock_guard autoLock(dataLock_); + currentTask = currentContext_.currentTaskId; + } + if (currentTask != INVALID_TASK_ID) { + StopAllTasks(-E_CLOUD_ERROR); + } + int errCode = E_OK; + { + std::lock_guard lock(syncMutex_); + errCode = removeFunc(); + hasKvRemoveTask = false; } + if (errCode != E_OK) { + LOGE("[CloudSyncer] removeFunc execute failed errCode: %d.", errCode); + } + return errCode; } -void CloudSyncer::CheckQueryCloudData(std::string &traceId, DownloadData &downloadData, - std::vector &pkColNames) +void CloudSyncer::StopAllTasks(int errCode) { - for (auto &data : downloadData.data) { - bool isVersionExist = data.count(CloudDbConstant::VERSION_FIELD) != 0; - bool isContainAllPk = true; - for (auto &pkColName : pkColNames) { - if (data.count(pkColName) == 0) { - isContainAllPk = false; - break; - } - } - std::string gid; - (void)CloudStorageUtils::GetValueFromVBucket(CloudDbConstant::GID_FIELD, data, gid); - if (!isVersionExist || !isContainAllPk) { - LOGE("[CloudSyncer] Invalid data from cloud, no version[%d], lost primary key[%d], gid[%s], traceId[%s]", - static_cast(!isVersionExist), static_cast(!isContainAllPk), gid.c_str(), traceId.c_str()); - } + CloudSyncer::TaskId currentTask; + { + std::lock_guard autoLock(dataLock_); + currentTask = currentContext_.currentTaskId; + } + // mark current task user_change + SetTaskFailed(currentTask, errCode); + UnlockIfNeed(); + WaitCurTaskFinished(); + + std::vector infoList = CopyAndClearTaskInfos(); + for (auto &info: infoList) { + LOGI("[CloudSyncer] finished taskId %" PRIu64 " with errCode %d, isPriority %d.", info.taskId, errCode, + info.priorityTask); + auto processNotifier = std::make_shared(this); + processNotifier->Init(info.table, info.devices, info.users); + info.errCode = errCode; + info.status = ProcessStatus::FINISHED; + processNotifier->NotifyProcess(info, {}, true); } } @@ -1461,8 +1475,9 @@ int CloudSyncer::BatchDownloadAndCommitRes(const DownloadList &downloadList, con int errorCode = E_OK; int index = 0; for (auto &item : downloadRecord) { - auto deleteCode = CloudDBProxy::GetInnerErrorCode(removeAssets[index].status); + auto deleteCode = removeAssets[index].status == OK ? E_OK : -E_REMOVE_ASSETS_FAILED; auto downloadCode = CloudDBProxy::GetInnerErrorCode(downloadAssets[index].status); + downloadCode = downloadCode == -E_CLOUD_RECORD_EXIST_CONFLICT ? E_OK : downloadCode; if (!isSharedTable) { item.downloadItem.assets = BackFillAssetsAfterDownload(downloadCode, deleteCode, item.flags, downloadAssets[index].assets, removeAssets[index].assets); @@ -1480,8 +1495,9 @@ int CloudSyncer::BatchDownloadAndCommitRes(const DownloadList &downloadList, con deleteCode == E_OK && downloadCode == E_OK)); errorCode = (errorCode != E_OK) ? errorCode : deleteCode; errorCode = (errorCode != E_OK) ? errorCode : downloadCode; - int ret = CommitDownloadResult(item.downloadItem, info, commitList, errorCode); - if (ret != E_OK && ret != -E_REMOVE_ASSETS_FAILED) { + int currErrorCode = (deleteCode != E_OK) ? deleteCode : downloadCode; + int ret = CommitDownloadResult(item.downloadItem, info, commitList, currErrorCode); + if (ret != E_OK) { errorCode = errorCode == E_OK ? ret : errorCode; } index++; @@ -1521,4 +1537,38 @@ void CloudSyncer::AddNotifyDataFromDownloadAssets(const std::set &dupHashKe changedAssets.primaryData[ChangeType::OP_UPDATE].push_back(downloadItem.primaryKeyValList); } } -} \ No newline at end of file + +void CloudSyncer::CheckDataAfterDownload(const std::string &tableName) +{ + int dataCount = 0; + int logicDeleteDataCount = 0; + int errCode = storageProxy_->GetLocalDataCount(tableName, dataCount, logicDeleteDataCount); + if (errCode == E_OK) { + LOGI("[CloudSyncer] Check local data after download[%s[%u]], data count: %d, logic delete data count: %d", + DBCommon::StringMiddleMasking(tableName).c_str(), tableName.length(), dataCount, logicDeleteDataCount); + } else { + LOGW("[CloudSyncer] Get local data after download fail: %d", errCode); + } +} + +void CloudSyncer::CheckQueryCloudData(std::string &traceId, DownloadData &downloadData, + std::vector &pkColNames) +{ + for (auto &data : downloadData.data) { + bool isVersionExist = data.count(CloudDbConstant::VERSION_FIELD) != 0; + bool isContainAllPk = true; + for (auto &pkColName : pkColNames) { + if (data.count(pkColName) == 0) { + isContainAllPk = false; + break; + } + } + std::string gid; + (void)CloudStorageUtils::GetValueFromVBucket(CloudDbConstant::GID_FIELD, data, gid); + if (!isVersionExist || !isContainAllPk) { + LOGE("[CloudSyncer] Invalid data from cloud, no version[%d], lost primary key[%d], gid[%s], traceId[%s]", + static_cast(!isVersionExist), static_cast(!isContainAllPk), gid.c_str(), traceId.c_str()); + } + } +} +} 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 de721262..ecad716d 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 @@ -228,6 +228,9 @@ std::map ProcessNotifier::GetCurrentTableProcess( void ProcessNotifier::UpdateUploadInfoIfNeeded(const ICloudSyncer::InnerProcessInfo &process) { + if (process.tableName.empty()) { + return; + } auto &syncProcess = IsMultiUser() ? multiSyncProcess_.at(user_) : syncProcess_; auto tableProcess = syncProcess.tableProcess.find(process.tableName); auto retryInfo = processRetryInfo_.find(process.tableName); @@ -235,6 +238,35 @@ void ProcessNotifier::UpdateUploadInfoIfNeeded(const ICloudSyncer::InnerProcessI uint32_t downloadOpCount = process.retryInfo.downloadBatchOpCount; uint32_t uploadRetryCount = retryInfo->second; tableProcess->second.upLoadInfo.successCount += std::min(uploadRetryCount, downloadOpCount); + processRetryInfo_.erase(retryInfo); + } +} + +void ProcessNotifier::UpdateAllTablesFinally() +{ + std::lock_guard autoLock(processMutex_); + UpdateTableInfoFinally(syncProcess_.tableProcess); + for (auto &syncProcess : multiSyncProcess_) { + UpdateTableInfoFinally(syncProcess.second.tableProcess); + } +} + +void ProcessNotifier::UpdateTableInfoFinally(std::map &processInfo) +{ + for (auto &item : processInfo) { + uint32_t uploadOpCount = item.second.upLoadInfo.successCount + item.second.upLoadInfo.failCount; + if (item.second.upLoadInfo.total > uploadOpCount) { + item.second.upLoadInfo.successCount = item.second.upLoadInfo.total - item.second.upLoadInfo.failCount; + } else { + item.second.upLoadInfo.total = uploadOpCount; + } + + uint32_t downloadOpCount = item.second.downLoadInfo.successCount + item.second.downLoadInfo.failCount; + if (item.second.downLoadInfo.total > downloadOpCount) { + item.second.downLoadInfo.successCount = item.second.downLoadInfo.total - item.second.downLoadInfo.failCount; + } else { + item.second.downLoadInfo.total = downloadOpCount; + } } } } 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 a26ec87e..804eeb8a 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 @@ -47,6 +47,8 @@ public: void SetAllTableFinish(); + void UpdateAllTablesFinally(); + std::map GetCurrentTableProcess() const; protected: mutable std::mutex processMutex_; @@ -62,6 +64,8 @@ private: /* update success count of previous upload batch after download retry. */ void UpdateUploadInfoIfNeeded(const ICloudSyncer::InnerProcessInfo &process); + + void UpdateTableInfoFinally(std::map &processInfo); }; } #endif // PROCESS_NOTIFIER_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 dba37897..c56316b6 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 @@ -222,7 +222,7 @@ int GenericSyncer::CancelSync(uint32_t syncId) } const std::vector &devices = operation->GetDevices(); - for (auto &deviceId : devices) { + for (const auto &deviceId : devices) { engine->ClearAllSyncTaskByDevice(deviceId); } LOGI("[Syncer] End cancelSync %" PRIu32 ", devices = %s", syncId, GetSyncDevicesStr(devices).c_str()); diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device/isync_task_context.h b/kv_store/frameworks/libs/distributeddb/syncer/src/device/isync_task_context.h index d66ba8e8..91ed8893 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device/isync_task_context.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device/isync_task_context.h @@ -26,7 +26,7 @@ #include "sync_target.h" #include "time_helper.h" namespace DistributedDB { -using CommErrHandler = std::function; +using CommErrHandler = std::function; class ISyncTaskContext : public virtual RefObject { public: 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 ef1ec281..8ddd8894 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 @@ -44,7 +44,6 @@ Metadata::Metadata() Metadata::~Metadata() { naturalStoragePtr_ = nullptr; - metadataMap_.clear(); } int Metadata::Initialize(ISyncInterface* storage) @@ -67,10 +66,6 @@ int Metadata::Initialize(ISyncInterface* storage) LOGE("Metadata::Initialize get meatadata from db failed,err=%d", errCode); return errCode; } - { - std::lock_guard lockGuard(metadataLock_); - metadataMap_.clear(); - } (void)querySyncWaterMarkHelper_.Initialize(storage); return LoadAllMetadata(); } @@ -215,17 +210,17 @@ int Metadata::SaveMetaDataValue(const DeviceID &deviceId, const MetaDataValue &i errCode = SetMetadataToDb(key, value); if (errCode != E_OK) { LOGE("Metadata::SetMetadataToDb failed errCode:%d", errCode); - return errCode; } - PutMetadataToMap(hashDeviceId, inValue); - return E_OK; + return errCode; } void Metadata::GetMetaDataValue(const DeviceID &deviceId, MetaDataValue &outValue, bool isNeedHash) { - DeviceID hashDeviceId; - GetHashDeviceId(deviceId, hashDeviceId, isNeedHash); - GetMetadataFromMap(hashDeviceId, outValue); + int errCode = GetMetaDataValueFromDB(deviceId, isNeedHash, outValue); + if (errCode == -E_NOT_FOUND && RuntimeContext::GetInstance()->IsTimeChanged()) { + outValue = {}; + outValue.syncMark = static_cast(SyncMark::SYNC_MARK_TIME_CHANGE); + } } int Metadata::SerializeMetaData(const MetaDataValue &inValue, std::vector &outValue) @@ -266,19 +261,6 @@ int Metadata::SetMetadataToDb(const std::vector &key, const std::vector return naturalStoragePtr_->PutMetaData(key, inValue, false); } -void Metadata::PutMetadataToMap(const DeviceID &deviceId, const MetaDataValue &value) -{ - metadataMap_[deviceId] = value; -} - -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]; -} - int64_t Metadata::StringToLong(const std::vector &value) const { std::string valueString(value.begin(), value.end()); @@ -320,12 +302,7 @@ int Metadata::LoadAllMetadata() std::vector> querySyncIds; for (const auto &deviceId : metaDataKeys) { - if (IsMetaDataKey(deviceId, DBConstant::DEVICEID_PREFIX_KEY)) { - errCode = LoadDeviceIdDataToMap(deviceId); - if (errCode != E_OK) { - return errCode; - } - } else if (IsMetaDataKey(deviceId, QuerySyncWaterMarkHelper::GetQuerySyncPrefixKey())) { + if (IsMetaDataKey(deviceId, QuerySyncWaterMarkHelper::GetQuerySyncPrefixKey())) { querySyncIds.push_back(deviceId); } else if (IsMetaDataKey(deviceId, QuerySyncWaterMarkHelper::GetDeleteSyncPrefixKey())) { errCode = querySyncWaterMarkHelper_.LoadDeleteSyncDataToCache(deviceId); @@ -341,24 +318,6 @@ int Metadata::LoadAllMetadata() return InitLocalMetaData(); } -int Metadata::LoadDeviceIdDataToMap(const Key &key) -{ - std::vector value; - int errCode = GetMetadataFromDb(key, value); - if (errCode != E_OK) { - return errCode; - } - MetaDataValue metaValue; - std::string metaKey(key.begin(), key.end()); - errCode = DeSerializeMetaData(value, metaValue); - if (errCode != E_OK) { - return errCode; - } - std::lock_guard lockGuard(metadataLock_); - PutMetadataToMap(metaKey, metaValue); - return errCode; -} - void Metadata::GetHashDeviceId(const DeviceID &deviceId, DeviceID &hashDeviceId, bool isNeedHash) { if (!isNeedHash) { @@ -481,12 +440,10 @@ int Metadata::ResetRecvQueryWaterMark(const DeviceID &deviceId, const std::strin void Metadata::GetDbCreateTime(const DeviceID &deviceId, uint64_t &outValue) { - MetaDataValue metadata; std::lock_guard lockGuard(metadataLock_); - DeviceID hashDeviceId; - GetHashDeviceId(deviceId, hashDeviceId, true); - if (metadataMap_.find(hashDeviceId) != metadataMap_.end()) { - metadata = metadataMap_[hashDeviceId]; + MetaDataValue metadata; + int errCode = GetMetaDataValueFromDB(deviceId, true, metadata); + if (errCode == E_OK) { outValue = metadata.dbCreateTime; return; } @@ -496,12 +453,10 @@ void Metadata::GetDbCreateTime(const DeviceID &deviceId, uint64_t &outValue) int Metadata::SetDbCreateTime(const DeviceID &deviceId, uint64_t inValue, bool isNeedHash) { - MetaDataValue metadata; std::lock_guard lockGuard(metadataLock_); - DeviceID hashDeviceId; - GetHashDeviceId(deviceId, hashDeviceId, isNeedHash); - if (metadataMap_.find(hashDeviceId) != metadataMap_.end()) { - metadata = metadataMap_[hashDeviceId]; + MetaDataValue metadata; + int errCode = GetMetaDataValueFromDB(deviceId, isNeedHash, metadata); + if (errCode == E_OK) { if (metadata.dbCreateTime != 0 && metadata.dbCreateTime != inValue) { metadata.clearDeviceDataMark = REMOVE_DEVICE_DATA_MARK; LOGI("Metadata::SetDbCreateTime,set clear data mark,dev=%s,dbCreateTime=%" PRIu64, @@ -510,33 +465,32 @@ int Metadata::SetDbCreateTime(const DeviceID &deviceId, uint64_t inValue, bool i if (metadata.dbCreateTime == 0) { LOGI("Metadata::SetDbCreateTime,update dev=%s,dbCreateTime=%" PRIu64, STR_MASK(deviceId), inValue); } + } else if (errCode != -E_NOT_FOUND) { + return errCode; } + metadata.dbCreateTime = inValue; - return SaveMetaDataValue(deviceId, metadata); + return SaveMetaDataValue(deviceId, metadata, isNeedHash); } int Metadata::ResetMetaDataAfterRemoveData(const DeviceID &deviceId) { - MetaDataValue metadata; std::lock_guard lockGuard(metadataLock_); - DeviceID hashDeviceId; - GetHashDeviceId(deviceId, hashDeviceId, true); - if (metadataMap_.find(hashDeviceId) != metadataMap_.end()) { - metadata = metadataMap_[hashDeviceId]; - metadata.clearDeviceDataMark = 0; // clear mark - return SaveMetaDataValue(deviceId, metadata); + MetaDataValue metadata; + int errCode = GetMetaDataValueFromDB(deviceId, true, metadata); + if (errCode == E_OK) { + metadata.clearDeviceDataMark = 0; + return SaveMetaDataValue(deviceId, metadata, true); } - return -E_NOT_FOUND; + return errCode; } void Metadata::GetRemoveDataMark(const DeviceID &deviceId, uint64_t &outValue) { - MetaDataValue metadata; std::lock_guard lockGuard(metadataLock_); - DeviceID hashDeviceId; - GetHashDeviceId(deviceId, hashDeviceId, true); - if (metadataMap_.find(hashDeviceId) != metadataMap_.end()) { - metadata = metadataMap_[hashDeviceId]; + MetaDataValue metadata; + int errCode = GetMetaDataValueFromDB(deviceId, true, metadata); + if (errCode == E_OK) { outValue = metadata.clearDeviceDataMark; return; } @@ -641,15 +595,10 @@ void Metadata::UnlockWaterMark() const int Metadata::GetWaterMarkInfoFromDB(const std::string &dev, bool isNeedHash, WatermarkInfo &info) { - Key devKey; - DeviceID hashDeviceId; - { - std::lock_guard lockGuard(metadataLock_); - GetHashDeviceId(dev, hashDeviceId, isNeedHash); - DBCommon::StringToVector(hashDeviceId, devKey); - } // read from db avoid watermark update in diff process - int errCode = LoadDeviceIdDataToMap(devKey); + std::lock_guard lockGuard(metadataLock_); + MetaDataValue metadata; + int errCode = GetMetaDataValueFromDB(dev, isNeedHash, metadata); if (errCode == -E_NOT_FOUND) { LOGD("[Metadata] not found meta value"); return E_OK; @@ -658,13 +607,9 @@ int Metadata::GetWaterMarkInfoFromDB(const std::string &dev, bool isNeedHash, Wa LOGE("[Metadata] reload meta value failed %d", errCode); return errCode; } - { - std::lock_guard lockGuard(metadataLock_); - MetaDataValue metadata; - GetMetadataFromMap(hashDeviceId, metadata); - info.sendMark = metadata.localWaterMark; - info.receiveMark = metadata.peerWaterMark; - } + + info.sendMark = metadata.localWaterMark; + info.receiveMark = metadata.peerWaterMark; return E_OK; } @@ -683,12 +628,29 @@ int Metadata::ClearAllTimeSyncFinishMark() int Metadata::ClearAllMetaDataValue(uint32_t innerClearAction) { - int errCode = E_OK; + std::vector> metaDataKeys; + int errCode = GetAllMetadataKey(metaDataKeys); + if (errCode != E_OK) { + LOGE("[Metadata][ClearAllMetaDataValue] get all metadata key failed err=%d", errCode); + return errCode; + } + std::lock_guard lockGuard(metadataLock_); - for (auto &[hashDev, metaDataValue] : metadataMap_) { - ClearMetaDataValue(innerClearAction, metaDataValue); + for (const auto &deviceId : metaDataKeys) { + if (!IsMetaDataKey(deviceId, DBConstant::DEVICEID_PREFIX_KEY)) { + continue; + } + MetaDataValue metaData; + int innerErrCode = GetMetaDataValueFromDB(deviceId, metaData); + if (innerErrCode != E_OK) { + LOGW("[Metadata][ClearAllMetaDataValue] action %" PRIu32 " get meta data failed %d", innerClearAction, + innerErrCode); + errCode = errCode == E_OK ? innerErrCode : errCode; + continue; + } + ClearMetaDataValue(innerClearAction, metaData); std::vector value; - int innerErrCode = SerializeMetaData(metaDataValue, value); + innerErrCode = SerializeMetaData(metaData, value); // clear sync mark without transaction here // just ignore error metadata value if (innerErrCode != E_OK) { @@ -698,9 +660,7 @@ int Metadata::ClearAllMetaDataValue(uint32_t innerClearAction) continue; } - std::vector key; - DBCommon::StringToVector(hashDev, key); - innerErrCode = SetMetadataToDb(key, value); + innerErrCode = SetMetadataToDb(deviceId, value); if (innerErrCode != E_OK) { LOGW("[Metadata][ClearAllMetaDataValue] action %" PRIu32 " save meta data failed %d", innerClearAction, innerErrCode); @@ -970,4 +930,25 @@ int Metadata::InitLocalMetaData() } return errCode; } + +int Metadata::GetMetaDataValueFromDB(const std::string &deviceId, bool isNeedHash, MetaDataValue &metaDataValue) +{ + DeviceID hashDeviceId; + Key devKey; + GetHashDeviceId(deviceId, hashDeviceId, isNeedHash); + DBCommon::StringToVector(hashDeviceId, devKey); + + return GetMetaDataValueFromDB(devKey, metaDataValue); +} + +int Metadata::GetMetaDataValueFromDB(const Key &key, MetaDataValue &metaDataValue) +{ + std::vector value; + int errCode = GetMetadataFromDb(key, value); + if (errCode != E_OK) { + LOGE("[Metadata] Get metadata from db failed %d", errCode); + return errCode; + } + return DeSerializeMetaData(value, metaDataValue); +} } // namespace DistributedDB \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device/meta_data.h b/kv_store/frameworks/libs/distributeddb/syncer/src/device/meta_data.h index 8efc3134..be647845 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device/meta_data.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device/meta_data.h @@ -188,10 +188,6 @@ private: int SetMetadataToDb(const std::vector &key, const std::vector &inValue); - void PutMetadataToMap(const DeviceID &deviceId, const MetaDataValue &value); - - void GetMetadataFromMap(const DeviceID &deviceId, MetaDataValue &outValue); - int64_t StringToLong(const std::vector &value) const; int GetAllMetadataKey(std::vector> &keys); @@ -200,10 +196,6 @@ private: void GetHashDeviceId(const DeviceID &deviceId, DeviceID &hashDeviceId, bool isNeedHash); - // this function will read data from db by metaData's key - // and then serialize it and put to map - int LoadDeviceIdDataToMap(const Key &key); - // reset the waterMark to zero int ResetRecvQueryWaterMark(const DeviceID &deviceId, const std::string &tableName, bool isNeedHash); @@ -236,6 +228,10 @@ private: int InitLocalMetaData(); + int GetMetaDataValueFromDB(const std::string &deviceId, bool isNeedHash, MetaDataValue &metaDataValue); + + int GetMetaDataValueFromDB(const Key &key, MetaDataValue &metaDataValue); + // store localTimeOffset in ram; if change, should add a lock first, change here and metadata, // then release lock std::atomic localTimeOffset_; @@ -244,7 +240,6 @@ private: // if changed, it should be locked from save-to-db to change-in-memory.save to db must be first, // if save to db fail, it will not be changed in memory. - std::map metadataMap_; mutable std::mutex metadataLock_; std::map deviceIdToHashDeviceIdMap_; diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device/query_sync_water_mark_helper.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/device/query_sync_water_mark_helper.cpp index 712deadf..c708137c 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device/query_sync_water_mark_helper.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device/query_sync_water_mark_helper.cpp @@ -39,7 +39,6 @@ QuerySyncWaterMarkHelper::~QuerySyncWaterMarkHelper() { storage_ = nullptr; deviceIdToHashQuerySyncIdMap_.clear(); - deleteSyncCache_.clear(); deviceIdToHashDeleteSyncIdMap_.clear(); } @@ -86,22 +85,14 @@ int QuerySyncWaterMarkHelper::LoadDeleteSyncDataToCache(const Key &deleteWaterMa if (errCode != E_OK) { return errCode; } - std::lock_guard autoLock(deleteSyncLock_); - deleteSyncCache_[dbKey] = deleteWaterMark; return errCode; } int QuerySyncWaterMarkHelper::GetQueryWaterMarkInCacheAndDb(const std::string &cacheKey, QueryWaterMark &queryWaterMark) { - // first get from cache_ - int errCode = querySyncCache_.Get(cacheKey, queryWaterMark); - bool addToCache = false; - if (errCode == -E_NOT_FOUND) { - // second get from db - errCode = GetQueryWaterMarkFromDB(cacheKey, queryWaterMark); - addToCache = true; - } + // second get from db + int errCode = GetQueryWaterMarkFromDB(cacheKey, queryWaterMark); if (errCode == -E_NOT_FOUND) { // third generate one and save to db errCode = PutQueryWaterMarkToDB(cacheKey, queryWaterMark); @@ -109,11 +100,6 @@ int QuerySyncWaterMarkHelper::GetQueryWaterMarkInCacheAndDb(const std::string &c // something error return if (errCode != E_OK) { LOGE("[Meta]GetQueryWaterMark Fail code = %d", errCode); - return errCode; - } - // remember add to cache_ - if (addToCache) { - querySyncCache_.Put(cacheKey, queryWaterMark); } return errCode; } @@ -182,13 +168,8 @@ int QuerySyncWaterMarkHelper::UpdateCacheAndSave(const std::string &cacheKey, if (errCode != E_OK) { return errCode; } - // save db first - errCode = SaveQueryWaterMarkToDB(cacheKey, queryWaterMark); - if (errCode != E_OK) { - return errCode; - } - querySyncCache_.Put(cacheKey, queryWaterMark); - return errCode; + // save db + return SaveQueryWaterMarkToDB(cacheKey, queryWaterMark); } int QuerySyncWaterMarkHelper::PutQueryWaterMarkToDB(const DeviceID &dbKeyString, QueryWaterMark &queryWaterMark) @@ -338,37 +319,24 @@ int QuerySyncWaterMarkHelper::SetRecvDeleteSyncWaterMark(const DeviceID &deviceI int QuerySyncWaterMarkHelper::UpdateDeleteSyncCacheAndSave(const std::string &dbKey, const DeleteWaterMark &deleteWaterMark) { - // save db first - int errCode = SaveDeleteWaterMarkToDB(dbKey, deleteWaterMark); - if (errCode != E_OK) { - return errCode; - } - // modify cache - deleteSyncCache_[dbKey] = deleteWaterMark; - return errCode; + // save db + return SaveDeleteWaterMarkToDB(dbKey, deleteWaterMark); } int QuerySyncWaterMarkHelper::GetDeleteWaterMarkFromCache(const DeviceID &hashDeviceId, DeleteWaterMark &deleteWaterMark) { - // if not found - if (deleteSyncCache_.find(hashDeviceId) == deleteSyncCache_.end()) { - DeleteWaterMark waterMark; - waterMark.version = DELETE_WATERMARK_VERSION_CURRENT; - int errCode = GetDeleteWaterMarkFromDB(hashDeviceId, waterMark); - if (errCode == -E_NOT_FOUND) { - deleteWaterMark.sendWaterMark = 0; - deleteWaterMark.recvWaterMark = 0; - errCode = E_OK; - } - if (errCode != E_OK) { - LOGE("[Meta]GetDeleteWaterMark Fail code = %d", errCode); - return errCode; - } - deleteSyncCache_.insert(std::pair(hashDeviceId, waterMark)); + deleteWaterMark.version = DELETE_WATERMARK_VERSION_CURRENT; + int errCode = GetDeleteWaterMarkFromDB(hashDeviceId, deleteWaterMark); + if (errCode == -E_NOT_FOUND) { + deleteWaterMark.sendWaterMark = 0; + deleteWaterMark.recvWaterMark = 0; + errCode = E_OK; } - deleteWaterMark = deleteSyncCache_[hashDeviceId]; - return E_OK; + if (errCode != E_OK) { + LOGE("[Meta]GetDeleteWaterMark Fail code = %d", errCode); + } + return errCode; } int QuerySyncWaterMarkHelper::GetDeleteWaterMarkFromDB(const DeviceID &hashDeviceId, @@ -537,8 +505,6 @@ int QuerySyncWaterMarkHelper::ResetRecvQueryWaterMark(const DeviceID &deviceId, LOGE("[META]ResetRecvQueryWaterMark fail errCode:%d", errCode); return errCode; } - // clean cache - querySyncCache_.RemoveWithPrefixKey(prefixKeyStr); return E_OK; } } // namespace DistributedDB \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device/query_sync_water_mark_helper.h b/kv_store/frameworks/libs/distributeddb/syncer/src/device/query_sync_water_mark_helper.h index bb76a503..6c576a2b 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device/query_sync_water_mark_helper.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device/query_sync_water_mark_helper.h @@ -143,12 +143,10 @@ private: // because it will change the eliminationChain // and the queryWaterMark use a LRU Map to store in ram std::mutex queryWaterMarkLock_; - LruMap querySyncCache_; std::map> deviceIdToHashQuerySyncIdMap_; // also store deleteKeyWaterMark should add a lock std::mutex deleteSyncLock_; - std::map deleteSyncCache_; std::map deviceIdToHashDeleteSyncIdMap_; ISyncInterface *storage_; 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 10cb8311..eb30ebfd 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 @@ -519,7 +519,8 @@ int RemoteExecutor::SendRequestMessage(const std::string &target, Message *messa SendConfig sendConfig; SetSendConfigParam(syncInterface->GetDbProperties(), target, false, REMOTE_EXECUTOR_SEND_TIME_OUT, sendConfig); RefObject::IncObjRef(this); - int errCode = communicator->SendMessage(target, message, sendConfig, [this, sessionId](int errCode) { + int errCode = communicator->SendMessage(target, message, sendConfig, + [this, sessionId](int errCode, bool isDirectEnd) { if (errCode != E_OK) { DoSendFailed(sessionId, errCode); } 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 7048bb2d..d5543bfd 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 @@ -1066,8 +1066,8 @@ int SingleVerDataSync::SendDataPacket(SyncType syncType, DataRequestPacket *pack if (performance != nullptr) { performance->StepTimeRecordStart(PT_TEST_RECORDS::RECORD_DATA_SEND_REQUEST_TO_ACK_RECV); } - CommErrHandler handler = [this, context, sessionId = message->GetSessionId()](int ret) { - SyncTaskContext::CommErrHandlerFunc(ret, context, sessionId); + CommErrHandler handler = [this, context, sessionId = message->GetSessionId()](int ret, bool isDirectEnd) { + SyncTaskContext::CommErrHandlerFunc(ret, context, sessionId, isDirectEnd); }; errCode = Send(context, message, handler, packetLen); if (errCode != E_OK) { @@ -1467,8 +1467,8 @@ int SingleVerDataSync::SendReSendPacket(DataRequestPacket *packet, SingleVerSync return errCode; } SingleVerDataSyncUtils::SetMessageHeadInfo(*message, TYPE_REQUEST, context->GetDeviceId(), sequenceId, sessionId); - CommErrHandler handler = [this, context, sessionId = message->GetSessionId()](int ret) { - SyncTaskContext::CommErrHandlerFunc(ret, context, sessionId); + CommErrHandler handler = [this, context, sessionId = message->GetSessionId()](int ret, bool isDirectEnd) { + SyncTaskContext::CommErrHandlerFunc(ret, context, sessionId, isDirectEnd); }; errCode = Send(context, message, handler, packetLen); if (errCode != E_OK) { 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 ce774443..4a34bf9f 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 @@ -249,7 +249,7 @@ protected: int UnsubscribeRequestRecv(SingleVerSyncTaskContext *context, const Message *message); int SendControlAck(SingleVerSyncTaskContext *context, const Message *message, int32_t recvCode, uint32_t controlCmdType, const CommErrHandler &handler = nullptr); - int QuerySyncCheck(SingleVerSyncTaskContext *context); + static int QuerySyncCheck(SingleVerSyncTaskContext *context); void RemoveSubscribeIfNeed(const std::string &queryId, const std::shared_ptr &subscribeManager); diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_data_sync_extend.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_data_sync_extend.cpp index b9f50390..cbfeb722 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_data_sync_extend.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device/singlever/single_ver_data_sync_extend.cpp @@ -111,8 +111,8 @@ int SingleVerDataSync::SendControlPacket(ControlRequestPacket *packet, SingleVer } SingleVerDataSyncUtils::SetMessageHeadInfo(*message, TYPE_REQUEST, context->GetDeviceId(), context->GetSequenceId(), context->GetRequestSessionId()); - CommErrHandler handler = [this, context, sessionId = message->GetSessionId()](int ret) { - SyncTaskContext::CommErrHandlerFunc(ret, context, sessionId); + CommErrHandler handler = [this, context, sessionId = message->GetSessionId()](int ret, bool isDirectEnd) { + SyncTaskContext::CommErrHandlerFunc(ret, context, sessionId, isDirectEnd); }; errCode = Send(context, message, handler, packetLen); if (errCode != E_OK) { @@ -337,4 +337,4 @@ void SingleVerDataSync::RemoveSubscribeIfNeed(const std::string &queryId, storage_->RemoveSubscribe(queryId); } } -} // namespace DistributedDB \ No newline at end of file +} // namespace DistributedDB 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 6f7783ba..986f9abe 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 @@ -477,8 +477,9 @@ Event SingleVerSyncStateMachine::DoTimeSync() const CommErrHandler handler = nullptr; // Auto sync need do retry don't use errHandler to return. if (!context_->IsAutoSync()) { - handler = [this, context = context_, requestSessionId = context_->GetRequestSessionId()](int ret) { - SyncTaskContext::CommErrHandlerFunc(ret, context, requestSessionId); + handler = [this, context = context_, + requestSessionId = context_->GetRequestSessionId()](int ret, bool isDirectEnd) { + SyncTaskContext::CommErrHandlerFunc(ret, context, requestSessionId, isDirectEnd); }; } int errCode = timeSync_->SyncStart(handler, context_->GetRequestSessionId()); @@ -509,8 +510,9 @@ Event SingleVerSyncStateMachine::DoAbilitySync() const return GetEventAfterTimeSync(context_->GetMode()); } - CommErrHandler handler = [this, context = context_, requestSessionId = context_->GetRequestSessionId()](int ret) { - SyncTaskContext::CommErrHandlerFunc(ret, context, requestSessionId); + CommErrHandler handler = [this, context = context_, + requestSessionId = context_->GetRequestSessionId()](int ret, bool isDirectEnd) { + SyncTaskContext::CommErrHandlerFunc(ret, context, requestSessionId, isDirectEnd); }; LOGI("[StateMachine][AbilitySync] start abilitySync,label=%s,dev=%s", dataSync_->GetLabel().c_str(), STR_MASK(context_->GetDeviceId())); @@ -747,6 +749,8 @@ int SingleVerSyncStateMachine::HandleDataAckRecv(const Message *inMsg) } if (errCode == -E_NEED_ABILITY_SYNC || errCode == -E_RE_SEND_DATA || errCode == -E_NEED_TIME_SYNC) { StopFeedDogForSync(SyncDirectionFlag::SEND); + dataSync_->ClearSyncStatus(); + context_->ReSetSequenceId(); } else if (errCode == -E_SAVE_DATA_NOTIFY) { return errCode; } 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 2237712a..8a38d34e 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 @@ -484,7 +484,7 @@ void SyncTaskContext::Abort(int status) Clear(); } -void SyncTaskContext::CommErrHandlerFunc(int errCode, ISyncTaskContext *context, int32_t sessionId) +void SyncTaskContext::CommErrHandlerFunc(int errCode, ISyncTaskContext *context, int32_t sessionId, bool isDirectEnd) { { std::lock_guard lock(synTaskContextSetLock_); @@ -496,7 +496,8 @@ void SyncTaskContext::CommErrHandlerFunc(int errCode, ISyncTaskContext *context, RefObject::IncObjRef(context); } - static_cast(context)->CommErrHandlerFuncInner(errCode, static_cast(sessionId)); + static_cast(context)->CommErrHandlerFuncInner(errCode, static_cast(sessionId), + isDirectEnd); RefObject::DecObjRef(context); } @@ -527,7 +528,7 @@ bool SyncTaskContext::IsCommNormal() const return isCommNormal_; } -void SyncTaskContext::CommErrHandlerFuncInner(int errCode, uint32_t sessionId) +void SyncTaskContext::CommErrHandlerFuncInner(int errCode, uint32_t sessionId, bool isDirectEnd) { { RefObject::AutoLock lock(this); @@ -536,12 +537,17 @@ void SyncTaskContext::CommErrHandlerFuncInner(int errCode, uint32_t sessionId) } if (errCode == E_OK) { + SetCommFailErrCode(errCode); // when communicator sent message failed, the state machine will get the error and exit this sync task // it seems unnecessary to change isCommNormal_ value, so just return here return; } } - LOGE("[SyncTaskContext][CommErr] errCode %d", errCode); + LOGE("[SyncTaskContext][CommErr] errCode %d, isDirectEnd %d", errCode, static_cast(isDirectEnd)); + if (!isDirectEnd) { + SetErrCodeWhenWaitTimeOut(errCode); + return; + } if (errCode > 0) { SetCommFailErrCode(static_cast(COMM_FAILURE)); } else { @@ -857,4 +863,13 @@ void SyncTaskContext::SetCommFailErrCode(int errCode) { commErrCode_ = errCode; } + +void SyncTaskContext::SetErrCodeWhenWaitTimeOut(int errCode) +{ + if (errCode > 0) { + SetCommFailErrCode(static_cast(TIME_OUT)); + } else { + SetCommFailErrCode(errCode); + } +} } // namespace DistributedDB diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/device/sync_task_context.h b/kv_store/frameworks/libs/distributeddb/syncer/src/device/sync_task_context.h index 07d474fa..825dac41 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/device/sync_task_context.h +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/device/sync_task_context.h @@ -174,7 +174,7 @@ public: virtual void Abort(int status); // Used in send msg, as execution is asynchronous, should use this function to handle result. - static void CommErrHandlerFunc(int errCode, ISyncTaskContext *context, int32_t sessionId); + static void CommErrHandlerFunc(int errCode, ISyncTaskContext *context, int32_t sessionId, bool isDirectEnd = true); int GetTaskErrCode() const override; @@ -229,7 +229,7 @@ protected: virtual void CopyTargetData(const ISyncTarget *target, const TaskParam &taskParam); - void CommErrHandlerFuncInner(int errCode, uint32_t sessionId); + void CommErrHandlerFuncInner(int errCode, uint32_t sessionId, bool isDirectEnd = true); void KillWait(); @@ -247,6 +247,8 @@ protected: static uint8_t GetPermissionCheckFlag(bool isAutoSync, int syncMode); + void SetErrCodeWhenWaitTimeOut(int errCode); + mutable std::mutex targetQueueLock_; std::list requestTargetQueue_; std::list responseTargetQueue_; 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 55b903c6..43bd032e 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 @@ -502,7 +502,7 @@ int TimeSync::TimeSyncDriver(TimerId timerId) } std::lock_guard lock(timeDriverLock_); int errCode = RuntimeContext::GetInstance()->ScheduleTask([this]() { - CommErrHandler handler = [this](int ret) { CommErrHandlerFunc(ret, this); }; + CommErrHandler handler = [this](int ret, bool isDirectEnd) { CommErrHandlerFunc(ret, this); }; (void)this->SyncStart(handler); std::lock_guard innerLock(this->timeDriverLock_); this->timeDriverLockCount_--; @@ -523,7 +523,7 @@ int TimeSync::GetTimeOffset(TimeOffset &outOffset, uint32_t timeout, uint32_t se std::lock_guard lock(cvLock_); isAckReceived_ = false; } - CommErrHandler handler = [this](int ret) { CommErrHandlerFunc(ret, this); }; + CommErrHandler handler = [this](int ret, bool isDirectEnd) { CommErrHandlerFunc(ret, this); }; int errCode = SyncStart(handler, sessionId); LOGD("TimeSync::GetTimeOffset start, current time = %" PRIu64 ", errCode = %d, timeout = %" PRIu32 " ms", TimeHelper::GetSysCurrentTime(), errCode, timeout); @@ -621,7 +621,7 @@ int TimeSync::SendMessageWithSendEnd(const Message *message, const CommErrHandle { std::shared_ptr timeSyncPtr = shared_from_this(); auto sessionId = message->GetSessionId(); - return SendPacket(deviceId_, message, [handler, timeSyncPtr, sessionId, this](int errCode) { + return SendPacket(deviceId_, message, [handler, timeSyncPtr, sessionId, this](int errCode, bool isDirectEnd) { if (closed_) { LOGW("[TimeSync] DB closed, ignore send end! dev=%.3s", deviceId_.c_str()); return; @@ -632,7 +632,7 @@ int TimeSync::SendMessageWithSendEnd(const Message *message, const CommErrHandle sessionBeginTime_[sessionId] = timeHelper_->GetTime(); } if (handler != nullptr) { - handler(errCode); + handler(errCode, isDirectEnd); } }); } diff --git a/kv_store/frameworks/libs/distributeddb/syncer/src/sync_operation.cpp b/kv_store/frameworks/libs/distributeddb/syncer/src/sync_operation.cpp index a9df29eb..0e68d5fe 100644 --- a/kv_store/frameworks/libs/distributeddb/syncer/src/sync_operation.cpp +++ b/kv_store/frameworks/libs/distributeddb/syncer/src/sync_operation.cpp @@ -114,7 +114,7 @@ void SyncOperation::SetStatus(const std::string &deviceId, int status, int commE return; } iter->second = status; - if ((status != OP_COMM_ABNORMAL) || (commErrCode == E_OK)) { + if (((status != OP_COMM_ABNORMAL) && (status != OP_TIMEOUT)) || (commErrCode == E_OK)) { return; } commErrCodeMap_.insert(std::pair(deviceId, commErrCode)); @@ -164,7 +164,7 @@ int SyncOperation::GetMode() const void SyncOperation::ReplaceCommErrCode(std::map &finishStatus) { for (auto &item : finishStatus) { - if (item.second != OP_COMM_ABNORMAL) { + if ((item.second != OP_COMM_ABNORMAL) && (item.second != OP_TIMEOUT)) { continue; } std::string deviceId = item.first; @@ -476,7 +476,7 @@ std::string SyncOperation::GetFinishDetailMsg(const std::map & std::string msg = "Sync detail is:"; for (const auto &[dev, status]: finishStatus) { msg += "dev=" + DBCommon::StringMasking(dev); - if (status > static_cast(OP_FINISHED_ALL)) { + if ((status > static_cast(OP_FINISHED_ALL)) || (status < E_OK)) { msg += " sync failed, reason is " + std::to_string(status); } else { msg += " sync success"; diff --git a/kv_store/frameworks/libs/distributeddb/test/BUILD.gn b/kv_store/frameworks/libs/distributeddb/test/BUILD.gn index cd3cb621..d5647788 100644 --- a/kv_store/frameworks/libs/distributeddb/test/BUILD.gn +++ b/kv_store/frameworks/libs/distributeddb/test/BUILD.gn @@ -901,6 +901,7 @@ group("unittest") { ":DistributedDBCloudSaveCloudDataTest", ":DistributedDBCloudSchemaMgrTest", ":DistributedDBCloudStrategyTest", + ":DistributedDBCloudSyncerDownloadAssetsTest", ":DistributedDBCloudSyncerDownloadTest", ":DistributedDBCloudSyncerLockTest", ":DistributedDBCloudSyncerProgressManagerTest", diff --git a/kv_store/frameworks/libs/distributeddb/test/fuzztest/json_fuzzer/json_fuzzer.cpp b/kv_store/frameworks/libs/distributeddb/test/fuzztest/json_fuzzer/json_fuzzer.cpp index 8b4ff2d7..778d346e 100644 --- a/kv_store/frameworks/libs/distributeddb/test/fuzztest/json_fuzzer/json_fuzzer.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/fuzztest/json_fuzzer/json_fuzzer.cpp @@ -1567,14 +1567,13 @@ void DbFlushFuzz(const uint8_t *data, size_t size) { GRD_DB *db = nullptr; GRD_DB *db2 = nullptr; + const uint32_t flags = *reinterpret_cast(data); int ret = GRD_DBOpen(TEST_DB_FILE, CONFIG_STR, GRD_DB_OPEN_CREATE, &db); if (ret == GRD_OK) { - GRD_Flush(db, 0); - GRD_Flush(db, 1); + GRD_Flush(db, flags); GRD_DBClose(db, GRD_DB_CLOSE); } - GRD_Flush(db2, 0); - GRD_Flush(db2, 1); + GRD_Flush(db2, flags); } void TestGrdDbApGrdGetItem002Fuzz() diff --git a/kv_store/frameworks/libs/distributeddb/test/fuzztest/jsoninner_fuzzer/jsoninner_fuzzer.cpp b/kv_store/frameworks/libs/distributeddb/test/fuzztest/jsoninner_fuzzer/jsoninner_fuzzer.cpp index d619d966..7abfdeec 100644 --- a/kv_store/frameworks/libs/distributeddb/test/fuzztest/jsoninner_fuzzer/jsoninner_fuzzer.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/fuzztest/jsoninner_fuzzer/jsoninner_fuzzer.cpp @@ -1576,14 +1576,13 @@ void DbFlushFuzz(const uint8_t *data, size_t size) { GRD_DB *db = nullptr; GRD_DB *db2 = nullptr; + const uint32_t flags = *reinterpret_cast(data); int ret = GRD_DBOpenInner(TEST_DB_FILE, CONFIG_STR, GRD_DB_OPEN_CREATE, &db); if (ret == GRD_OK) { - GRD_FlushInner(db, 0); - GRD_FlushInner(db, 1); + GRD_FlushInner(db, flags); GRD_DBCloseInner(db, GRD_DB_CLOSE); } - GRD_FlushInner(db2, 0); - GRD_FlushInner(db2, 1); + GRD_FlushInner(db2, flags); } void TestGrdDbApGrdGetItem002Fuzz() diff --git a/kv_store/frameworks/libs/distributeddb/test/fuzztest/kvdelegatemanager_fuzzer/kvdelegatemanager_fuzzer.cpp b/kv_store/frameworks/libs/distributeddb/test/fuzztest/kvdelegatemanager_fuzzer/kvdelegatemanager_fuzzer.cpp index 0a5fdcf3..31429f8d 100644 --- a/kv_store/frameworks/libs/distributeddb/test/fuzztest/kvdelegatemanager_fuzzer/kvdelegatemanager_fuzzer.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/fuzztest/kvdelegatemanager_fuzzer/kvdelegatemanager_fuzzer.cpp @@ -35,7 +35,7 @@ using namespace DistributedDBTest; KvStoreDelegateManager g_mgr("APP_ID", "USER_ID"); const std::string DUMP_DISTRIBUTED_DB = "--database"; -std::string GetRandomString(const uint8_t *data, size_t size, size_t len, uint32_t &start) +std::string GetString(const uint8_t *data, size_t size, size_t len, uint32_t &start) { std::string res; if (size == 0) { @@ -49,7 +49,7 @@ std::string GetRandomString(const uint8_t *data, size_t size, size_t len, uint32 return res; } -void GetRandomAutoLaunchOption(const uint8_t* data, size_t size, AutoLaunchOption &option) +void GetAutoLaunchOption(const uint8_t* data, size_t size, AutoLaunchOption &option) { std::string randomStr = size == 0 ? "" : std::string(data, data + size - 1); option.schema = randomStr; @@ -96,9 +96,9 @@ void CombineTest(const uint8_t *data, size_t size) const int paramCount = 3; for (size_t len = 1; len < (size / paramCount); len++) { uint32_t start = 0; - std::string appId = GetRandomString(data, size, len, start); - std::string userId = GetRandomString(data, size, len, start); - std::string storeId = GetRandomString(data, size, len, start); + std::string appId = GetString(data, size, len, start); + std::string userId = GetString(data, size, len, start); + std::string storeId = GetString(data, size, len, start); std::string dir; (void) KvStoreDelegateManager::GetDatabaseDir(storeId, appId, userId, dir); (void) KvStoreDelegateManager::GetDatabaseDir(storeId, dir); @@ -106,12 +106,12 @@ void CombineTest(const uint8_t *data, size_t size) bool syncDualTupleMode = static_cast(*data); (void) KvStoreDelegateManager::GetKvStoreIdentifier(userId, appId, storeId, syncDualTupleMode); AutoLaunchOption option; - GetRandomAutoLaunchOption(data, size, option); + GetAutoLaunchOption(data, size, option); option.dataDir = path; (void) KvStoreDelegateManager::EnableKvStoreAutoLaunch(userId, appId, storeId, option, nullptr); (void) KvStoreDelegateManager::DisableKvStoreAutoLaunch(userId, appId, storeId); CallbackFuzz(data, storeId); - std::string targetDev = GetRandomString(data, size, len, start); + std::string targetDev = GetString(data, size, len, start); bool isCheckOk = static_cast(*data); auto databaseStatusNotifyCallback = [userId, appId, storeId, targetDev, &isCheckOk] ( const std::string ¬ifyUserId, const std::string ¬ifyAppId, const std::string ¬ifyStoreId, diff --git a/kv_store/frameworks/libs/distributeddb/test/fuzztest/nbdelegate_fuzzer/nbdelegate_fuzzer.cpp b/kv_store/frameworks/libs/distributeddb/test/fuzztest/nbdelegate_fuzzer/nbdelegate_fuzzer.cpp index 6a8cb3c7..0370e56f 100644 --- a/kv_store/frameworks/libs/distributeddb/test/fuzztest/nbdelegate_fuzzer/nbdelegate_fuzzer.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/fuzztest/nbdelegate_fuzzer/nbdelegate_fuzzer.cpp @@ -193,13 +193,13 @@ void GetDeviceEntriesTest(const uint8_t *data, size_t size, KvStoreNbDelegate *k kvNbDelegatePtr->GetDeviceEntries(device, vect); } -void RandomModeRemoveDeviceData(const uint8_t *data, size_t size, KvStoreNbDelegate *kvNbDelegatePtr) +void RemoveDeviceDataByMode(const uint8_t *data, size_t size, KvStoreNbDelegate *kvNbDelegatePtr) { if (size == 0) { return; } auto mode = static_cast(data[0]); - LOGI("[RandomModeRemoveDeviceData] select mode %d", static_cast(mode)); + LOGI("[RemoveDeviceDataByMode] select mode %d", static_cast(mode)); if (mode == DEFAULT) { return; } @@ -259,7 +259,7 @@ void FuzzCURD(const uint8_t *data, size_t size, KvStoreNbDelegate *kvNbDelegateP kvNbDelegatePtr->GetTaskCount(); std::string rawString(reinterpret_cast(data), size); kvNbDelegatePtr->RemoveDeviceData(rawString); - RandomModeRemoveDeviceData(data, size, kvNbDelegatePtr); + RemoveDeviceDataByMode(data, size, kvNbDelegatePtr); GetDeviceEntriesTest(data, size, kvNbDelegatePtr); } diff --git a/kv_store/frameworks/libs/distributeddb/test/moduletest/src/distributeddb_nb_observer_test.cpp b/kv_store/frameworks/libs/distributeddb/test/moduletest/src/distributeddb_nb_observer_test.cpp index 17a8ca19..4637f85d 100644 --- a/kv_store/frameworks/libs/distributeddb/test/moduletest/src/distributeddb_nb_observer_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/moduletest/src/distributeddb_nb_observer_test.cpp @@ -1259,14 +1259,14 @@ HWTEST_F(DistributeddbNbObserverTest, Pressure007, TestSize.Level1) if (opCnt == NB_OPERATION_CNT_START) { EXPECT_EQ(status, OK); } else { - EXPECT_EQ(status, DB_ERROR); + EXPECT_EQ(status, ALREADY_SET); } status = g_nbObserverDelegate->RegisterObserver(KEY_1, OBSERVER_CHANGES_NATIVE | OBSERVER_CHANGES_FOREIGN, &observerSync); if (opCnt == NB_OPERATION_CNT_START) { EXPECT_EQ(status, OK); } else { - EXPECT_EQ(status, DB_ERROR); + EXPECT_EQ(status, ALREADY_SET); } } @@ -1346,7 +1346,7 @@ HWTEST_F(DistributeddbNbObserverTest, Pressure008, TestSize.Level1) if (opCnt == NB_OPERATION_CNT_START) { EXPECT_EQ(status, OK); } else { - EXPECT_EQ(status, DB_ERROR); + EXPECT_EQ(status, ALREADY_SET); } } @@ -1435,7 +1435,7 @@ HWTEST_F(DistributeddbNbObserverTest, Pressure009, TestSize.Level1) if (opCnt == NB_OPERATION_CNT_START) { EXPECT_EQ(status, OK); } else { - EXPECT_EQ(status, DB_ERROR); + EXPECT_EQ(status, ALREADY_SET); } } diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_tools_unit_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_tools_unit_test.cpp index 5f7668e3..48999d1c 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_tools_unit_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/common/distributeddb_tools_unit_test.cpp @@ -1249,7 +1249,7 @@ int RelationalTestUtils::GetMetaData(sqlite3 *db, const DistributedDB::Key &key, return -E_INVALID_ARGS; } - std::string sql = "SELECT value FROM " + DBConstant::RELATIONAL_PREFIX + "metadata WHERE key = ?;"; + std::string sql = "SELECT value FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + "metadata WHERE key = ?;"; sqlite3_stmt *stmt = nullptr; int errCode = SQLiteUtils::GetStatement(db, sql, stmt); if (errCode != E_OK) { @@ -1275,7 +1275,8 @@ int RelationalTestUtils::SetMetaData(sqlite3 *db, const DistributedDB::Key &key, return -E_INVALID_ARGS; } - std::string sql = "INSERT OR REPLACE INTO " + DBConstant::RELATIONAL_PREFIX + "metadata VALUES (?, ?);"; + std::string sql = "INSERT OR REPLACE INTO " + std::string(DBConstant::RELATIONAL_PREFIX) + + "metadata VALUES (?, ?);"; sqlite3_stmt *stmt = nullptr; int errCode = SQLiteUtils::GetStatement(db, sql, stmt); if (errCode != E_OK) { diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/adapter_stub.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/adapter_stub.cpp index e4694550..c25e42d4 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/adapter_stub.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/adapter_stub.cpp @@ -254,7 +254,7 @@ void AdapterStub::SimulateSendRetry(const std::string &dstTarget) targetRetrySet_.insert(dstTarget); } -void AdapterStub::SimulateSendRetryClear(const std::string &dstTarget) +void AdapterStub::SimulateSendRetryClear(const std::string &dstTarget, int softBusErrCode) { { std::lock_guard retryLockGuard(retryMutex_); @@ -265,7 +265,7 @@ void AdapterStub::SimulateSendRetryClear(const std::string &dstTarget) } std::lock_guard onSendableLockGuard(onSendableMutex_); if (onSendableHandle_) { - onSendableHandle_(dstTarget); + onSendableHandle_(dstTarget, softBusErrCode); } } diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/adapter_stub.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/adapter_stub.h index 9dc785f0..1dc6839f 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/adapter_stub.h +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/adapter_stub.h @@ -67,7 +67,7 @@ public: void SimulateSendBlockClear(); void SimulateSendRetry(const std::string &dstTarget); - void SimulateSendRetryClear(const std::string &dstTarget); + void SimulateSendRetryClear(const std::string &dstTarget, int softBusErrCode = E_OK); void SimulateSendPartialLoss(); void SimulateSendPartialLossClear(); diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_deep_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_deep_test.cpp index 484e8d89..95d82774 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_deep_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_deep_test.cpp @@ -964,4 +964,54 @@ HWTEST_F(DistributedDBCommunicatorDeepTest, NetworkAdapter007, TestSize.Level1) DeviceInfos deviceInfos; onDataReceive(deviceInfos, data.data(), 1u); EXPECT_EQ(callByteReceiveCount, 0); -} \ No newline at end of file +} + +/** + * @tc.name: RetrySendExceededLimit001 + * @tc.desc: Test send result when the number of retry times exceeds the limit + * @tc.type: FUNC + * @tc.require: + * @tc.author: suyue + */ +HWTEST_F(DistributedDBCommunicatorDeepTest, RetrySendExceededLimit001, TestSize.Level2) +{ + /** + * @tc.steps: step1. connect device A with device B and fork SendBytes + * @tc.expected: step1. operation OK + */ + AdapterStub::ConnectAdapterStub(g_envDeviceA.adapterHandle, g_envDeviceB.adapterHandle); + std::atomic count = 0; + g_envDeviceA.adapterHandle->ForkSendBytes([&count]() { + count++; + return -E_WAIT_RETRY; + }); + + /** + * @tc.steps: step2. the number of retry times for device A to send a message exceeds the limit + * @tc.expected: step2. sendResult fail + */ + std::vector> sendResult; + auto sendResultNotifier = [&sendResult](int result, bool isDirectEnd) { + sendResult.push_back(std::pair(result, isDirectEnd)); + }; + const uint32_t dataLength = 13 * 1024 * 1024; // 13 MB, 1024 is scale + Message *sendMsg = BuildRegedGiantMessage(dataLength); + ASSERT_NE(sendMsg, nullptr); + SendConfig conf = {false, false, 0}; + int errCode = g_commAB->SendMessage(DEVICE_NAME_B, sendMsg, conf, sendResultNotifier); + EXPECT_EQ(errCode, E_OK); + std::this_thread::sleep_for(std::chrono::seconds(1)); // Wait 1s to make sure send done + g_envDeviceA.adapterHandle->SimulateSendRetry(DEVICE_NAME_B); + g_envDeviceA.adapterHandle->SimulateSendRetryClear(DEVICE_NAME_B, -E_BASE); + int reTryTimes = 5; + while ((count < 4) && (reTryTimes > 0)) { // Wait to make sure retry exceeds the limit + std::this_thread::sleep_for(std::chrono::seconds(3)); + reTryTimes--; + } + ASSERT_EQ(sendResult.size(), static_cast(1)); // only one callback result notification + EXPECT_EQ(sendResult[0].first, -E_BASE); // index 0 retry fail + EXPECT_EQ(sendResult[0].second, false); + + g_envDeviceA.adapterHandle->ForkSendBytes(nullptr); + AdapterStub::DisconnectAdapterStub(g_envDeviceA.adapterHandle, g_envDeviceB.adapterHandle); +} diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_send_receive_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_send_receive_test.cpp index ea0d11a2..5b066152 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_send_receive_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/communicator/distributeddb_communicator_send_receive_test.cpp @@ -578,7 +578,7 @@ HWTEST_F(DistributedDBCommunicatorSendReceiveTest, SendResultNotify001, TestSize { // preset std::vector sendResult; - auto sendResultNotifier = [&sendResult](int result) { + auto sendResultNotifier = [&sendResult](int result, bool isDirectEnd) { sendResult.push_back(result); }; 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 7448fdf7..97d452cb 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 @@ -406,7 +406,7 @@ namespace { int errCode = SQLiteUtils::BindBlobToStatement(bindStmt, 1, key, false); return errCode; }; - std::string sql = "select value from " + DBConstant::RELATIONAL_PREFIX + "metadata where key = ?;"; + std::string sql = "select value from " + std::string(DBConstant::RELATIONAL_PREFIX) + "metadata where key = ?;"; int errCode = RelationalTestUtils::ExecSql(db, sql, bindCallback, [&count] (sqlite3_stmt *stmt) { std::string schemaStr; std::vector value; diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_relational_ext_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_relational_ext_test.cpp index d2ed5943..bb08417a 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 @@ -263,7 +263,7 @@ void InsertTriggerTest(DistributedDB::TableSyncType tableSyncType) * @tc.steps:step3. select data from log table. * @tc.expected: step3. return ok. */ - sql = "select * from " + DBConstant::RELATIONAL_PREFIX + tableName + "_log;"; + sql = "select * from " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName + "_log;"; uint64_t curTime = 0; int errCode = GetCurrentSysTimeIn100Ns(curTime); EXPECT_EQ(errCode, E_OK); @@ -411,7 +411,7 @@ void UpdateTriggerTest(bool primaryKeyIsRowId) * @tc.steps:step4. select data from log table. * @tc.expected: step4. return ok. */ - sql = "select * from " + DBConstant::RELATIONAL_PREFIX + tableName + "_log;"; + sql = "select * from " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName + "_log;"; uint64_t curTime = 0; int errCode = GetCurrentSysTimeIn100Ns(curTime); EXPECT_EQ(errCode, E_OK); @@ -509,7 +509,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, DeleteTriggerTest001, Te * @tc.steps:step4. select data from log table. * @tc.expected: step4. return ok. */ - sql = "select * from " + DBConstant::RELATIONAL_PREFIX + tableName + "_log;"; + sql = "select * from " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName + "_log;"; uint64_t curTime = 0; int errCode = GetCurrentSysTimeIn100Ns(curTime); EXPECT_EQ(errCode, E_OK); @@ -982,13 +982,14 @@ void InitLogicDeleteData(sqlite3 *&db, const std::string &tableName, uint64_t nu std::string sql = "insert or replace into " + tableName + " VALUES('" + std::to_string(i) + "', 'zhangsan');"; EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); } - std::string sql = "update " + DBConstant::RELATIONAL_PREFIX + tableName + "_log" + " SET flag = flag | 0x08"; + std::string sql = "update " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName + "_log" + + " SET flag = flag | 0x08"; EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); } void CheckLogicDeleteData(sqlite3 *&db, const std::string &tableName, uint64_t expectNum) { - std::string sql = "select count(*) from " + DBConstant::RELATIONAL_PREFIX + tableName + "_log" + std::string sql = "select count(*) from " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName + "_log" " where flag&0x08=0x08 and flag&0x01=0"; sqlite3_stmt *stmt = nullptr; EXPECT_EQ(SQLiteUtils::GetStatement(db, sql, stmt), E_OK); 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 788c9cdf..40cdbc7e 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 @@ -377,7 +377,9 @@ namespace { void DistributedDBCloudInterfacesSetCloudSchemaTest::CloseDb() { - g_delegate->UnRegisterObserver(g_observer); + if (g_delegate != nullptr) { + g_delegate->UnRegisterObserver(g_observer); + } delete g_observer; g_observer = nullptr; g_virtualCloudDb = nullptr; @@ -2163,7 +2165,7 @@ namespace { /** * @tc.name: SharedTableSync019 - * @tc.desc: Test falg_only has notify. + * @tc.desc: Test flag_only has notify. * @tc.type: FUNC * @tc.require: * @tc.author: wangxiangdong diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_database_rd_kernel_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_database_rd_kernel_test.cpp index f86972bc..a6c0eb51 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_database_rd_kernel_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_database_rd_kernel_test.cpp @@ -884,4 +884,4 @@ HWTEST_F(DistributedDBInterfacesDatabaseRdKernelTest, DataInterceptor1, TestSize g_kvNbDelegatePtr = nullptr; EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK); } -#endif // USE_RD_KERNEL \ No newline at end of file +#endif // USE_RD_KERNEL diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_extend_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_extend_test.cpp index 36f91fa1..1e1ad17a 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_extend_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_nb_delegate_extend_test.cpp @@ -285,6 +285,42 @@ HWTEST_F(DistributedDBInterfacesNBDelegateExtendTest, TimeChangeWithCloseStoreTe g_kvNbDelegatePtr = nullptr; EXPECT_EQ(g_mgr.DeleteKvStore("TimeChangeWithCloseStoreTest003"), OK); } + +/** + * @tc.name: TimeChangeWithDataChangeTest001 + * @tc.desc: Test change data and change time + * @tc.type: FUNC + * @tc.require: + * @tc.author: liaoyonghuang + */ +HWTEST_F(DistributedDBInterfacesNBDelegateExtendTest, TimeChangeWithDataChangeTest001, TestSize.Level0) +{ + /** + * @tc.steps:step1. Create local database. + * @tc.expected: step1. Returns a non-null kvstore. + */ + KvStoreNbDelegate::Option option; + option.localOnly = true; + g_mgr.GetKvStore("TimeChangeWithDataChangeTest001", option, g_kvNbDelegateCallback); + ASSERT_TRUE(g_kvNbDelegatePtr != nullptr); + EXPECT_TRUE(g_kvDelegateStatus == OK); + /** + * @tc.steps:step2. Set 100s time offset, put{k1, v1}. Then Set 0s time offset, put {k1, v2}. + * @tc.expected: step2. Get {k1, v2} form DB. + */ + OS::SetOffsetBySecond(100); // 100 : fake system time change + g_kvNbDelegatePtr->Put(KEY_1, VALUE_1); + OS::SetOffsetBySecond(0); + g_kvNbDelegatePtr->Put(KEY_1, VALUE_2); + Value expectValue = VALUE_2; + Value actualValue; + g_kvNbDelegatePtr->Get(KEY_1, actualValue); + EXPECT_EQ(expectValue, actualValue); + + EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK); + g_kvNbDelegatePtr = nullptr; + EXPECT_EQ(g_mgr.DeleteKvStore("TimeChangeWithDataChangeTest001"), OK); +} #endif // DB_DEBUG_ENV /** @@ -889,6 +925,46 @@ HWTEST_F(DistributedDBInterfacesNBDelegateExtendTest, SyncRangeQuery001, TestSiz EXPECT_EQ(mgr.DeleteKvStore(STORE_ID_1), OK); } +#ifndef USE_RD_KERNEL +/** + * @tc.name: InvalidOption001 + * @tc.desc: Test get kv store use invalid options info func with rd, need execute in manual. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhujinlin + */ +HWTEST_F(DistributedDBInterfacesNBDelegateExtendTest, InvalidOption001, TestSize.Level3) +{ + /** + * @tc.steps:step1. Get the nb delegate. + * @tc.expected: step1. Get results OK and non-null delegate. + */ + KvStoreNbDelegate::Option option = {true, false, false}; + option.storageEngineType = GAUSSDB_RD; + option.rdconfig.pageSize = 64u; + option.rdconfig.cacheSize = 4u * 1024u * 1024u; + option.rdconfig.type = HASH; + g_mgr.GetKvStore("InvalidOption001", option, g_kvNbDelegateCallback); + ASSERT_EQ(g_kvNbDelegatePtr, nullptr); + EXPECT_EQ(g_kvDelegateStatus, INVALID_ARGS); + /** + * @tc.steps:step2. Get the nb delegate. + * @tc.expected: step2. Get results OK and non-null delegate. + */ + option.rdconfig.cacheSize = (4u * 1024u * 1024u) - 64u; + g_mgr.GetKvStore("InvalidOption001", option, g_kvNbDelegateCallback); + ASSERT_NE(g_kvNbDelegatePtr, nullptr); + EXPECT_EQ(g_kvDelegateStatus, OK); + /** + * @tc.steps:step3. Close and delete KV store + * @tc.expected: step3. Returns OK. + */ + g_mgr.CloseKvStore(g_kvNbDelegatePtr); + EXPECT_EQ(g_mgr.DeleteKvStore("InvalidOption001"), OK); + g_kvNbDelegatePtr = nullptr; +} +#endif + /** * @tc.name: OptionValidCheck001 * @tc.desc: test validation of option mode 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 047c3b47..9eb5ac60 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 @@ -484,6 +484,189 @@ HWTEST_F(DistributedDBInterfacesNBDelegateLocalBatchTest, SingleVerPutLocalBatch g_kvNbDelegatePtr = nullptr; } +#ifndef LOW_LEVEL_MEM_DEV +/** + * @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; +} +#endif // LOW_LEVEL_MEM_DEV + /** * @tc.name: SingleVerDeleteLocalBatch001 * @tc.desc: Check for illegal parameters. @@ -655,6 +838,152 @@ HWTEST_F(DistributedDBInterfacesNBDelegateLocalBatchTest, SingleVerDeleteLocalBa g_kvNbDelegatePtr = nullptr; } +#ifndef LOW_LEVEL_MEM_DEV +/** + * @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; +} +#endif // LOW_LEVEL_MEM_DEV + /** * @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 68d93661..57af4088 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 @@ -1174,6 +1174,189 @@ static void CreatEntrys(int recordSize, vector &keys, vector &values } } +#ifndef LOW_LEVEL_MEM_DEV +/** + * @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; +} +#endif // LOW_LEVEL_MEM_DEV + /** * @tc.name: SingleVerDeleteBatch001 * @tc.desc: Check for illegal parameters. @@ -1348,6 +1531,152 @@ HWTEST_F(DistributedDBInterfacesNBDelegateTest, SingleVerDeleteBatch002, TestSiz g_kvNbDelegatePtr = nullptr; } +#ifndef LOW_LEVEL_MEM_DEV +/** + * @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; +} +#endif // LOW_LEVEL_MEM_DEV + /** * @tc.name: SingleVerDeleteBatch007 * @tc.desc: Check normal delete batch while conn is nullptr. diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_query_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_query_test.cpp index 489bb987..6935d672 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_query_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_query_test.cpp @@ -281,4 +281,4 @@ HWTEST_F(DistributedDBInterfacesQueryTest, Query004, TestSize.Level1) const std::string tableName3 = "test3"; expression1.From(tableName3); EXPECT_EQ(expression1.GetExpressionStatus(), -E_NOT_SUPPORT); -} \ 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 2e9356fa..95ea6b0a 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 @@ -505,7 +505,8 @@ HWTEST_F(DistributedDBInterfacesRelationalSyncTest, UpdatePrimaryKeyTest001, Tes std::string updateSql = "update student_1 set id = 1002 where name = 'xue';"; EXPECT_EQ(RelationalTestUtils::ExecSql(db, updateSql), SQLITE_OK); - int cnt = RelationalTestUtils::CheckTableRecords(db, DBConstant::RELATIONAL_PREFIX + "student_1" + "_log"); + int cnt = RelationalTestUtils::CheckTableRecords(db, std::string(DBConstant::RELATIONAL_PREFIX) + "student_1" + + "_log"); EXPECT_EQ(cnt, 2); } 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 4256c99c..77b8e9fb 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 @@ -1988,4 +1988,46 @@ HWTEST_F(DistributedDBInterfacesRelationalTest, CreateDistributedTableTest005, T EXPECT_EQ(g_mgr.CloseStore(delegate), OK); delegate = nullptr; } + +/** + * @tc.name: CloudRelationalStoreTest006 + * @tc.desc: Test create distributed table and execute transaction concurrently + * @tc.type: FUNC + * @tc.require: + * @tc.author: liaoyonghuang + */ +HWTEST_F(DistributedDBInterfacesRelationalTest, CreateDistributedTableTest006, TestSize.Level0) +{ + /** + * @tc.steps:step1. Prepare db file + * @tc.expected: step1. Return OK. + */ + sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX); + ASSERT_NE(db, nullptr); + EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK); + EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_NO_UNIQUE), SQLITE_OK); + EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); + /** + * @tc.steps:step2. open relational store + * @tc.expected: step2. Return OK. + */ + RelationalStoreDelegate *delegate = nullptr; + DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate); + EXPECT_EQ(status, OK); + ASSERT_NE(delegate, nullptr); + /** + * @tc.steps:step3. create distributed table with CLOUD_COOPERATION after between a transaction + * @tc.expected: step3. Return OK. + */ + DistributedDB::SqlCondition sqlCondition; + std::vector records = {}; + sqlCondition.sql = "BEGIN;"; + EXPECT_EQ(delegate->ExecuteSql(sqlCondition, records), E_OK); + status = delegate->CreateDistributedTable("sync_data", DistributedDB::CLOUD_COOPERATION); + EXPECT_EQ(status, OK); + sqlCondition.sql = "COMMIT;"; + EXPECT_EQ(delegate->ExecuteSql(sqlCondition, records), E_OK); + status = g_mgr.CloseStore(delegate); + EXPECT_EQ(status, OK); +} } 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 9553ba83..f8d69097 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 @@ -142,8 +142,8 @@ namespace { void CheckExtendAndCursor(uint64_t num, int start, const std::string &tableName, bool addNum = true) { int index = 0; - string querySql = "select extend_field, cursor from " + DBConstant::RELATIONAL_PREFIX + tableName + "_log" + - " where data_key <= " + std::to_string(num); + string querySql = "select extend_field, cursor from " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName + + "_log" + " where data_key <= " + std::to_string(num); sqlite3_stmt *stmt = nullptr; EXPECT_EQ(SQLiteUtils::GetStatement(g_db, querySql, stmt), E_OK); while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) { @@ -213,8 +213,8 @@ namespace { * @tc.expected: step2. Return OK. */ OpenStore(); - sql = "select count(*) from sqlite_master where name = '" + DBConstant::RELATIONAL_PREFIX + TABLE_NAME2 + - "_log'"; + sql = "select count(*) from sqlite_master where name = '" + std::string(DBConstant::RELATIONAL_PREFIX) + + TABLE_NAME2 + "_log'"; EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, reinterpret_cast(0), nullptr), SQLITE_OK); @@ -224,7 +224,7 @@ namespace { */ const Key schemaKey(DBConstant::RELATIONAL_TRACKER_SCHEMA_KEY.begin(), DBConstant::RELATIONAL_TRACKER_SCHEMA_KEY.end()); - sql = "SELECT value FROM " + DBConstant::RELATIONAL_PREFIX + "metadata WHERE key=?;"; + sql = "SELECT value FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + "metadata WHERE key=?;"; sqlite3_stmt *stmt = nullptr; EXPECT_EQ(SQLiteUtils::GetStatement(g_db, sql, stmt), E_OK); EXPECT_EQ(SQLiteUtils::BindBlobToStatement(stmt, 1, schemaKey, false), E_OK); @@ -563,8 +563,8 @@ HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest008, uint64_t updateNum = 2; BatchUpdateTableName2Data(updateNum, LOCAL_TABLE_TRACKER_NAME_SET3); int index = 0; - string querySql = "select extend_field, cursor from " + DBConstant::RELATIONAL_PREFIX + TABLE_NAME2 + "_log" + - " where data_key <= " + std::to_string(updateNum); + string querySql = "select extend_field, cursor from " + std::string(DBConstant::RELATIONAL_PREFIX) + TABLE_NAME2 + + "_log" + " where data_key <= " + std::to_string(updateNum); sqlite3_stmt *stmt = nullptr; EXPECT_EQ(SQLiteUtils::GetStatement(g_db, querySql, stmt), E_OK); while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) { @@ -887,7 +887,7 @@ HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest015, */ TrackerSchema schema = g_normalSchema1; EXPECT_EQ(g_delegate->SetTrackerTable(schema), WITH_INVENTORY_DATA); - string querySql = "select extend_field from " + DBConstant::RELATIONAL_PREFIX + TABLE_NAME2 + "_log" + + string querySql = "select extend_field from " + std::string(DBConstant::RELATIONAL_PREFIX) + TABLE_NAME2 + "_log" + " where data_key = 15;"; sqlite3_stmt *stmt = nullptr; EXPECT_EQ(SQLiteUtils::GetStatement(g_db, querySql, stmt), E_OK); @@ -1085,10 +1085,10 @@ HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest019, * @tc.expected: step4. Return OK. */ EXPECT_EQ(g_delegate->CleanTrackerData(TABLE_NAME2, num + (num / HALF)), OK); - std::string sql = "select count(*) from " + DBConstant::RELATIONAL_PREFIX + TABLE_NAME2 + "_log" + + std::string sql = "select count(*) from " + std::string(DBConstant::RELATIONAL_PREFIX) + TABLE_NAME2 + "_log" + " where extend_field is NULL;"; EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, - reinterpret_cast(num / HALF), nullptr), SQLITE_OK); + reinterpret_cast(0), nullptr), SQLITE_OK); CloseStore(); } @@ -1125,8 +1125,8 @@ HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest020, * @tc.steps:step3. check the extend_field and cursor is null * @tc.expected: step3. Return OK. */ - sql = "select count(*) from " + DBConstant::RELATIONAL_PREFIX + TABLE_NAME2 + "_log where extend_field is NULL " + - " AND cursor is NULL"; + sql = "select count(*) from " + std::string(DBConstant::RELATIONAL_PREFIX) + TABLE_NAME2 + + "_log where extend_field is NULL " + " AND cursor is NULL"; EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, reinterpret_cast(0), nullptr), SQLITE_OK); @@ -1136,8 +1136,8 @@ HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest020, */ schema.extendColName = EXTEND_COL_NAME3; EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK); - sql = "select count(*) from " + DBConstant::RELATIONAL_PREFIX + TABLE_NAME2 + "_log where extend_field is NULL " + - " AND cursor is NULL"; + sql = "select count(*) from " + std::string(DBConstant::RELATIONAL_PREFIX) + TABLE_NAME2 + + "_log where extend_field is NULL " + " AND cursor is NULL"; EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, reinterpret_cast(0), nullptr), SQLITE_OK); CloseStore(); @@ -1203,7 +1203,7 @@ HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest023, * @tc.steps:step3. query cursor * @tc.expected: step3. Return OK. */ - string querySql = "select cursor from " + DBConstant::RELATIONAL_PREFIX + TABLE_NAME2 + "_log"; + string querySql = "select cursor from " + std::string(DBConstant::RELATIONAL_PREFIX) + TABLE_NAME2 + "_log"; sqlite3_stmt *stmt = nullptr; int index = 20; EXPECT_EQ(SQLiteUtils::GetStatement(g_db, querySql, stmt), E_OK); @@ -1236,6 +1236,42 @@ HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest024, CloseStore(); } +/** + * @tc.name: TrackerTableTest025 + * @tc.desc: Test CreateDistributedTable after insert data and set tracker table + * @tc.type: FUNC + * @tc.require: + * @tc.author: lijun + */ +HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest025, TestSize.Level0) +{ + CreateMultiTable(); + OpenStore(); + uint64_t num = 10; + + /** + * @tc.steps:step1. insert data + * @tc.expected: step1. OK. + */ + BatchInsertTableName2Data(num); + TrackerSchema schema = g_normalSchema1; + + /** + * @tc.steps:step2. SetTrackerTable on table2 + * @tc.expected: step2. Return WITH_INVENTORY_DATA. + */ + EXPECT_EQ(g_delegate->SetTrackerTable(schema), WITH_INVENTORY_DATA); + + /** + * @tc.steps:step3. check cursor before and after CreateDistributedTable + * @tc.expected: step3. Cursor is no change. + */ + CheckExtendAndCursor(num, -num); + EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK); + CheckExtendAndCursor(num, -num); + CloseStore(); +} + /** * @tc.name: ExecuteSql001 * @tc.desc: Test ExecuteSql with invalid param @@ -1432,7 +1468,8 @@ HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, ExecuteSql004, TestS SqlCondition condition; std::vector records; std::string querySql = "select " + TABLE_NAME2 + ".* from " + TABLE_NAME2 + " join "; - querySql += DBConstant::RELATIONAL_PREFIX + TABLE_NAME2 + "_log" + " as a on " + TABLE_NAME2 + "._rowid_ = "; + querySql += std::string(DBConstant::RELATIONAL_PREFIX) + TABLE_NAME2 + "_log" + " as a on " + TABLE_NAME2 + + "._rowid_ = "; querySql += "a.data_key where a.cursor > ?;"; condition.sql = querySql; condition.bindArgs = {begin}; @@ -1894,7 +1931,7 @@ HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest029, * @tc.expected: step3. Return OK. */ schema.isForceUpgrade = true; - EXPECT_EQ(g_delegate->SetTrackerTable(schema), WITH_INVENTORY_DATA); + EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK); CloseStore(); } @@ -1929,13 +1966,127 @@ HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest030, * @tc.expected: step3. Return OK. */ EXPECT_EQ(g_delegate->CleanTrackerData(TABLE_NAME2, num + (num / HALF)), OK); - std::string sql = "select count(*) from " + DBConstant::RELATIONAL_PREFIX + TABLE_NAME2 + "_log" + + std::string sql = "select count(*) from " + std::string(DBConstant::RELATIONAL_PREFIX) + TABLE_NAME2 + "_log" + " where extend_field is NULL;"; EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, reinterpret_cast(num), nullptr), SQLITE_OK); CloseStore(); } +/** + * @tc.name: TrackerTableTest031 + * @tc.desc: Test set tracker table with trackerColNames emtpy + * @tc.type: FUNC + * @tc.require: + * @tc.author: luoguo + */ +HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest031, TestSize.Level0) +{ + CreateMultiTable(); + OpenStore(); + + /** + * @tc.steps:step1. create distributed table and set data. + * @tc.expected: step1. Return OK. + */ + uint64_t num = 10; + BatchInsertTableName2Data(num); + EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), OK); + + /** + * @tc.steps:step2. set tracker table + * @tc.expected: step2. Return OK. + */ + TrackerSchema schema; + schema.tableName = TABLE_NAME2; + schema.extendColName = EXTEND_COL_NAME2; + schema.trackerColNames = {}; + schema.isForceUpgrade = false; + schema.isTrackAction = true; + EXPECT_EQ(g_delegate->SetTrackerTable(schema), WITH_INVENTORY_DATA); + + /** + * @tc.steps:step3. check cursor count. + * @tc.expected: step3. Return OK. + */ + std::string sql = "select count(*) from " + std::string(DBConstant::RELATIONAL_PREFIX) + TABLE_NAME2 + "_log" + + " where extend_field is NULL;"; + EXPECT_EQ(sqlite3_exec( + g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, reinterpret_cast(0u), nullptr), + SQLITE_OK); + CloseStore(); +} + +/** + * @tc.name: TrackerTableTest032 + * @tc.desc: Test after create distributed table cursor increace + * @tc.type: FUNC + * @tc.require: + * @tc.author: tankaisheng + */ +HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest032, TestSize.Level0) +{ + CreateMultiTable(); + OpenStore(); + + /** + * @tc.steps:step1. create distributed table and set data. + * @tc.expected: step1. Return OK. + */ + uint64_t num = 10; + BatchInsertTableName2Data(num); + EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), OK); + + /** + * @tc.steps:step2. check cursor count. + * @tc.expected: step2. Return OK. + */ + std::string sql = "select count(*) from " + std::string(DBConstant::RELATIONAL_PREFIX) + TABLE_NAME2 + "_log" + + " where cursor = 10;"; + EXPECT_EQ(sqlite3_exec( + g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, reinterpret_cast(1u), nullptr), + SQLITE_OK); + CloseStore(); +} + +/** + * @tc.name: TrackerTableTest033 + * @tc.desc: Test CreateDistributedTable after insert data and set tracker table + * @tc.type: FUNC + * @tc.require: + * @tc.author: luoguo + */ +HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest033, TestSize.Level0) +{ + CreateMultiTable(); + OpenStore(); + uint64_t num = 10; + + /** + * @tc.steps:step1. insert data + * @tc.expected: step1. OK. + */ + BatchInsertTableName2Data(num); + TrackerSchema schema = g_normalSchema1; + + /** + * @tc.steps:step2. SetTrackerTable on table2 and set status to 2. + * @tc.expected: step2. ok. + */ + EXPECT_EQ(g_delegate->SetTrackerTable(schema), WITH_INVENTORY_DATA); + std::string sql = "UPDATE " + std::string(DBConstant::RELATIONAL_PREFIX) + TABLE_NAME2 + "_log SET status = 2;"; + EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK); + /** + * @tc.steps:step3. check status after CreateDistributedTable + * @tc.expected: step3. status is 0. + */ + EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK); + sql = "select count(*) from " + std::string(DBConstant::RELATIONAL_PREFIX) + TABLE_NAME2 + "_log where status = 0;"; + EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, + reinterpret_cast(num), nullptr), SQLITE_OK); + CloseStore(); +} + /** * @tc.name: SchemaStrTest001 * @tc.desc: Test open reOpen stroe when schemaStr is empty 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 00607b54..4e218656 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 @@ -85,7 +85,7 @@ void BlockSync(const Query &query, RelationalStoreDelegate *delegate, SyncMode s LOGW("end call sync"); } -class DistributedDBCloudAssetsOperationSyncTest : public testing::Test { +class DistributedDBCloudAssetsOperationSyncTest : public testing::Test { public: static void SetUpTestCase(); static void TearDownTestCase(); @@ -100,6 +100,7 @@ protected: const Assets &templateAsset = {}); void UpdateLocalTableRecord(const std::string &tableName, int64_t begin, int64_t count, size_t assetCount = 2u, bool updateAssets = true); + void UpdateLocalAssetRecord(const std::string &tableName, int64_t begin, int64_t count); void CheckAssetsCount(const std::vector &expectCount, bool checkAsset = false); void UpdateCloudTableRecord(int64_t begin, int64_t count, bool assetIsNull); void ForkDownloadAndRemoveAsset(DBStatus removeStatus, int &downLoadCount, int &removeCount); @@ -107,7 +108,15 @@ protected: void InsertCloudAssetData(const std::string &assetHash); void PrepareForAssetOperation010(); void UpdateAssetWhenSyncUpload(); - std::vector GetAssets(const std::string &baseName, const Assets &templateAsset, size_t assetCount); + DBStatus InsertRecordToCloud(const std::vector &record); + void PrepareDataInCloud(); + void LocalAssetRemoveTest(); + + static std::vector GetAssets(const std::string &baseName, const Assets &templateAsset, size_t assetCount); + static std::vector GenerateAssetsRecords(const std::map &colType, + const Asset &templateAsset, int assetsCount, int rowCount); + static Asset GenerateAsset(const Asset &templateAsset, int id); + static Assets GenerateAssets(const Asset &templateAsset, int id, int assetsCount); std::string testDir_; std::string storePath_; sqlite3 *db_ = nullptr; @@ -263,6 +272,35 @@ void DistributedDBCloudAssetsOperationSyncTest::UpdateLocalTableRecord(const std } } +DBStatus DistributedDBCloudAssetsOperationSyncTest::InsertRecordToCloud(const std::vector &record) +{ + std::vector extend; + for (size_t i = 0; i < record.size(); ++i) { + VBucket log; + Timestamp now = TimeHelper::GetSysCurrentTime(); + 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); + extend.push_back(log); + } + std::vector copyRecord = record; + return virtualCloudDb_->BatchInsert(tableName_, std::move(copyRecord), extend); +} + +void DistributedDBCloudAssetsOperationSyncTest::PrepareDataInCloud() +{ + std::map colType; + colType["asset"] = TYPE_INDEX; + colType["assets"] = TYPE_INDEX; + Asset templateAsset = g_localAsset; + const int assetsCount = 10; + const int rowCount = 200; + auto recordAssets = GenerateAssetsRecords(colType, templateAsset, assetsCount, rowCount); + EXPECT_EQ(InsertRecordToCloud(recordAssets), OK); +} + std::vector DistributedDBCloudAssetsOperationSyncTest::GetAssets(const std::string &baseName, const Assets &templateAsset, size_t assetCount) { @@ -366,6 +404,43 @@ void DistributedDBCloudAssetsOperationSyncTest::ForkDownloadAndRemoveAsset(DBSta }); } +std::vector DistributedDBCloudAssetsOperationSyncTest::GenerateAssetsRecords( + const std::map &colType, const Asset &templateAsset, int assetsCount, int rowCount) +{ + std::vector res; + for (int i = 0; i < rowCount; ++i) { + VBucket record; + record["id"] = std::to_string(i); + for (const auto &[col, type] : colType) { + if (type == TYPE_INDEX) { + record[col] = GenerateAsset(templateAsset, i); + } else if (type == TYPE_INDEX) { + record[col] = GenerateAssets(templateAsset, i, assetsCount); + } + } + res.push_back(record); + } + return res; +} + +Asset DistributedDBCloudAssetsOperationSyncTest::GenerateAsset(const Asset &templateAsset, int id) +{ + Asset res = templateAsset; + res.name.append("_").append(std::to_string(id)); + res.hash.append("_").append(std::to_string(id)); + return res; +} + +Assets DistributedDBCloudAssetsOperationSyncTest::GenerateAssets(const Asset &templateAsset, int id, int assetsCount) +{ + Assets assets; + auto baseAsset = GenerateAsset(templateAsset, id); + for (int i = 0; i < assetsCount; ++i) { + assets.push_back(GenerateAsset(baseAsset, i)); + } + return assets; +} + /** * @tc.name: SyncWithAssetOperation001 * @tc.desc: Delete Assets When Download @@ -471,14 +546,7 @@ HWTEST_F(DistributedDBCloudAssetsOperationSyncTest, SyncWithAssetOperation003, T SQLiteUtils::ResetStatement(stmt, true, errCode); } -/** - * @tc.name: SyncWithAssetOperation004 - * @tc.desc: Download Assets When local assets was removed - * @tc.type: FUNC - * @tc.require: - * @tc.author: zhangqiquan - */ -HWTEST_F(DistributedDBCloudAssetsOperationSyncTest, SyncWithAssetOperation004, TestSize.Level0) +void DistributedDBCloudAssetsOperationSyncTest::LocalAssetRemoveTest() { const int actualCount = 5; // 5 record InsertUserTableRecord(tableName_, 0, actualCount); @@ -488,7 +556,7 @@ HWTEST_F(DistributedDBCloudAssetsOperationSyncTest, SyncWithAssetOperation004, T int removeCount = 0; ForkDownloadAndRemoveAsset(DB_ERROR, downLoadCount, removeCount); UpdateCloudTableRecord(0, actualCount, false); - RelationalTestUtils::CloudBlockSync(query, delegate_, DBStatus::OK, DBStatus::REMOTE_ASSETS_FAIL); + RelationalTestUtils::CloudBlockSync(query, delegate_, DBStatus::OK, DBStatus::REMOVE_ASSETS_FAIL); EXPECT_EQ(downLoadCount, 5); // local asset was removed should download 5 times EXPECT_EQ(removeCount, 1); virtualAssetLoader_->ForkDownload(nullptr); @@ -498,6 +566,18 @@ HWTEST_F(DistributedDBCloudAssetsOperationSyncTest, SyncWithAssetOperation004, T CheckAssetsCount(expectCount); } +/** + * @tc.name: SyncWithAssetOperation004 + * @tc.desc: Download Assets When local assets was removed + * @tc.type: FUNC + * @tc.require: + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBCloudAssetsOperationSyncTest, SyncWithAssetOperation004, TestSize.Level0) +{ + LocalAssetRemoveTest(); +} + void DistributedDBCloudAssetsOperationSyncTest::UpdateAssetWhenSyncUpload() { string sql = "UPDATE " + tableName_ + " SET asset = ? WHERE id = '54';"; @@ -529,7 +609,7 @@ HWTEST_F(DistributedDBCloudAssetsOperationSyncTest, SyncWithAssetOperation005, T * @tc.expected: step1. ok. */ InsertUserTableRecord(tableName_, 0, 60); - + /** * @tc.steps:step2. Sync to cloud and wait in upload. * @tc.expected: step2. ok. @@ -770,7 +850,7 @@ void DistributedDBCloudAssetsOperationSyncTest::InsertCloudAssetData(const std:: data.insert_or_assign("id", "0"); data.insert_or_assign("name", "CloudTest0"); Asset asset = g_localAsset; - data.insert_or_assign("asset", "asset"); + data.insert_or_assign("asset", asset); Assets assets; std::string assetNameBegin = "Phone"; for (int j = 1; j <= g_assetsNum; ++j) { @@ -933,6 +1013,80 @@ HWTEST_F(DistributedDBCloudAssetsOperationSyncTest, SyncWithAssetOperation011, T virtualAssetLoader_->ForkDownload(nullptr); } +/** + * @tc.name: SyncWithAssetOperation012 + * @tc.desc: Batch download Assets When local assets was removed + * @tc.type: FUNC + * @tc.require: + * @tc.author: liaoyonghuang + */ +HWTEST_F(DistributedDBCloudAssetsOperationSyncTest, SyncWithAssetOperation012, TestSize.Level0) +{ + RuntimeContext::GetInstance()->SetBatchDownloadAssets(true); + LocalAssetRemoveTest(); + RuntimeContext::GetInstance()->SetBatchDownloadAssets(false); +} + +void DistributedDBCloudAssetsOperationSyncTest::UpdateLocalAssetRecord(const std::string &tableName, int64_t begin, + int64_t count) +{ + int errCode; + std::vector assetBlob; + std::vector assetsBlob; + for (int64_t i = begin; i < begin + count; ++i) { + Asset asset = g_localAsset; + asset.hash = "new_hash"; + asset.status = static_cast(AssetStatus::UPDATE); + RuntimeContext::GetInstance()->AssetToBlob(asset, assetBlob); + std::vector assets; + assets.push_back(asset); + RuntimeContext::GetInstance()->AssetsToBlob(assets, assetsBlob); + std::string sql = "UPDATE " + tableName + " SET height = '175.0', asset = ?, assets = ? where id = " + + std::to_string(i); + sqlite3_stmt *stmt = nullptr; + ASSERT_EQ(SQLiteUtils::GetStatement(db_, sql, stmt), E_OK); + ASSERT_EQ(SQLiteUtils::BindBlobToStatement(stmt, 1, assetBlob, false), E_OK); // 1st bind + ASSERT_EQ(SQLiteUtils::BindBlobToStatement(stmt, 2, assetsBlob, false), E_OK); // 2nd bind + EXPECT_EQ(SQLiteUtils::StepWithRetry(stmt), SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)); + SQLiteUtils::ResetStatement(stmt, true, errCode); + } +} + +/** + * @tc.name: SyncWithAssetOperation013 + * @tc.desc: Test device modify data and then sync cursor will not changes + * @tc.type: FUNC + * @tc.require: + * @tc.author: caihaoting + */ +HWTEST_F(DistributedDBCloudAssetsOperationSyncTest, SyncWithAssetOperation013, TestSize.Level0) +{ + /** + * @tc.steps:step1. Insert local and cloud asset data and sync. + * @tc.expected: step1. ok. + */ + InsertCloudAssetData("assetHash"); + InsertLocalAssetData("assetHash"); + Query query = Query::Select().FromTable({ tableName_ }); + BlockSync(query, delegate_); + /** + * @tc.steps:step2. modify data of asset and sync. + * @tc.expected: step2. ok. + */ + UpdateLocalAssetRecord(tableName_, 0, 1); + const int cursor = 2; + std::string sql = "SELECT cursor FROM " + DBCommon::GetLogTableName(tableName_) + " where data_key=1"; + EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, + reinterpret_cast(cursor), nullptr), SQLITE_OK); + BlockSync(query, delegate_); + /** + * @tc.steps:step3. check modified data cursor and cursor is not changed. + * @tc.expected: step3. ok. + */ + EXPECT_EQ(sqlite3_exec(db_, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, + reinterpret_cast(cursor), nullptr), SQLITE_OK); +} + /** * @tc.name: IgnoreRecord001 * @tc.desc: Download Assets When local assets was removed @@ -1009,6 +1163,31 @@ HWTEST_F(DistributedDBCloudAssetsOperationSyncTest, IgnoreRecord003, TestSize.Le RelationalTestUtils::CloudBlockSync(query, delegate_); } +/** + * @tc.name: IgnoreRecord004 + * @tc.desc: Ignore Assets When Btch Download + * @tc.type: FUNC + * @tc.require: + * @tc.author: luoguo + */ +HWTEST_F(DistributedDBCloudAssetsOperationSyncTest, IgnoreRecord004, TestSize.Level0) +{ + RuntimeContext::GetInstance()->SetBatchDownloadAssets(true); + const int actualCount = 10; + InsertUserTableRecord(tableName_, 0, actualCount); + Query query = Query::Select().FromTable({ tableName_ }); + RelationalTestUtils::CloudBlockSync(query, delegate_); + UpdateCloudTableRecord(0, actualCount, false); + + virtualAssetLoader_->SetDownloadStatus(DBStatus::CLOUD_RECORD_EXIST_CONFLICT); + RelationalTestUtils::CloudBlockSync(query, delegate_); + virtualAssetLoader_->SetDownloadStatus(DBStatus::OK); + std::vector expectCount(10, 4); + CheckAssetsCount(expectCount); + RelationalTestUtils::CloudBlockSync(query, delegate_); + RuntimeContext::GetInstance()->SetBatchDownloadAssets(false); +} + /** * @tc.name: UpsertData001 * @tc.desc: Upsert data after delete it @@ -1481,5 +1660,61 @@ HWTEST_F(DistributedDBCloudAssetsOperationSyncTest, UploadAssetsTest004, TestSiz } virtualCloudDb_->ForkUpload(nullptr); } + +/** + * @tc.name: BatchNormalDownloadAsset001 + * @tc.desc: Test batch download asset in two batch. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zqq + */ +HWTEST_F(DistributedDBCloudAssetsOperationSyncTest, BatchNormalDownloadAsset001, TestSize.Level0) +{ + RuntimeContext::GetInstance()->SetBatchDownloadAssets(true); + PrepareDataInCloud(); + + Query query = Query::Select().FromTable({ tableName_ }); + BlockSync(query, delegate_); + EXPECT_EQ(virtualAssetLoader_->GetBatchDownloadCount(), 2); // download 2 times + EXPECT_EQ(virtualAssetLoader_->GetBatchRemoveCount(), 0); // remove 0 times + virtualAssetLoader_->Reset(); + RuntimeContext::GetInstance()->SetBatchDownloadAssets(false); +} + +/** + * @tc.name: BatchAbnormalDownloadAsset001 + * @tc.desc: Test batch download asset failed. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zqq + */ +HWTEST_F(DistributedDBCloudAssetsOperationSyncTest, BatchAbnormalDownloadAsset001, TestSize.Level0) +{ + RuntimeContext::GetInstance()->SetBatchDownloadAssets(true); + PrepareDataInCloud(); + virtualAssetLoader_->ForkBatchDownload([](int rowIndex, std::map &assets) { + if (rowIndex > 50) { // 50 record failed + for (auto &asset : assets) { + for (auto &item : asset.second) { + item.status = AssetStatus::ABNORMAL; + } + } + return DB_ERROR; + } + return OK; + }); + + Query query = Query::Select().FromTable({ tableName_ }); + BlockSync(query, delegate_); + EXPECT_EQ(virtualAssetLoader_->GetBatchDownloadCount(), 1); // download 1 times + EXPECT_EQ(virtualAssetLoader_->GetBatchRemoveCount(), 0); // remove 0 times + virtualAssetLoader_->Reset(); + + virtualAssetLoader_->ForkBatchDownload(nullptr); + BlockSync(query, delegate_); + EXPECT_EQ(virtualAssetLoader_->GetBatchDownloadCount(), 2); // download 2 times + EXPECT_EQ(virtualAssetLoader_->GetBatchRemoveCount(), 0); // remove 0 times + RuntimeContext::GetInstance()->SetBatchDownloadAssets(false); +} } #endif 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 44b998c0..3401a31c 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 @@ -958,6 +958,89 @@ HWTEST_F(DistributedDBCloudCheckSyncTest, CloudSyncTest007, TestSize.Level0) virtualCloudDb_->ForkUpload(nullptr); } +/** + * @tc.name: CloudSyncTest008 + * @tc.desc: test when normal sync interrupted by priority sync, process info should be consistent + * @tc.type: FUNC + * @tc.require: + * @tc.author: suyuchen + */ +HWTEST_F(DistributedDBCloudCheckSyncTest, CloudSyncTest008, TestSize.Level0) +{ + /** + * @tc.steps: step1. insert 35 records to user table + * @tc.expected: step1. OK. + */ + const int localCount = 35; + InsertUserTableRecord(tableName_, localCount, 0); + Query query = Query::Select().FromTable({tableName_}); + + /** + * @tc.steps: step2. Set CLOUD_VERSION_CONFLICT when normal sync task upload + * @tc.expected: step2. OK. + */ + int recordIndex = 0; + virtualCloudDb_->ForkInsertConflict([&recordIndex](const std::string &tableName, VBucket &extend, VBucket &record, + vector &cloudDataVec) { + recordIndex++; + if (recordIndex == 20) { + extend[CloudDbConstant::ERROR_FIELD] = static_cast(DBStatus::CLOUD_VERSION_CONFLICT); + std::this_thread::sleep_for(std::chrono::seconds(1)); + return CLOUD_VERSION_CONFLICT; + } + return OK; + }); + + /** + * @tc.steps: step3. set callback function for normal sync + * @tc.expected: step3. OK. + */ + std::map retSyncProcess; + auto normalCallback = [&retSyncProcess](const std::map &process) { + for (const auto &item : process) { + if (item.second.process == DistributedDB::FINISHED) { + ASSERT_EQ(process.empty(), false); + auto lastProcess = process.rbegin(); + retSyncProcess = lastProcess->second.tableProcess; + } + } + }; + + /** + * @tc.steps: step4. start normal sync + * @tc.expected: step4. OK. + */ + CloudSyncOption option; + PrepareOption(option, query, false); + ASSERT_EQ(delegate_->Sync(option, normalCallback), OK); + std::thread syncThread1([&]() { + BlockSync(query, delegate_, g_actualDBStatus); + }); + + /** + * @tc.steps: step5. start priority sync + * @tc.expected: step5. OK. + */ + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + std::thread syncThread2([&]() { + BlockSync(query, delegate_, g_actualDBStatus, true); + }); + syncThread1.join(); + syncThread2.join(); + + /** + * @tc.steps: step6. Check notification of normal sync + * @tc.expected: step6. OK. + */ + ASSERT_EQ(retSyncProcess.empty(), false); + auto taskInfo = retSyncProcess.rbegin(); + ASSERT_EQ(taskInfo->second.upLoadInfo.total, 35u); + ASSERT_EQ(taskInfo->second.upLoadInfo.successCount, 35u); + ASSERT_EQ(taskInfo->second.upLoadInfo.failCount, 0u); + + virtualCloudDb_->ForkInsertConflict(nullptr); +} + /** * @tc.name: CloudSyncObserverTest001 * @tc.desc: test cloud sync multi observer 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 9670fa77..e55f1b7e 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 @@ -2449,7 +2449,7 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, CloudCursorTest001, Tes * although it is unTrackerTable * @tc.expected: step2. return ok. */ - string sql = "select cursor from " + DBConstant::RELATIONAL_PREFIX + g_tableName1 + "_log"; + string sql = "select cursor from " + std::string(DBConstant::RELATIONAL_PREFIX) + g_tableName1 + "_log"; sqlite3_stmt *stmt = nullptr; EXPECT_EQ(SQLiteUtils::GetStatement(db, sql, stmt), E_OK); int64_t index = 0; 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 17e8d222..4f26d5a2 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 @@ -707,6 +707,53 @@ HWTEST_F(DistributedDBRelationalCloudSyncableStorageTest, GetUploadCount003, Tes EXPECT_EQ(g_storageProxy->Commit(), E_OK); } +/** + * @tc.name: GetUploadCount004 + * @tc.desc: Test getUploadCount and ExecuteSql concurrently + * @tc.type: FUNC + * @tc.require: + * @tc.author: liaoyonghuang + */ +HWTEST_F(DistributedDBRelationalCloudSyncableStorageTest, GetUploadCount004, TestSize.Level1) +{ + /** + * @tc.step1: Init data + * @tc.expected: step1. return OK + */ + CreateLogTable(g_tableName); + int64_t insCount = 100; + CreateAndInitUserTable(insCount, insCount, g_localAsset); + InitLogData(0, 0, insCount, insCount, g_logTblName); + int64_t resCount = 0; + /** + * @tc.step2: GetUploadCount and ExecuteSql concurrently + * @tc.expected: step2. return OK. + */ + std::thread getUploadCountThread([&]() { + for (int i = 0; i < 100; i++) { + if (g_storageProxy->StartTransaction() == E_OK) { + EXPECT_EQ(g_storageProxy->GetUploadCount(g_tableName, g_startTime, false, resCount), E_OK); + EXPECT_EQ(resCount, insCount); + EXPECT_EQ(g_storageProxy->Commit(), E_OK); + } + } + }); + std::thread execThread([&]() { + DistributedDB::SqlCondition sqlCondition; + sqlCondition.readOnly = true; + for (int i = 0; i < 100; i++) { + std::vector records = {}; + sqlCondition.sql = "BEGIN;"; + EXPECT_EQ(g_delegate->ExecuteSql(sqlCondition, records), E_OK); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + sqlCondition.sql = "COMMIT;"; + EXPECT_EQ(g_delegate->ExecuteSql(sqlCondition, records), E_OK); + } + }); + execThread.join(); + getUploadCountThread.join(); +} + /** * @tc.name: FillCloudGid001 * @tc.desc: FillCloudGid with invalid parm @@ -1444,7 +1491,7 @@ HWTEST_F(DistributedDBRelationalCloudSyncableStorageTest, PutCloudSyncVersion001 EXPECT_EQ(g_storageProxy->Commit(), E_OK); sqlite3 *db = nullptr; ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK); - std::string querySql = "SELECT COUNT(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + + std::string querySql = "SELECT COUNT(*) FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + g_tableName + CloudDbConstant::SHARED + "_log"; EXPECT_EQ(sqlite3_exec(db, querySql.c_str(), QueryCountCallback, reinterpret_cast(2L), nullptr), SQLITE_OK); diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_get_data_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_get_data_test.cpp index 46cd05b7..0c16248e 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_get_data_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_get_data_test.cpp @@ -91,7 +91,7 @@ int GetLogData(int key, uint64_t &flag, Timestamp ×tamp, const DeviceID &de if (!device.empty()) { } const string sql = "SELECT timestamp, flag \ - FROM " + g_tableName + " as a, " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_log as b \ + FROM " + g_tableName + " as a, " + std::string(DBConstant::RELATIONAL_PREFIX) + g_tableName + "_log as b \ WHERE a.key=? AND a.rowid=b.data_key;"; sqlite3 *db = nullptr; @@ -526,11 +526,11 @@ HWTEST_F(DistributedDBRelationalGetDataTest, GetSyncData3, TestSize.Level1) * @tc.steps: step6. Check data. * @tc.expected: 2 data in the from deviceA are deleted and all data from deviceB are not deleted. */ - ExpectCount(db, "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + + ExpectCount(db, "SELECT count(*) FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + g_tableName + "_log WHERE flag&0x01=0x01;", 2U); // 2 deleted log - ExpectCount(db, "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_" + + ExpectCount(db, "SELECT count(*) FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + g_tableName + "_" + DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceA)) + ";", 3U); // 3 records in A - ExpectCount(db, "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_" + + ExpectCount(db, "SELECT count(*) FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + g_tableName + "_" + DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceB)) + ";", RECORD_COUNT); // 5 records in B sqlite3_close(db); @@ -723,8 +723,8 @@ HWTEST_F(DistributedDBRelationalGetDataTest, GetIncorrectTypeData1, TestSize.Lev * @tc.steps: step6. Check data. * @tc.expected: All data in the two tables are same. */ - ExpectCount(db, "SELECT count(*) FROM " + tableName + " as a, " + DBConstant::RELATIONAL_PREFIX + g_tableName + - "_" + DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + " as b " + ExpectCount(db, "SELECT count(*) FROM " + tableName + " as a, " + std::string(DBConstant::RELATIONAL_PREFIX) + + g_tableName + "_" + DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + " as b " "WHERE a.key=b.key AND (a.value=b.value OR (a.value is NULL AND b.value is NULL));", RECORD_COUNT); /** @@ -732,7 +732,8 @@ HWTEST_F(DistributedDBRelationalGetDataTest, GetIncorrectTypeData1, TestSize.Lev * @tc.expected: 2 index for deviceA's data table exists. */ ExpectCount(db, - "SELECT count(*) FROM sqlite_master WHERE type='index' AND tbl_name='" + DBConstant::RELATIONAL_PREFIX + + "SELECT count(*) FROM sqlite_master WHERE type='index' AND tbl_name='" + + std::string(DBConstant::RELATIONAL_PREFIX) + g_tableName + "_" + DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + "'", 2U); // 2 index sqlite3_close(db); RefObject::DecObjRef(g_store); @@ -809,13 +810,13 @@ HWTEST_F(DistributedDBRelationalGetDataTest, UpdateData1, TestSize.Level1) * @tc.steps: step5. Check data. * @tc.expected: There is 5 data in table. */ - sql = "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_" + + sql = "SELECT count(*) FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + g_tableName + "_" + DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + ";"; size_t count = 0; EXPECT_EQ(GetCount(db, sql, count), E_OK); EXPECT_EQ(count, RECORD_COUNT); - sql = "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_log;"; + sql = "SELECT count(*) FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + g_tableName + "_log;"; count = 0; EXPECT_EQ(GetCount(db, sql, count), E_OK); EXPECT_EQ(count, RECORD_COUNT); @@ -952,11 +953,12 @@ HWTEST_F(DistributedDBRelationalGetDataTest, MissQuery1, TestSize.Level1) * @tc.steps: step5. Check data. * @tc.expected: There is 3 data in table. */ - std::string getDataSql = "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_" + + std::string getDataSql = "SELECT count(*) FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + g_tableName + "_" + DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + ";"; ExpectCount(db, getDataSql, 3); // 2,3,4 - std::string getLogSql = "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_log;"; + std::string getLogSql = "SELECT count(*) FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + g_tableName + + "_log;"; ExpectCount(db, getLogSql, 3); // 2,3,4 /** @@ -1067,14 +1069,14 @@ HWTEST_F(DistributedDBRelationalGetDataTest, CompatibleData1, TestSize.Level1) * @tc.steps: step6. Check data. * @tc.expected: All data in the two tables are same. */ - sql = "SELECT count(*) FROM " + g_tableName + " as a," + DBConstant::RELATIONAL_PREFIX + tableName + "_" + - DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + " as b " + + sql = "SELECT count(*) FROM " + g_tableName + " as a," + std::string(DBConstant::RELATIONAL_PREFIX) + + tableName + "_" + DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + " as b " + "WHERE a.key=b.key AND a.value=b.value;"; size_t count = 0; EXPECT_EQ(GetCount(db, sql, count), E_OK); EXPECT_EQ(count, 1UL); - sql = "SELECT count(*) FROM " + tableName + " as a," + DBConstant::RELATIONAL_PREFIX + g_tableName + "_" + - DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + " as b " + + sql = "SELECT count(*) FROM " + tableName + " as a," + std::string(DBConstant::RELATIONAL_PREFIX) + + g_tableName + "_" + DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + " as b " + "WHERE a.key=b.key AND a.value=b.value;"; count = 0; EXPECT_EQ(GetCount(db, sql, count), E_OK); @@ -1238,8 +1240,8 @@ HWTEST_F(DistributedDBRelationalGetDataTest, CompatibleData2, TestSize.Level1) "265a9c8c3c690cdfdac72acfe7a50f748811802635d987bb7d69dc602ed3794f' ('key' 'integer' NOT NULL,'value' 'integer'," " 'integer_type' 'integer' NOT NULL DEFAULT 123, 'text_type' 'text' NOT NULL DEFAULT 'high_version', " "'real_type' 'real' NOT NULL DEFAULT 123.123456, 'blob_type' 'blob' NOT NULL DEFAULT 123, PRIMARY KEY ('key'))"; - sql = "SELECT sql FROM sqlite_master WHERE tbl_name='" + DBConstant::RELATIONAL_PREFIX + g_tableName + "_" + - DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + "';"; + sql = "SELECT sql FROM sqlite_master WHERE tbl_name='" + std::string(DBConstant::RELATIONAL_PREFIX) + g_tableName + + "_" + DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + "';"; EXPECT_EQ(GetOneText(db, sql), expectSql); sqlite3_close(db); @@ -1510,7 +1512,7 @@ HWTEST_F(DistributedDBRelationalGetDataTest, NoPkData1, TestSize.Level1) * @tc.steps: step8. Check data. * @tc.expected: There is 2 data. */ - std::string sql = "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + tableName + "_" + + std::string sql = "SELECT count(*) FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName + "_" + DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + ";"; size_t count = 0; EXPECT_EQ(GetCount(db, sql, count), E_OK); @@ -1552,7 +1554,7 @@ HWTEST_F(DistributedDBRelationalGetDataTest, GetAfterDropTable1, TestSize.Level1 sqlite3 *db = nullptr; ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK); - std::string getLogSql = "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_log " + std::string getLogSql = "SELECT count(*) FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + g_tableName + "_log " "WHERE flag&0x01<>0;"; ExpectCount(db, getLogSql, 0u); // 0 means no deleted data. diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_sqlite_single_ver_storage_engine_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_sqlite_single_ver_storage_engine_test.cpp index d274ddfd..3e23fd5f 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_sqlite_single_ver_storage_engine_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_sqlite_single_ver_storage_engine_test.cpp @@ -217,9 +217,7 @@ HWTEST_F(DistributedDBStorageSQLiteSingleVerStorageEngineTest, DataTest003, Test * @tc.steps:step6. delete invalid SQLiteSingleVerNaturalStoreConnection * @tc.expected: step6. return OK. */ - if (invalidConnection != nullptr) { - delete invalidConnection; - invalidConnection = nullptr; - } + delete invalidConnection; + invalidConnection = nullptr; ASSERT_EQ(invalidConnection, nullptr); } 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 503c3b2c..3a2a95ab 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 @@ -331,6 +331,11 @@ public: return CloudSyncer::GetSyncParamForDownload(taskId, param); } + void SetResumeTaskUpload(TaskId taskId, bool upload) + { + resumeTaskInfos_[taskId].upload = upload; + } + bool IsResumeTaskUpload(TaskId taskId) { return resumeTaskInfos_[taskId].upload; 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 6c2d6224..904aae4c 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 @@ -23,6 +23,7 @@ #include "distributeddb_tools_unit_test.h" #include "kv_store_errno.h" #include "mock_icloud_sync_storage_interface.h" +#include "virtual_asset_loader.h" #include "virtual_cloud_db.h" #include "virtual_cloud_syncer.h" #include "virtual_communicator_aggregator.h" @@ -904,6 +905,97 @@ HWTEST_F(DistributedDBCloudDBProxyTest, CloudDBProxyTest013, TestSize.Level0) EXPECT_EQ(ret, -E_OK); } +/** + * @tc.name: CloudDBProxyTest015 + * @tc.desc: Verify CloudDBProxy BatchDownload interfaces. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liuhongyang + */ +HWTEST_F(DistributedDBCloudDBProxyTest, CloudDBProxyTest015, TestSize.Level0) +{ + CloudDBProxy proxy; + + const Asset a1 = { + .version = 1, .name = "Phone", .assetId = "0", .subpath = "/local/sync", .uri = "/local/sync", + .modifyTime = "123456", .createTime = "", .size = "256", .hash = "ASE" + }; + const Asset a2 = { + .version = 2, .name = "Phone", .assetId = "0", .subpath = "/local/sync", .uri = "/cloud/sync", + .modifyTime = "123456", .createTime = "0", .size = "1024", .hash = "DEC" + }; + Assets assets1; + Assets assets2; + assets1.push_back(a1); + assets2.push_back(a2); + + IAssetLoader::AssetRecord emptyR1 = {"r1", "pre"}; + IAssetLoader::AssetRecord nonEmptyR2 = {"r2", "pre", {{"a1", assets1}}}; + IAssetLoader::AssetRecord emptyR3 = {"r3", "pre"}; + IAssetLoader::AssetRecord nonEmptyR4 = {"r4", "pre", {{"a2", assets2}}}; + size_t uintExpected = 0; + /** + * @tc.steps: step1. call CloudDBProxy BatchDownload when iAssetLoader_ is nullptr and no records has assets + * @tc.expected: step1. return E_OK. + */ + std::vector downloadAssets; + int ret = proxy.BatchDownload(TABLE_NAME, downloadAssets); + EXPECT_EQ(downloadAssets.size(), uintExpected); + EXPECT_EQ(ret, E_OK); + + downloadAssets.push_back(emptyR1); + ret = proxy.BatchDownload(TABLE_NAME, downloadAssets); + uintExpected = 1; + EXPECT_EQ(downloadAssets.size(), uintExpected); + EXPECT_EQ(ret, E_OK); + + /** + * @tc.steps: step2. call CloudDBProxy BatchDownload when iAssetLoader_ is nullptr and some records has assets + * @tc.expected: step2. return -E_NOT_SET. + */ + downloadAssets.push_back(nonEmptyR2); + ret = proxy.BatchDownload(TABLE_NAME, downloadAssets); + uintExpected = 2; + EXPECT_EQ(downloadAssets.size(), uintExpected); + EXPECT_EQ(ret, -E_NOT_SET); + + /** + * @tc.steps: step3. call CloudDBProxy BatchDownload and make iAssetLoader_ change the assets and status + * @tc.expected: step3. return E_OK, and status are changed in original vectors + */ + int totalRecordsUsed = 0; // number of records passed to loader + std::shared_ptr virtialAssetLoader = make_shared(); + virtialAssetLoader->ForkBatchDownload([&totalRecordsUsed](int rowIndex, std::map &assets) { + totalRecordsUsed++; + for (auto &asset : assets) { + if (asset.first == "a1") { + return DB_ERROR; + } + if (asset.first == "a2") { + asset.second[0].version = 3; + return NOT_FOUND; + } + } + return OK; + }); + proxy.SetIAssetLoader(virtialAssetLoader); + downloadAssets.push_back(emptyR3); + downloadAssets.push_back(nonEmptyR4); + uintExpected = 4; + EXPECT_EQ(downloadAssets.size(), uintExpected); + + ret = proxy.BatchDownload(TABLE_NAME, downloadAssets); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(virtialAssetLoader->GetBatchDownloadCount(), 1); + EXPECT_EQ(totalRecordsUsed, 2); + EXPECT_EQ(downloadAssets[0].status, OK); + EXPECT_EQ(downloadAssets[1].status, DB_ERROR); + EXPECT_EQ(downloadAssets[2].status, OK); + EXPECT_EQ(downloadAssets[3].status, NOT_FOUND); + uintExpected = 3; + EXPECT_EQ(downloadAssets[3].assets["a2"][0].version, uintExpected); +} + /** * @tc.name: CloudSyncUtilsTest * @tc.desc: Verify CloudSyncUtils interfaces diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_kv_syncer_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_kv_syncer_test.cpp index 69293d25..4957feda 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_kv_syncer_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_kv_syncer_test.cpp @@ -838,4 +838,100 @@ HWTEST_F(DistributedDBCloudKvSyncerTest, DeviceCollaborationTest001, TestSize.Le CloseKvStore(kvDelegatePtrS3, STORE_ID_3); CloseKvStore(kvDelegatePtrS4, STORE_ID_4); } + +/** + * @tc.name: DeviceCollaborationTest002 + * @tc.desc: Check concurrent removeDeviceData and sync + * @tc.type: FUNC + * @tc.require: + * @tc.author: wangxiangdong + */ +HWTEST_F(DistributedDBCloudKvSyncerTest, DeviceCollaborationTest002, TestSize.Level0) +{ + /** + * @tc.steps: step1. open db with DEVICE_COLLABORATION. + * @tc.expected: step1. return E_OK. + */ + KvStoreNbDelegate* kvDelegatePtrS3 = nullptr; + KvStoreNbDelegate::Option option; + option.conflictResolvePolicy = ConflictResolvePolicy::DEVICE_COLLABORATION; + ASSERT_EQ(GetKvStore(kvDelegatePtrS3, STORE_ID_3, option), OK); + ASSERT_NE(kvDelegatePtrS3, nullptr); + KvStoreNbDelegate* kvDelegatePtrS4 = nullptr; + ASSERT_EQ(GetKvStore(kvDelegatePtrS4, STORE_ID_4, option), OK); + ASSERT_NE(kvDelegatePtrS4, nullptr); + /** + * @tc.steps: step2. db3 put 200 k-v data. + * @tc.expected: step2. OK. + */ + std::vector entries; + for (int i = 0; i < 200; 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()); + Entry entry; + entry.key = key; + entry.value = value; + entries.push_back(entry); + } + + ASSERT_EQ(kvDelegatePtrS1_->PutBatch(entries), OK); + communicatorAggregator_->SetLocalDeviceId("DB3"); + /** + * @tc.steps: step3. when sync, try to removeDeviceData. + * @tc.expected: step3. sync stop. + */ + auto callback = [](const std::map &process) { + LOGD("process finished"); + }; + auto actualRet = kvDelegatePtrS3->Sync(g_CloudSyncoption, callback); + EXPECT_EQ(actualRet, OK); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); // wait for 100ms + EXPECT_EQ(kvDelegatePtrS3->RemoveDeviceData("", ClearMode::FLAG_AND_DATA), OK); + communicatorAggregator_->SetLocalDeviceId("DB4"); + BlockSync(kvDelegatePtrS4, OK, g_CloudSyncoption); + std::string keyStr = "k_1"; + Key key(keyStr.begin(), keyStr.end()); + Value actualValue; + EXPECT_EQ(kvDelegatePtrS4->Get(key, actualValue), NOT_FOUND); + CloseKvStore(kvDelegatePtrS3, STORE_ID_3); + CloseKvStore(kvDelegatePtrS4, STORE_ID_4); +} + +/** + * @tc.name: DeviceCollaborationTest003 + * @tc.desc: Check concurrent removeDeviceData and sync + * @tc.type: FUNC + * @tc.require: + * @tc.author: liaoyonghuang + */ +HWTEST_F(DistributedDBCloudKvSyncerTest, DeviceCollaborationTest003, TestSize.Level1) +{ + /** + * @tc.steps: step1. Block in sync + * @tc.expected: step1. return E_OK. + */ + ASSERT_EQ(kvDelegatePtrS1_->Put(KEY_1, VALUE_1), OK); + virtualCloudDb_->ForkUpload([](const std::string &, VBucket &) { + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + }); + std::thread syncThread([&]() { + BlockSync(kvDelegatePtrS1_, CLOUD_ERROR, g_CloudSyncoption); + }); + /** + * @tc.steps: step2. RemoveDeviceData concurrently + * @tc.expected: step2. return E_OK. + */ + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + std::thread removeThread1([&]() { + EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData("", ClearMode::FLAG_AND_DATA), OK); + }); + std::thread removeThread2([&]() { + EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData("", ClearMode::FLAG_AND_DATA), OK); + }); + syncThread.join(); + removeThread1.join(); + removeThread2.join(); +} } \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_kvstore_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_kvstore_test.cpp index 0eee17b0..8daf7c4c 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_kvstore_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_kvstore_test.cpp @@ -1432,6 +1432,53 @@ HWTEST_F(DistributedDBCloudKvStoreTest, RemoveDeviceTest012, TestSize.Level0) EXPECT_EQ(kvDelegatePtrS1_->Get({'k', '2'}, actualValue), NOT_FOUND); } +/** + * @tc.name: RemoveDeviceTest013 + * @tc.desc: remove log record with FLAG_ONLY and empty deviceId. + * @tc.type: FUNC + * @tc.require: + * @tc.author: wangxiangdong + */ +HWTEST_F(DistributedDBCloudKvStoreTest, RemoveDeviceTest013, TestSize.Level0) +{ + /** + * @tc.steps: step1. Insert data + * * @tc.expected: step1. insert successfully + */ + Key k1 = {'k', '1'}; + Value v1 = {'v', '1'}; + deviceB_->PutData(k1, v1, 1u, 0); // 1 is current timestamp + /** + * @tc.steps: step2. sync between devices + * * @tc.expected: step2. insert successfully + */ + deviceB_->Sync(SyncMode::SYNC_MODE_PUSH_ONLY, true); + Value actualValue; + EXPECT_EQ(kvDelegatePtrS2_->Get(k1, actualValue), OK); + EXPECT_EQ(actualValue, v1); + ASSERT_EQ(kvDelegatePtrS1_->Put(k1, v1), OK); + /** + * @tc.steps: step3. sync with cloud + * * @tc.expected: step3. OK + */ + BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption); + BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption); + Value actualValue2; + EXPECT_EQ(kvDelegatePtrS2_->Get(k1, actualValue2), OK); + EXPECT_EQ(actualValue2, v1); + EXPECT_EQ(kvDelegatePtrS2_->RemoveDeviceData("", ClearMode::FLAG_AND_DATA), OK); + Value actualValue3; + EXPECT_EQ(kvDelegatePtrS2_->Get(k1, actualValue3), NOT_FOUND); + /** + * @tc.steps: step4. sync between devices and check result + * * @tc.expected: step4. OK + */ + deviceB_->Sync(SyncMode::SYNC_MODE_PUSH_ONLY, true); + Value actualValue4; + EXPECT_EQ(kvDelegatePtrS2_->Get(k1, actualValue4), OK); + EXPECT_EQ(actualValue4, v1); +} + /** * @tc.name: NormalSyncInvalid001 * @tc.desc: Test normal push not sync and get cloud version. @@ -1716,4 +1763,60 @@ HWTEST_F(DistributedDBCloudKvStoreTest, NormalSyncInvalid008, TestSize.Level0) EXPECT_EQ(kvStoreImpl->Close(), OK); EXPECT_EQ(kvDelegatePtrS1_->SetCloudSyncConfig(config), DB_ERROR); } + +/** + * @tc.name: ConflictSync001 + * @tc.desc: test upload delete with version conflict error under merge mode, then success after retry. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suyuchen + */ +HWTEST_F(DistributedDBCloudKvStoreTest, ConflictSync001, TestSize.Level0) +{ + /** + * @tc.steps: step1. Set the retry count to 2 + * @tc.expected: step1. ok. + */ + CloudSyncConfig config; + config.maxRetryConflictTimes = 2; + kvDelegatePtrS1_->SetCloudSyncConfig(config); + /** + * @tc.steps: step2. Put 2 records and set flag to cloud + * @tc.expected: step2. ok. + */ + InsertRecord(2); + SetFlag({'k', '0'}, LogInfoFlag::FLAG_CLOUD); + SetFlag({'k', '1'}, LogInfoFlag::FLAG_CLOUD); + /** + * @tc.steps: step3. delete {k1, v1} + * @tc.expected: step3. ok. + */ + kvDelegatePtrS1_->Delete(KEY_1); + /** + * @tc.steps: step4. Set CLOUD_VERSION_CONFLICT when upload, and do sync + * @tc.expected: step4. OK. + */ + int recordIndex = 0; + virtualCloudDb_->ForkInsertConflict([&recordIndex](const std::string &tableName, VBucket &extend, VBucket &record, + vector &cloudDataVec) { + recordIndex++; + if (recordIndex == 1) { // set 1st record return CLOUD_VERSION_CONFLICT + extend[CloudDbConstant::ERROR_FIELD] = static_cast(DBStatus::CLOUD_VERSION_CONFLICT); + return CLOUD_VERSION_CONFLICT; + } + return OK; + }); + BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption); + /** + * @tc.steps: step5. Check last process + * @tc.expected: step5. ok. + */ + for (const auto &table : lastProcess_.tableProcess) { + EXPECT_EQ(table.second.upLoadInfo.total, 1u); + EXPECT_EQ(table.second.upLoadInfo.successCount, 1u); + EXPECT_EQ(table.second.upLoadInfo.failCount, 0u); + EXPECT_EQ(table.second.upLoadInfo.deleteCount, 1u); + } + virtualCloudDb_->ForkInsertConflict(nullptr); +} } 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 cff414d0..cfbcaca1 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 @@ -971,6 +971,7 @@ HWTEST_F(DistributedDBCloudSyncerLockTest, QueryCursorTest004, TestSize.Level0) */ HWTEST_F(DistributedDBCloudSyncerLockTest, QueryCursorTest006, TestSize.Level0) { + RuntimeContext::GetInstance()->SetBatchDownloadAssets(true); /** * @tc.steps:step1. insert local and sync * @tc.expected: step1. return ok. @@ -980,7 +981,7 @@ HWTEST_F(DistributedDBCloudSyncerLockTest, QueryCursorTest006, TestSize.Level0) CallSync(option); /** - * @tc.steps:step2. change asset/assets and set RemoveLocalAssets fail + * @tc.steps:step2. change asset/assets and set BatchRemoveLocalAssets fail * @tc.expected: step2. return ok. */ std::string sql = "SELECT asset, assets FROM " + ASSETS_TABLE_NAME + ";"; @@ -1003,7 +1004,7 @@ HWTEST_F(DistributedDBCloudSyncerLockTest, QueryCursorTest006, TestSize.Level0) asset.hash = "new_hash"; assets.pop_back(); UpdateCloudAssets(asset, assets, std::string("0")); - g_virtualAssetLoader->SetRemoveStatus(DBStatus::LOCAL_ASSET_NOT_FOUND); + g_virtualAssetLoader->SetBatchRemoveStatus(DBStatus::LOCAL_ASSET_NOT_FOUND); /** * @tc.steps:step3. sync and check cursor @@ -1014,7 +1015,9 @@ HWTEST_F(DistributedDBCloudSyncerLockTest, QueryCursorTest006, TestSize.Level0) " where cursor='3';"; EXPECT_EQ(sqlite3_exec(db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, reinterpret_cast(1), nullptr), SQLITE_OK); - g_virtualAssetLoader->SetRemoveStatus(DBStatus::OK); + g_virtualAssetLoader->SetBatchRemoveStatus(DBStatus::OK); + EXPECT_EQ(g_syncProcess.errCode, DBStatus::REMOVE_ASSETS_FAIL); + RuntimeContext::GetInstance()->SetBatchDownloadAssets(false); } /** @@ -1221,5 +1224,69 @@ HWTEST_F(DistributedDBCloudSyncerLockTest, ReviseLocalModTimeTest001, TestSize.L EXPECT_EQ(sqlite3_exec(db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, reinterpret_cast(cloudCount), nullptr), SQLITE_OK); } + +/** + * @tc.name: RemoveAssetsFailTest001 + * @tc.desc: Test failCount when remove assets fail + * @tc.type: FUNC + * @tc.require: + * @tc.author: suyue + */ +HWTEST_F(DistributedDBCloudSyncerLockTest, RemoveAssetsFailTest001, TestSize.Level0) +{ + /** + * @tc.steps:step1. insert local and sync + * @tc.expected: step1. return ok. + */ + RuntimeContext::GetInstance()->SetBatchDownloadAssets(true); + InsertLocalData(0, 1, ASSETS_TABLE_NAME, false); + CloudSyncOption option = PrepareOption(Query::Select().FromTable({ ASSETS_TABLE_NAME }), LockAction::INSERT); + CallSync(option); + + /** + * @tc.steps:step2. change asset and set RemoveLocalAssets fail + * @tc.expected: step2. return ok. + */ + std::string sql = "SELECT asset, assets FROM " + ASSETS_TABLE_NAME + ";"; + sqlite3_stmt *stmt = nullptr; + ASSERT_EQ(SQLiteUtils::GetStatement(db, sql, stmt), E_OK); + Asset asset; + Assets assets; + while (SQLiteUtils::StepWithRetry(stmt) != SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) { + ASSERT_EQ(sqlite3_column_type(stmt, 0), SQLITE_BLOB); + ASSERT_EQ(sqlite3_column_type(stmt, 1), SQLITE_BLOB); + Type assetsBlob; + ASSERT_EQ(SQLiteRelationalUtils::GetCloudValueByType(stmt, TYPE_INDEX, 0, assetsBlob), E_OK); + assets = g_virtualCloudDataTranslate->BlobToAssets(std::get(assetsBlob)); + Type assetBlob; + ASSERT_EQ(SQLiteRelationalUtils::GetCloudValueByType(stmt, TYPE_INDEX, 0, assetBlob), E_OK); + asset = g_virtualCloudDataTranslate->BlobToAsset(std::get(assetBlob)); + } + int errCode = E_OK; + SQLiteUtils::ResetStatement(stmt, true, errCode); + asset.hash = "new_hash"; + assets.pop_back(); + UpdateCloudAssets(asset, assets, std::string("0")); + g_virtualAssetLoader->SetRemoveStatus(DBStatus::LOCAL_ASSET_NOT_FOUND); + + /** + * @tc.steps:step3. sync and check failCount + * @tc.expected: step3. return ok. + */ + int downLoadCount = 0; + g_virtualAssetLoader->ForkDownload([this, &downLoadCount](std::map &assets) { + downLoadCount++; + if (downLoadCount == 1) { + std::string sql = "delete from " + ASSETS_TABLE_NAME + " WHERE id=0"; + EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); + } + }); + CallSync(option); + for (const auto &table : g_syncProcess.tableProcess) { + EXPECT_EQ(table.second.downLoadInfo.failCount, 1u); + } + g_virtualAssetLoader->SetRemoveStatus(DBStatus::OK); + RuntimeContext::GetInstance()->SetBatchDownloadAssets(false); +} } // namespace #endif // RELATIONAL_STORE \ No newline at end of file diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_upload_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_upload_test.cpp index 2517e93e..5ca1769f 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_upload_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/distributeddb_cloud_syncer_upload_test.cpp @@ -1052,4 +1052,90 @@ HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck018, TestSize.Level1 delete iCloud; idb = nullptr; } + +/** + * @tc.name: UploadModeCheck019 + * @tc.desc: Get sync param when task resume + * @tc.type: FUNC + * @tc.require: + * @tc.author: chenghuitao + */ +HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck019, TestSize.Level0) +{ + MockICloudSyncStorageInterface *iCloud = new MockICloudSyncStorageInterface(); + std::shared_ptr storageProxy = std::make_shared(iCloud); + TestCloudSyncer *cloudSyncer = new(std::nothrow) TestCloudSyncer(storageProxy); + std::shared_ptr idb3 = std::make_shared(); + cloudSyncer->SetMockICloudDB(idb3); + + CommonExpectCall(iCloud); + BatchExpectCall(iCloud); + + // init cloud syncer, set task as resumed and upload + TaskId taskId = 10u; + cloudSyncer->InitCloudSyncer(taskId, SYNC_MODE_CLOUD_FORCE_PUSH); + cloudSyncer->SetTaskResume(taskId, true); + cloudSyncer->SetResumeTaskUpload(taskId, true); + + // set resumed info and cached water mark + ICloudSyncer::SyncParam param; + param.cloudWaterMark = "waterMark"; + param.tableName = cloudSyncer->GetCurrentContextTableName(); + cloudSyncer->SetResumeSyncParam(taskId, param); + cloudSyncer->SetCloudWaterMarks(param.tableName, param.cloudWaterMark); + + // call GetSyncParamForDownload method and check waterMark of the sync param + ICloudSyncer::SyncParam actualParam; + EXPECT_EQ(cloudSyncer->CallGetSyncParamForDownload(taskId, actualParam), E_OK); + std::string expectCloudWaterMark = ""; + EXPECT_EQ(actualParam.cloudWaterMark, expectCloudWaterMark); + + cloudSyncer->CallClose(); + RefObject::KillAndDecObjRef(cloudSyncer); + storageProxy.reset(); + delete iCloud; + idb3 = nullptr; +} + +/** + * @tc.name: UploadModeCheck020 + * @tc.desc: Get sync param when task does NOT pause + * @tc.type: FUNC + * @tc.require: + * @tc.author: chenghuitao + */ +HWTEST_F(DistributedDBCloudSyncerUploadTest, UploadModeCheck020, TestSize.Level0) +{ + MockICloudSyncStorageInterface *iCloud = new MockICloudSyncStorageInterface(); + std::shared_ptr storageProxy = std::make_shared(iCloud); + TestCloudSyncer *cloudSyncer = new(std::nothrow) TestCloudSyncer(storageProxy); + std::shared_ptr idb3 = std::make_shared(); + cloudSyncer->SetMockICloudDB(idb3); + + CommonExpectCall(iCloud); + BatchExpectCall(iCloud); + + // init cloud syncer + TaskId taskId = 10u; + cloudSyncer->InitCloudSyncer(taskId, SYNC_MODE_CLOUD_FORCE_PUSH); + + // set resumed info and cached water mark + ICloudSyncer::SyncParam param; + param.cloudWaterMark = "waterMark"; + param.tableName = cloudSyncer->GetCurrentContextTableName(); + cloudSyncer->SetResumeSyncParam(taskId, param); + cloudSyncer->SetCloudWaterMarks(param.tableName, param.cloudWaterMark); + + // call GetSyncParamForDownload method and check waterMark of the sync param + ICloudSyncer::SyncParam actualParam; + EXPECT_EQ(cloudSyncer->CallGetSyncParamForDownload(taskId, actualParam), E_OK); + std::string expectCloudWaterMark = "waterMark"; + EXPECT_EQ(actualParam.cloudWaterMark, expectCloudWaterMark); + + cloudSyncer->CallClose(); + RefObject::KillAndDecObjRef(cloudSyncer); + storageProxy.reset(); + delete iCloud; + idb3 = nullptr; +} } diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_asset_loader.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_asset_loader.cpp index 365ca9b1..e05e9f67 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_asset_loader.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_asset_loader.cpp @@ -40,21 +40,21 @@ DBStatus VirtualAssetLoader::Download(const std::string &tableName, const std::s DBStatus VirtualAssetLoader::RemoveLocalAssets(const std::vector &assets) { + { + std::lock_guard autoLock(dataMutex_); + if (removeStatus_ != OK) { + return removeStatus_; + } + } if (removeAssetsCallBack_) { return removeAssetsCallBack_(assets); } return DBStatus::OK; } -DBStatus VirtualAssetLoader::RemoveLocalAssets(const std::string &tableName, const std::string &gid, const Type &prefix, - std::map &assets) +DBStatus VirtualAssetLoader::RemoveLocalAssetsInner(const std::string &tableName, const std::string &gid, + const Type &prefix, std::map &assets) { - { - std::lock_guard autoLock(dataMutex_); - if (removeStatus_ != OK) { - return removeStatus_; - } - } DBStatus errCode = DBStatus::OK; if (removeLocalAssetsCallBack_) { errCode = removeLocalAssetsCallBack_(assets); @@ -72,6 +72,18 @@ DBStatus VirtualAssetLoader::RemoveLocalAssets(const std::string &tableName, con return DBStatus::OK; } +DBStatus VirtualAssetLoader::RemoveLocalAssets(const std::string &tableName, const std::string &gid, const Type &prefix, + std::map &assets) +{ + { + std::lock_guard autoLock(dataMutex_); + if (removeStatus_ != OK) { + return removeStatus_; + } + } + return RemoveLocalAssetsInner(tableName, gid, prefix, assets); +} + void VirtualAssetLoader::SetDownloadStatus(DBStatus status) { std::lock_guard autoLock(dataMutex_); @@ -86,6 +98,13 @@ void VirtualAssetLoader::SetRemoveStatus(DBStatus status) removeStatus_ = status; } +void VirtualAssetLoader::SetBatchRemoveStatus(DBStatus status) +{ + std::lock_guard autoLock(dataMutex_); + LOGD("[VirtualAssetLoader] set batch remove status :%d", static_cast(status)); + batchRemoveStatus_ = status; +} + void VirtualAssetLoader::ForkDownload(const DownloadCallBack &callback) { downloadCallBack_ = callback; @@ -100,4 +119,52 @@ void VirtualAssetLoader::SetRemoveLocalAssetsCallback(const RemoveLocalAssetsCal { removeLocalAssetsCallBack_ = callback; } + +void VirtualAssetLoader::BatchDownload(const std::string &tableName, std::vector &downloadAssets) +{ + downloadCount_++; + int index = 0; + for (auto &[gid, prefix, assets, status] : downloadAssets) { + if (batchDownloadCallback_) { + status = batchDownloadCallback_(index, assets); + } else { + status = Download(tableName, gid, prefix, assets); + } + index++; + } +} + +void VirtualAssetLoader::BatchRemoveLocalAssets(const std::string &tableName, + std::vector &removeAssets) +{ + removeCount_++; + for (auto &[gid, prefix, assets, status] : removeAssets) { + if (batchRemoveStatus_ != OK) { + status = batchRemoveStatus_; + } else { + status = RemoveLocalAssetsInner(tableName, gid, prefix, assets); + } + } +} + +int VirtualAssetLoader::GetBatchDownloadCount() +{ + return downloadCount_; +} + +int VirtualAssetLoader::GetBatchRemoveCount() +{ + return removeCount_; +} + +void VirtualAssetLoader::Reset() +{ + removeCount_ = 0; + downloadCount_ = 0; +} + +void VirtualAssetLoader::ForkBatchDownload(const BatchDownloadCallback &callback) +{ + batchDownloadCallback_ = callback; +} } diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_asset_loader.h b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_asset_loader.h index f30f39a3..374e7d52 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_asset_loader.h +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/cloud/virtual_asset_loader.h @@ -15,6 +15,7 @@ #ifndef VIRTUAL_ASSETLOADER_H #define VIRTUAL_ASSETLOADER_H +#include #include #include "iAssetLoader.h" @@ -22,6 +23,7 @@ namespace DistributedDB { using DownloadCallBack = std::function &assets)>; using RemoveAssetsCallBack = std::function &assets)>; using RemoveLocalAssetsCallBack = std::function &assets)>; +using BatchDownloadCallback = std::function &assets)>; class VirtualAssetLoader : public IAssetLoader { public: VirtualAssetLoader() = default; @@ -39,18 +41,39 @@ public: void SetRemoveStatus(DBStatus status); + void SetBatchRemoveStatus(DBStatus status); + void ForkDownload(const DownloadCallBack &callback); void ForkRemoveLocalAssets(const RemoveAssetsCallBack &callback); void SetRemoveLocalAssetsCallback(const RemoveLocalAssetsCallBack &callback); + + void BatchDownload(const std::string &tableName, std::vector &downloadAssets) override; + + void BatchRemoveLocalAssets(const std::string &tableName, std::vector &removeAssets) override; + + int GetBatchDownloadCount(); + + int GetBatchRemoveCount(); + + void Reset(); + + void ForkBatchDownload(const BatchDownloadCallback &callback); private: + DBStatus RemoveLocalAssetsInner(const std::string &tableName, const std::string &gid, const Type &prefix, + std::map &assets); + std::mutex dataMutex_; DBStatus downloadStatus_ = OK; DBStatus removeStatus_ = OK; + DBStatus batchRemoveStatus_ = OK; DownloadCallBack downloadCallBack_; RemoveAssetsCallBack removeAssetsCallBack_; RemoveLocalAssetsCallBack removeLocalAssetsCallBack_; + std::atomic downloadCount_ = 0; + std::atomic removeCount_ = 0; + BatchDownloadCallback batchDownloadCallback_; }; } #endif // VIRTUAL_ASSETLOADER_H 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 ed76bab1..dc8dab51 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 @@ -298,12 +298,12 @@ HWTEST_F(DistributedDBMetaDataTest, MetadataTest006, TestSize.Level0) PutMetaDataValue(hashDeviceId, metaDataValue); /** * @tc.steps: step2. Check ability sync finish by meta. - * @tc.expected: step2. A is not finish because of cached. + * @tc.expected: step2. A is finish because meta data is loaded from db. */ - EXPECT_FALSE(metadata_->IsAbilitySyncFinish(DEVICE_A)); + EXPECT_TRUE(metadata_->IsAbilitySyncFinish(DEVICE_A)); /** * @tc.steps: step3. Erase water mark and check again. - * @tc.expected: step3. A is finish because reload cache. + * @tc.expected: step3. A is finish because meta data is loaded from db. */ EXPECT_EQ(metadata_->EraseDeviceWaterMark(DEVICE_A, true), E_OK); EXPECT_TRUE(metadata_->IsAbilitySyncFinish(DEVICE_A)); diff --git a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_multi_user_test.cpp b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_multi_user_test.cpp index 88063699..18a8aba2 100644 --- a/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_multi_user_test.cpp +++ b/kv_store/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_multi_user_test.cpp @@ -423,6 +423,18 @@ namespace { messageCount++; }); } + + void InsertBatchValue(const std::string &tableName, const std::string &dbPath, int totalNum) + { + sqlite3 *db = nullptr; + EXPECT_EQ(GetDB(db, dbPath), SQLITE_OK); + for (int i = 0; i < totalNum; i++) { + std::string sql = "insert into " + tableName + + " values(" + std::to_string(i) + ", 'aaa');"; + EXPECT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK); + } + EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); + } } class DistributedDBRelationalMultiUserTest : public testing::Test { @@ -1248,6 +1260,55 @@ HWTEST_F(DistributedDBRelationalMultiUserTest, RDBSyncOpt005, TestSize.Level0) g_communicatorAggregator->RegOnDispatch(nullptr); } +/** + * @tc.name: RDBSyncOpt006 + * @tc.desc: check sync when time change. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suyue + */ +HWTEST_F(DistributedDBRelationalMultiUserTest, RDBSyncOpt006, TestSize.Level0) +{ + /** + * @tc.steps: step1. openStore and insert data + * @tc.expected: step1. return ok + */ + OpenStore1(true); + PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1); + PrepareVirtualDeviceBEnv(g_tableName); + InsertBatchValue(g_tableName, g_storePath1, 10000); + + /** + * @tc.steps: step2. device B set delay send time + * * @tc.expected: step2. return ok + */ + std::set delayDevice = {DEVICE_B}; + g_communicatorAggregator->SetSendDelayInfo(3000u, TIME_SYNC_MESSAGE, 1u, 0u, delayDevice); // send delay 3000ms + + /** + * @tc.steps: step3. notify time change when sync + * @tc.expected: step3. sync success + */ + Query query = Query::Select(g_tableName); + SyncStatusCallback callback = nullptr; + thread thd1 = thread([&]() { + EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PULL_ONLY, query, true), E_OK); + }); + std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME)); + thread thd2 = thread([]() { + RuntimeContext::GetInstance()->NotifyTimestampChanged(100); + RuntimeContext::GetInstance()->RecordAllTimeChange(); + RuntimeContext::GetInstance()->ClearAllDeviceTimeInfo(); + }); + thd1.join(); + thd2.join(); + + CloseStore(); + OS::RemoveFile(g_storePath1); + PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1); + g_communicatorAggregator->ResetSendDelayInfo(); +} + /** * @tc.name: DropDistributedTableTest001 * @tc.desc: Test sync after drop distributed table. 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 4b2106fa..e27cf38a 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 @@ -827,77 +827,6 @@ HWTEST_F(DistributedDBSingleVerP2PComplexSyncTest, DeviceOfflineSync002, TestSiz EXPECT_EQ(value5, value4); } -/** - * @tc.name: Device Offline Sync 003 - * @tc.desc: Test sync statuses when device offline and sendMessage return different errCode - * @tc.type: FUNC - * @tc.require: - * @tc.author: suyue - */ -HWTEST_F(DistributedDBSingleVerP2PComplexSyncTest, DeviceOfflineSync003, TestSize.Level1) -{ - /** - * @tc.steps: step1. device put data. - * @tc.expected: step1. sync return OK. - */ - std::vector devices; - devices.push_back(g_deviceB->GetDeviceId()); - devices.push_back(g_deviceC->GetDeviceId()); - Key key1 = {'1'}; - Value value1 = {'1'}; - ASSERT_EQ(g_kvDelegatePtr->Put(key1, value1), OK); - - /** - * @tc.steps: step2. call sync when device offline and mock commErrCode is E_BASE(positive number). - * @tc.expected: step2. return COMM_FAILURE. - */ - g_communicatorAggregator->MockCommErrCode(E_BASE); - std::map result; - DBStatus status = g_tool.SyncTest(g_kvDelegatePtr, devices, SYNC_MODE_PUSH_ONLY, result); - ASSERT_EQ(status, OK); - for (const auto &pair : result) { - LOGD("dev %s, status %d, expectStatus %d", pair.first.c_str(), pair.second, E_BASE); - EXPECT_EQ(pair.second, COMM_FAILURE); - } - - /** - * @tc.steps: step3. call sync when device offline and mock commErrCode is -E_BASE(negative number). - * @tc.expected: step3. return -E_BASE. - */ - g_communicatorAggregator->MockCommErrCode(-E_BASE); - status = g_tool.SyncTest(g_kvDelegatePtr, devices, SYNC_MODE_PUSH_ONLY, result); - ASSERT_EQ(status, OK); - for (const auto &pair : result) { - LOGD("dev %s, status %d, expectStatus %d", pair.first.c_str(), pair.second, COMM_FAILURE); - EXPECT_EQ(pair.second, static_cast(-E_BASE)); - } - - /** - * @tc.steps: step4. call sync when device offline and mock commErrCode is INT_MAX. - * @tc.expected: step4. return COMM_FAILURE. - */ - g_communicatorAggregator->MockCommErrCode(INT_MAX); - status = g_tool.SyncTest(g_kvDelegatePtr, devices, SYNC_MODE_PUSH_ONLY, result); - ASSERT_EQ(status, OK); - for (const auto &pair : result) { - LOGD("dev %s, status %d, expectStatus %d", pair.first.c_str(), pair.second, INT_MAX); - EXPECT_EQ(pair.second, COMM_FAILURE); - } - - /** - * @tc.steps: step5. call sync when device offline and mock commErrCode is -INT_MAX. - * @tc.expected: step5. return -INT_MAX. - */ - g_communicatorAggregator->MockCommErrCode(-INT_MAX); - status = g_tool.SyncTest(g_kvDelegatePtr, devices, SYNC_MODE_PUSH_ONLY, result); - ASSERT_EQ(status, OK); - for (const auto &pair : result) { - LOGD("dev %s, status %d, expectStatus %d", pair.first.c_str(), pair.second, -INT_MAX); - EXPECT_EQ(pair.second, -INT_MAX); - } - g_communicatorAggregator->MockCommErrCode(E_OK); -} - /** * @tc.name: EncryptedAlgoUpgrade001 * @tc.desc: Test upgrade encrypted db can sync normally @@ -2280,3 +2209,149 @@ HWTEST_F(DistributedDBSingleVerP2PComplexSyncTest, MetaBusy001, TestSize.Level1) g_deviceB->SetSaveDataCallback(nullptr); RuntimeContext::GetInstance()->StopTaskPool(); } + +/** + * @tc.name: TestErrCodePassthrough001 + * @tc.desc: Test ErrCode Passthrough when sync comm fail + * @tc.type: FUNC + * @tc.require: + * @tc.author: suyue + */ +HWTEST_F(DistributedDBSingleVerP2PComplexSyncTest, TestErrCodePassthrough001, TestSize.Level1) +{ + /** + * @tc.steps: step1. device put data. + * @tc.expected: step1. sync return OK. + */ + std::vector devices; + devices.push_back(g_deviceB->GetDeviceId()); + devices.push_back(g_deviceC->GetDeviceId()); + Key key1 = {'1'}; + Value value1 = {'1'}; + ASSERT_EQ(g_kvDelegatePtr->Put(key1, value1), OK); + + /** + * @tc.steps: step2. call sync and mock commErrCode is E_BASE(positive number). + * @tc.expected: step2. return COMM_FAILURE. + */ + g_communicatorAggregator->MockCommErrCode(E_BASE); + std::map result; + DBStatus status = g_tool.SyncTest(g_kvDelegatePtr, devices, SYNC_MODE_PUSH_ONLY, result); + ASSERT_EQ(status, OK); + for (const auto &pair : result) { + LOGD("dev %s, status %d, expectStatus %d", pair.first.c_str(), pair.second, E_BASE); + EXPECT_EQ(pair.second, COMM_FAILURE); + } + + /** + * @tc.steps: step3. call sync and mock commErrCode is -E_BASE(negative number). + * @tc.expected: step3. return -E_BASE. + */ + g_communicatorAggregator->MockCommErrCode(-E_BASE); + status = g_tool.SyncTest(g_kvDelegatePtr, devices, SYNC_MODE_PUSH_ONLY, result); + ASSERT_EQ(status, OK); + for (const auto &pair : result) { + LOGD("dev %s, status %d, expectStatus %d", pair.first.c_str(), pair.second, COMM_FAILURE); + EXPECT_EQ(pair.second, static_cast(-E_BASE)); + } + + /** + * @tc.steps: step4. call sync and mock commErrCode is INT_MAX. + * @tc.expected: step4. return COMM_FAILURE. + */ + g_communicatorAggregator->MockCommErrCode(INT_MAX); + status = g_tool.SyncTest(g_kvDelegatePtr, devices, SYNC_MODE_PUSH_ONLY, result); + ASSERT_EQ(status, OK); + for (const auto &pair : result) { + LOGD("dev %s, status %d, expectStatus %d", pair.first.c_str(), pair.second, INT_MAX); + EXPECT_EQ(pair.second, COMM_FAILURE); + } + + /** + * @tc.steps: step5. call sync and mock commErrCode is -INT_MAX. + * @tc.expected: step5. return -INT_MAX. + */ + g_communicatorAggregator->MockCommErrCode(-INT_MAX); + status = g_tool.SyncTest(g_kvDelegatePtr, devices, SYNC_MODE_PUSH_ONLY, result); + ASSERT_EQ(status, OK); + for (const auto &pair : result) { + LOGD("dev %s, status %d, expectStatus %d", pair.first.c_str(), pair.second, -INT_MAX); + EXPECT_EQ(pair.second, -INT_MAX); + } + g_communicatorAggregator->MockCommErrCode(E_OK); +} + +/** + * @tc.name: TestErrCodePassthrough002 + * @tc.desc: Test ErrCode Passthrough when sync time out and isDirectEnd is false + * @tc.type: FUNC + * @tc.require: + * @tc.author: suyue + */ +HWTEST_F(DistributedDBSingleVerP2PComplexSyncTest, TestErrCodePassthrough002, TestSize.Level3) +{ + /** + * @tc.steps: step1. device put data. + * @tc.expected: step1. sync return OK. + */ + std::vector devices; + devices.push_back(g_deviceB->GetDeviceId()); + ASSERT_EQ(g_kvDelegatePtr->Put({'k', '1'}, {'v', '1'}), OK); + + /** + * @tc.steps: step2. set messageId invalid and isDirectEnd is false + * @tc.expected: step2. make sure deviceA push data failed due to timeout + */ + g_communicatorAggregator->RegOnDispatch([](const std::string &target, DistributedDB::Message *msg) { + ASSERT_NE(msg, nullptr); + if (target == DEVICE_B && msg->GetMessageId() == QUERY_SYNC_MESSAGE) { + msg->SetMessageId(INVALID_MESSAGE_ID); + } + }); + g_communicatorAggregator->MockDirectEndFlag(false); + + /** + * @tc.steps: step3. call sync and mock errCode is E_BASE(positive number). + * @tc.expected: step3. return TIME_OUT. + */ + std::map result; + auto callback = [&result](const std::map &map) { + result = map; + }; + Query query = Query::Select().PrefixKey({'k', '1'}); + g_communicatorAggregator->MockCommErrCode(E_BASE); + EXPECT_EQ(g_kvDelegatePtr->Sync(devices, DistributedDB::SYNC_MODE_PUSH_ONLY, callback, query, true), OK); + EXPECT_EQ(result.size(), devices.size()); + EXPECT_EQ(result[DEVICE_B], TIME_OUT); + + /** + * @tc.steps: step4. call sync and mock errCode is -E_BASE(negative number). + * @tc.expected: step4. return -E_BASE. + */ + g_communicatorAggregator->MockCommErrCode(-E_BASE); + EXPECT_EQ(g_kvDelegatePtr->Sync(devices, DistributedDB::SYNC_MODE_PUSH_ONLY, callback, query, true), OK); + EXPECT_EQ(result.size(), devices.size()); + EXPECT_EQ(result[DEVICE_B], -E_BASE); + + /** + * @tc.steps: step5. call sync and mock errCode is E_OK(0). + * @tc.expected: step5. return TIME_OUT. + */ + g_communicatorAggregator->MockCommErrCode(E_OK); + EXPECT_EQ(g_kvDelegatePtr->Sync(devices, DistributedDB::SYNC_MODE_PUSH_ONLY, callback, query, true), OK); + EXPECT_EQ(result.size(), devices.size()); + EXPECT_EQ(result[DEVICE_B], TIME_OUT); + + /** + * @tc.steps: step6. call sync and mock errCode is -INT_MAX. + * @tc.expected: step6. return -INT_MAX. + */ + g_communicatorAggregator->MockCommErrCode(-INT_MAX); + EXPECT_EQ(g_kvDelegatePtr->Sync(devices, DistributedDB::SYNC_MODE_PUSH_ONLY, callback, query, true), OK); + EXPECT_EQ(result.size(), devices.size()); + EXPECT_EQ(result[DEVICE_B], -INT_MAX); + + g_communicatorAggregator->RegOnDispatch(nullptr); + g_communicatorAggregator->MockCommErrCode(E_OK); + g_communicatorAggregator->MockDirectEndFlag(true); +} 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 d663c43f..29ee0cec 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 @@ -1156,6 +1156,10 @@ HWTEST_F(DistributedDBSingleVerP2PQuerySyncTest, MetaDataExceptionBranch001, Tes * @tc.expected: step1. out value = 0 */ Metadata meta; + VirtualSingleVerSyncDBInterface storage; + int errCode = meta.Initialize(&storage); + ASSERT_EQ(errCode, E_OK); + uint64_t val = 99; // 99 is the initial value of outValue uint64_t outValue = val; meta.GetRemoveDataMark("D1", outValue); 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 78941c21..ea7a7c98 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 @@ -2407,6 +2407,43 @@ HWTEST_F(DistributedDBSingleVerP2PSyncCheckTest, KVSyncOpt007, TestSize.Level0) g_communicatorAggregator->RegOnDispatch(nullptr); } +/** + * @tc.name: KVSyncOpt008 + * @tc.desc: check rebuild open store with NOT_SET. + * @tc.type: FUNC + * @tc.require: + * @tc.author: tankaisheng + */ +HWTEST_F(DistributedDBSingleVerP2PSyncCheckTest, KVSyncOpt008, TestSize.Level0) +{ + /** + * @tc.steps: step1. record packet which send to B + */ + std::atomic messageCount = 0; + RegOnDispatchWithoutDataPacket(messageCount, true); + /** + * @tc.steps: step2. deviceA call sync and wait + * @tc.expected: step2. sync should return OK. + */ + std::vector devices; + devices.push_back(g_deviceB->GetDeviceId()); + EXPECT_EQ(g_deviceB->Sync(SYNC_MODE_PUSH_ONLY, true), E_OK); + EXPECT_EQ(messageCount, 2); // 2 contain time sync request packet and ability sync packet + /** + * @tc.steps: step3. rebuild kv store + * @tc.expected: step3. rebuild failed. + */ + ASSERT_EQ(g_mgr.CloseKvStore(g_kvDelegatePtr), OK); + g_kvDelegatePtr = nullptr; + g_mgr.DeleteKvStore(STORE_ID); + KvStoreNbDelegate::Option option; + option.secOption.securityLabel = SecurityLabel::NOT_SET; + option.secOption.securityFlag = SecurityFlag::SECE; + g_mgr.GetKvStore(STORE_ID, option, g_kvDelegateCallback); + ASSERT_TRUE(g_kvDelegateStatus == DBStatus::INVALID_ARGS); + ASSERT_TRUE(g_kvDelegatePtr == nullptr); +} + /** * @tc.name: KVTimeChange001 * @tc.desc: check time sync and ability sync once 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 2b7b4d4a..4626a323 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 @@ -259,8 +259,8 @@ void VirtualCommunicatorAggregator::CallSendEnd(int errCode, const OnSendEnd &on errCode = commErrCodeMock_; } if (onEnd) { - (void)RuntimeContext::GetInstance()->ScheduleTask([errCode, onEnd]() { - onEnd(errCode); + (void)RuntimeContext::GetInstance()->ScheduleTask([errCode, onEnd, this]() { + onEnd(errCode, isDirectEnd_); }); } } @@ -380,4 +380,9 @@ void VirtualCommunicatorAggregator::MockCommErrCode(int mockErrCode) std::lock_guard lock(localDeviceIdMutex_); commErrCodeMock_ = mockErrCode; } + +void VirtualCommunicatorAggregator::MockDirectEndFlag(bool isDirectEnd) +{ + isDirectEnd_ = isDirectEnd; +} } // 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 8a3ae4fc..64812feb 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 @@ -95,6 +95,8 @@ public: void MockCommErrCode(int mockErrCode); + void MockDirectEndFlag(bool isDirectEnd); + ~VirtualCommunicatorAggregator() override = default; VirtualCommunicatorAggregator() = default; @@ -127,7 +129,8 @@ private: std::string localDeviceId_; int getLocalDeviceRet_ = E_OK; int commErrCodeMock_ = E_OK; + bool isDirectEnd_ = true; }; } // namespace DistributedDB -#endif // VIRTUAL_ICOMMUNICATORAGGREGATOR_H +#endif // VIRTUAL_ICOMMUNICATORAGGREGATOR_H \ No newline at end of file diff --git a/kv_store/interfaces/innerkits/distributeddata/include/executor.h b/kv_store/interfaces/innerkits/distributeddata/include/executor.h index 29217ccc..3d2c49bc 100644 --- a/kv_store/interfaces/innerkits/distributeddata/include/executor.h +++ b/kv_store/interfaces/innerkits/distributeddata/include/executor.h @@ -20,7 +20,6 @@ #include #include #include "priority_queue.h" -#include "active_boottime.h" namespace OHOS { class Executor : public std::enable_shared_from_this { @@ -104,7 +103,7 @@ private: } waits_ = nullptr; } while (running_ == RUNNING && - condition_.wait_until(lock, Boottime::Now() + TIME_OUT, [this]() { + condition_.wait_until(lock, std::chrono::steady_clock::now() + TIME_OUT, [this]() { return waits_ != nullptr; })); } while (!release_(self_, running_ == IS_STOPPING)); diff --git a/kv_store/interfaces/innerkits/distributeddata/include/executor_pool.h b/kv_store/interfaces/innerkits/distributeddata/include/executor_pool.h index 0c9d0608..8357b84c 100644 --- a/kv_store/interfaces/innerkits/distributeddata/include/executor_pool.h +++ b/kv_store/interfaces/innerkits/distributeddata/include/executor_pool.h @@ -24,7 +24,6 @@ #include "executor.h" #include "pool.h" #include "priority_queue.h" -#include "active_boottime.h" namespace OHOS { class ExecutorPool { public: @@ -107,7 +106,7 @@ public: innerTask.interval = interval; innerTask.times = times; innerTask.taskId = GenTaskId(); - return Schedule(std::move(innerTask), Boottime::Now() + delay); + return Schedule(std::move(innerTask), std::chrono::steady_clock::now() + delay); } bool Remove(TaskId taskId, bool wait = false) @@ -130,7 +129,7 @@ public: if (task.interval != INVALID_INTERVAL) { task.interval = interval; } - auto time = Boottime::Now() + interval; + auto time = std::chrono::steady_clock::now() + interval; return std::pair{ task.interval != INVALID_INTERVAL, time }; }); return updated ? taskId : INVALID_TASK_ID; @@ -203,7 +202,7 @@ private: static std::pair NextTimer(InnerTask &task) { if (task.interval != INVALID_INTERVAL && --task.times > 0) { - auto time = Boottime::Now() + task.interval; + auto time = std::chrono::steady_clock::now() + task.interval; return { true, time }; } return { false, INVALID_TIME }; diff --git a/kv_store/interfaces/innerkits/distributeddata/include/priority_queue.h b/kv_store/interfaces/innerkits/distributeddata/include/priority_queue.h index 36fb68bd..f10bca3a 100644 --- a/kv_store/interfaces/innerkits/distributeddata/include/priority_queue.h +++ b/kv_store/interfaces/innerkits/distributeddata/include/priority_queue.h @@ -23,7 +23,6 @@ #include #include #include -#include "active_boottime.h" namespace OHOS { template class PriorityQueue { @@ -49,7 +48,7 @@ public: std::unique_lock lock(pqMtx_); while (!tasks_.empty()) { auto waitTme = tasks_.begin()->first; - if (waitTme > Boottime::Now()) { + if (waitTme > std::chrono::steady_clock::now()) { popCv_.wait_until(lock, waitTme); continue; } diff --git a/kv_store/interfaces/innerkits/distributeddata/include/store_errno.h b/kv_store/interfaces/innerkits/distributeddata/include/store_errno.h index 5065b787..5fa5c94b 100644 --- a/kv_store/interfaces/innerkits/distributeddata/include/store_errno.h +++ b/kv_store/interfaces/innerkits/distributeddata/include/store_errno.h @@ -208,7 +208,12 @@ enum Status : int32_t { /** * database can not open. */ - DB_CANT_OPEN = DISTRIBUTEDDATAMGR_ERR_OFFSET + 42 + DB_CANT_OPEN = DISTRIBUTEDDATAMGR_ERR_OFFSET + 42, + + /** + * The device is not online. + */ + DEVICE_NOT_ONLINE = DISTRIBUTEDDATAMGR_ERR_OFFSET + 43 }; } // namespace OHOS::DistributedKv #endif // OHOS_DISTRIBUTED_DATA_INTERFACES_DISTRIBUTEDDATA_STORE_ERRNO_H diff --git a/kv_store/interfaces/innerkits/distributeddata/include/types.h b/kv_store/interfaces/innerkits/distributeddata/include/types.h index 3a8ace34..dda871da 100644 --- a/kv_store/interfaces/innerkits/distributeddata/include/types.h +++ b/kv_store/interfaces/innerkits/distributeddata/include/types.h @@ -567,6 +567,10 @@ struct Options { * Set authType of kv store. */ AuthType authType = AuthType::DEFAULT; + /** + * Application sdk version. + */ + int32_t apiVersion = 9; }; /** diff --git a/kv_store/test/fuzztest/taskscheduler_fuzzer/taskscheduler_fuzzer.cpp b/kv_store/test/fuzztest/taskscheduler_fuzzer/taskscheduler_fuzzer.cpp index 84236170..3a9a03d5 100644 --- a/kv_store/test/fuzztest/taskscheduler_fuzzer/taskscheduler_fuzzer.cpp +++ b/kv_store/test/fuzztest/taskscheduler_fuzzer/taskscheduler_fuzzer.cpp @@ -23,7 +23,7 @@ namespace OHOS { static constexpr int MAX_DELAY_TIME = 5; static constexpr int MAX_INTERVAL_TIME = 3; -void AtFuzz(size_t time) +void AtFuzz(int time) { TaskScheduler taskScheduler; std::chrono::steady_clock::time_point tp = std::chrono::steady_clock::now() + @@ -33,7 +33,7 @@ void AtFuzz(size_t time) taskScheduler.Remove(task); } -void EveryFUZZ(size_t time) +void EveryFUZZ(int time) { TaskScheduler taskScheduler; std::chrono::duration delay(time % MAX_DELAY_TIME); @@ -47,7 +47,7 @@ void EveryFUZZ(size_t time) taskScheduler.Clean(); } -void ResetFuzz(size_t time) +void ResetFuzz(int time) { TaskScheduler taskScheduler; std::chrono::duration interval(time % MAX_INTERVAL_TIME); @@ -61,8 +61,9 @@ void ResetFuzz(size_t time) extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { /* Run your code on data */ - OHOS::AtFuzz(size); - OHOS::EveryFUZZ(size); - OHOS::ResetFuzz(size); + int time = static_cast(*data); + OHOS::AtFuzz(time); + OHOS::EveryFUZZ(time); + OHOS::ResetFuzz(time); return 0; -} +} \ No newline at end of file diff --git a/mock/src/mock_notification.cpp b/mock/src/mock_notification.cpp index 377ff72e..1c93e256 100644 --- a/mock/src/mock_notification.cpp +++ b/mock/src/mock_notification.cpp @@ -298,6 +298,7 @@ CommonEventSubscriber::CommonEventSubscriber(const CommonEventSubscribeInfo &sub CommonEventSubscriber::~CommonEventSubscriber() {} const std::string CommonEventSupport::COMMON_EVENT_USER_REMOVED = "COMMON_EVENT_USER_REMOVED"; const std::string CommonEventSupport::COMMON_EVENT_USER_UNLOCKED = "COMMON_EVENT_USER_UNLOCKED"; +const std::string CommonEventSupport::COMMON_EVENT_USER_STOPPING = "COMMON_EVENT_USER_STOPPING"; const std::string CommonEventSupport::COMMON_EVENT_USER_STOPPED = "COMMON_EVENT_USER_STOPPED"; const std::string CommonEventSupport::COMMON_EVENT_HWID_TOKEN_INVALID = "COMMON_EVENT_HWID_TOKEN_INVALID"; const std::string CommonEventSupport::COMMON_EVENT_HWID_LOGOUT = "COMMON_EVENT_HWID_LOGOUT"; diff --git a/preferences/frameworks/js/napi/common/src/napi_preferences_error.cpp b/preferences/frameworks/js/napi/common/src/napi_preferences_error.cpp index 02e60ebe..51f79f17 100644 --- a/preferences/frameworks/js/napi/common/src/napi_preferences_error.cpp +++ b/preferences/frameworks/js/napi/common/src/napi_preferences_error.cpp @@ -18,12 +18,13 @@ 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." }, + { E_NOT_STAGE_MODE, E_NOT_STAGE_MODE, "The operations is supported in stage mode only." }, + { E_DATA_GROUP_ID_INVALID, E_DATA_GROUP_ID_INVALID, "Invalid dataGroupId." }, + { NativePreferences::E_DELETE_FILE_FAIL, E_DELETE_FILE_FAIL, + "Failed to delete the user preferences persistence 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" }, + "Failed to obtain the subscription service." }, + { NativePreferences::E_NOT_SUPPORTED, E_NOT_SUPPORTED, "Capability not supported." }, }; const std::optional GetJsErrorCode(int32_t errorCode) diff --git a/preferences/frameworks/js/napi/sendable_preferences/src/napi_preferences.cpp b/preferences/frameworks/js/napi/sendable_preferences/src/napi_preferences.cpp index 264e3d3f..0e2e01b3 100644 --- a/preferences/frameworks/js/napi/sendable_preferences/src/napi_preferences.cpp +++ b/preferences/frameworks/js/napi/sendable_preferences/src/napi_preferences.cpp @@ -152,6 +152,10 @@ int ParseKey(napi_env env, const napi_value arg, std::shared_ptr context) { int32_t rc = Utils::ConvertFromSendable(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 must be less then 16 * 1024 * 1024 btyes.")); + } PRE_CHECK_RETURN_ERR_SET(rc == napi_ok, std::make_shared("The type of value must be ValueType.")); return OK; } diff --git a/preferences/frameworks/js/napi/storage/src/napi_storage.cpp b/preferences/frameworks/js/napi/storage/src/napi_storage.cpp index 679ba6c2..4124c57e 100644 --- a/preferences/frameworks/js/napi/storage/src/napi_storage.cpp +++ b/preferences/frameworks/js/napi/storage/src/napi_storage.cpp @@ -154,7 +154,11 @@ napi_value StorageProxy::New(napi_env env, napi_callback_info info) obj->env_ = env; obj->value_ = std::move(preference); obj->uvQueue_ = std::make_shared(env); - NAPI_CALL(env, napi_wrap(env, thiz, obj, StorageProxy::Destructor, nullptr, nullptr)); + status = napi_wrap(env, thiz, obj, StorageProxy::Destructor, nullptr, nullptr); + if (status != napi_ok) { + delete obj; + return nullptr; + } return thiz; } diff --git a/preferences/frameworks/native/src/preferences_xml_utils.cpp b/preferences/frameworks/native/src/preferences_xml_utils.cpp index 587fd928..43b8657a 100644 --- a/preferences/frameworks/native/src/preferences_xml_utils.cpp +++ b/preferences/frameworks/native/src/preferences_xml_utils.cpp @@ -76,11 +76,12 @@ static void ReportXmlFileIsBroken(const std::string &fileName, const std::string PreferencesDfxManager::ReportDbFault(succreportParam); } -static bool RenameFromBackupFile(const std::string &fileName, const std::string &bundleName, bool &isReportCorrupt) +static bool RenameFromBackupFile(const std::string &fileName, const std::string &bundleName, + bool &isReportCorrupt, std::string &operationMsg) { std::string backupFileName = MakeFilePath(fileName, STR_BACKUP); if (!IsFileExist(backupFileName)) { - LOG_DEBUG("the backup file does not exist."); + operationMsg.append("backup file not exist."); return false; } xmlResetLastError(); @@ -93,11 +94,16 @@ static bool RenameFromBackupFile(const std::string &fileName, const std::string LOG_ERROR("restore XML file: %{public}s failed, errno is %{public}d, error is %{public}s.", ExtractFileName(fileName).c_str(), errCode, errMessage.c_str()); std::remove(backupFileName.c_str()); + if (errCode == REQUIRED_KEY_NOT_AVAILABLE || errCode == REQUIRED_KEY_REVOKED) { + return false; + } + operationMsg.append("backup file corrupt."); isReportCorrupt = true; return false; } if (std::rename(backupFileName.c_str(), fileName.c_str())) { LOG_ERROR("failed to restore backup errno %{public}d.", errno); + operationMsg.append("rename file from backup file failed."); return false; } isReportCorrupt = false; @@ -131,6 +137,7 @@ static xmlDoc *XmlReadFile(const std::string &fileName, const std::string &bundl bool isReport = false; PreferencesFileLock fileLock(MakeFilePath(fileName, STR_LOCK), dataGroupId); int errCode = 0; + std::string operationMsg = "read file: "; if (IsFileExist(fileName)) { doc = ReadFile(fileName, errCode); if (doc != nullptr) { @@ -146,14 +153,14 @@ static xmlDoc *XmlReadFile(const std::string &fileName, const std::string &bundl if (!RenameToBrokenFile(fileName)) { return doc; } + operationMsg.append("current file corrupt."); isReport = true; } - if (RenameFromBackupFile(fileName, bundleName, isReport)) { + if (RenameFromBackupFile(fileName, bundleName, isReport, operationMsg)) { doc = ReadFile(fileName, errCode); } if (isReport) { - const std::string operationMsg = "operation: failed to read XML format file."; ReportXmlFileIsBroken(fileName, bundleName, operationMsg, errCode); } return doc; @@ -332,6 +339,7 @@ bool XmlSaveFormatFileEnc( } bool isReport = false; + std::string operationMsg = "write file: "; auto [ret, errCode] = SaveFormatFileEnc(fileName, doc); if (!ret) { xmlErrorPtr xmlErr = xmlGetLastError(); @@ -341,13 +349,14 @@ bool XmlSaveFormatFileEnc( if (errCode == REQUIRED_KEY_NOT_AVAILABLE || errCode == REQUIRED_KEY_REVOKED) { return false; } + if (IsFileExist(fileName)) { RenameToBrokenFile(fileName); + operationMsg.append("original file exist."); isReport = true; } - RenameFromBackupFile(fileName, bundleName, isReport); + RenameFromBackupFile(fileName, bundleName, isReport, operationMsg); if (isReport) { - const std::string operationMsg = "operation: failed to save XML format file."; ReportXmlFileIsBroken(fileName, bundleName, operationMsg, errCode); } return false; diff --git a/relational_store/frameworks/cj/include/native_log.h b/relational_store/frameworks/cj/include/native_log.h index 2abae3fa..6bab6681 100644 --- a/relational_store/frameworks/cj/include/native_log.h +++ b/relational_store/frameworks/cj/include/native_log.h @@ -28,14 +28,14 @@ #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 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__); \ -} +#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 index c517c850..9fb62f3c 100644 --- a/relational_store/frameworks/cj/include/relational_store_ffi.h +++ b/relational_store/frameworks/cj/include/relational_store_ffi.h @@ -16,241 +16,238 @@ #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 "relational_store_utils.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 "ffi_remote_data.h" +#include "js_ability.h" #include "logger.h" +#include "napi_base_context.h" +#include "native_log.h" +#include "rdb_common.h" #include "rdb_errno.h" +#include "rdb_helper.h" #include "rdb_open_callback.h" #include "rdb_sql_utils.h" +#include "rdb_store_config.h" +#include "relational_store_impl_rdbpredicatesproxy.h" +#include "relational_store_impl_rdbstore.h" +#include "relational_store_impl_resultsetproxy.h" +#include "relational_store_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 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 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 void FfiOHOSRelationalStoreDeleteRdbStoreConfig( + OHOS::AbilityRuntime::Context *context, StoreConfig config, int32_t *errCode); - FFI_EXPORT int64_t FfiOHOSRelationalStoreRdbPredicatesConstructor(const char* tableName); +FFI_EXPORT int64_t FfiOHOSRelationalStoreRdbPredicatesConstructor(const char *tableName); - FFI_EXPORT int32_t FfiOHOSRelationalStoreInDevices(int64_t id, const char** devicesArray, int64_t devicesSize); +FFI_EXPORT int32_t FfiOHOSRelationalStoreInDevices(int64_t id, const char **devicesArray, int64_t devicesSize); - FFI_EXPORT CArrStr FfiOHOSRelationalStoreGetAllColumnNames(int64_t id); +FFI_EXPORT CArrStr FfiOHOSRelationalStoreGetAllColumnNames(int64_t id); - FFI_EXPORT int32_t FfiOHOSRelationalStoreGetColumnCount(int64_t id, int32_t *errCode); +FFI_EXPORT int32_t FfiOHOSRelationalStoreGetColumnCount(int64_t id, int32_t *errCode); - FFI_EXPORT int32_t FfiOHOSRelationalStoreGetRowCount(int64_t id, int32_t *errCode); +FFI_EXPORT int32_t FfiOHOSRelationalStoreGetRowCount(int64_t id, int32_t *errCode); - FFI_EXPORT int32_t FfiOHOSRelationalStoreGetRowIndex(int64_t id, int32_t *errCode); +FFI_EXPORT int32_t FfiOHOSRelationalStoreGetRowIndex(int64_t id, int32_t *errCode); - FFI_EXPORT bool FfiOHOSRelationalStoreIsAtFirstRow(int64_t id, int32_t *errCode); +FFI_EXPORT bool FfiOHOSRelationalStoreIsAtFirstRow(int64_t id, int32_t *errCode); - FFI_EXPORT bool FfiOHOSRelationalStoreIsAtLastRow(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 FfiOHOSRelationalStoreIsEnded(int64_t id, int32_t *errCode); - FFI_EXPORT bool FfiOHOSRelationalStoreIsStarted(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 bool FfiOHOSRelationalStoreIsClosed(int64_t id, int32_t *errCode); - FFI_EXPORT int32_t FfiOHOSRelationalStoreInAllDevices(int64_t id); +FFI_EXPORT int32_t FfiOHOSRelationalStoreInAllDevices(int64_t id); - FFI_EXPORT int32_t FfiOHOSRelationalStoreBeginWrap(int64_t id); +FFI_EXPORT int32_t FfiOHOSRelationalStoreBeginWrap(int64_t id); - FFI_EXPORT int32_t FfiOHOSRelationalStoreEndWrap(int64_t id); +FFI_EXPORT int32_t FfiOHOSRelationalStoreEndWrap(int64_t id); - FFI_EXPORT int32_t FfiOHOSRelationalStoreOr(int64_t id); +FFI_EXPORT int32_t FfiOHOSRelationalStoreOr(int64_t id); - FFI_EXPORT int32_t FfiOHOSRelationalStoreAnd(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 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 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 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 FfiOHOSRelationalStoreIsNull(int64_t id, const char *field); - FFI_EXPORT int32_t FfiOHOSRelationalStoreIsNotNull(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 FfiOHOSRelationalStoreLike(int64_t id, const char *field, const char *value); - FFI_EXPORT int32_t FfiOHOSRelationalStoreOrderByAsc(int64_t id, const char* field); +FFI_EXPORT int32_t FfiOHOSRelationalStoreGlob(int64_t id, const char *field, const char *value); - FFI_EXPORT int32_t FfiOHOSRelationalStoreOrderByDesc(int64_t id, const char* field); +FFI_EXPORT int32_t FfiOHOSRelationalStoreOrderByAsc(int64_t id, const char *field); - FFI_EXPORT int32_t FfiOHOSRelationalStoreDistinct(int64_t id); +FFI_EXPORT int32_t FfiOHOSRelationalStoreOrderByDesc(int64_t id, const char *field); - FFI_EXPORT int32_t FfiOHOSRelationalStoreLimitAs(int64_t id, int32_t value); +FFI_EXPORT int32_t FfiOHOSRelationalStoreDistinct(int64_t id); - FFI_EXPORT int32_t FfiOHOSRelationalStoreOffsetAs(int64_t id, int32_t rowOffset); +FFI_EXPORT int32_t FfiOHOSRelationalStoreLimitAs(int64_t id, int32_t value); - FFI_EXPORT int32_t FfiOHOSRelationalStoreGroupBy(int64_t id, const char** fieldsArray, int64_t fieldsSize); +FFI_EXPORT int32_t FfiOHOSRelationalStoreOffsetAs(int64_t id, int32_t rowOffset); - FFI_EXPORT int32_t FfiOHOSRelationalStoreIndexedBy(int64_t id, const char* field); +FFI_EXPORT int32_t FfiOHOSRelationalStoreGroupBy(int64_t id, const char **fieldsArray, int64_t fieldsSize); - FFI_EXPORT int32_t FfiOHOSRelationalStoreLessThanOrEqualTo(int64_t id, const char* field, ValueType value); +FFI_EXPORT int32_t FfiOHOSRelationalStoreIndexedBy(int64_t id, const char *field); - FFI_EXPORT int32_t FfiOHOSRelationalStoreEqualTo(int64_t id, const char* field, ValueType value); +FFI_EXPORT int32_t FfiOHOSRelationalStoreLessThanOrEqualTo(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 FfiOHOSRelationalStoreEqualTo(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 FfiOHOSRelationalStoreGreaterThanOrEqualTo(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 FfiOHOSRelationalStoreGreaterThan(int64_t id, const char *field, ValueType value); - FFI_EXPORT int32_t FfiOHOSRelationalStoreLessThan(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 FfiOHOSRelationalStoreBetween(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 FfiOHOSRelationalStoreIn(int64_t id, const char* field, ValueType* values, int64_t valuesSize); +FFI_EXPORT int32_t FfiOHOSRelationalStoreBetween( + int64_t id, const char *field, ValueType lowValue, ValueType highValue); - FFI_EXPORT int32_t FfiOHOSRelationalStoreNotIn(int64_t id, const char* field, ValueType* values, - int64_t valuesSize); +FFI_EXPORT int32_t FfiOHOSRelationalStoreIn(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 int32_t FfiOHOSRelationalStoreNotIn(int64_t id, const char *field, ValueType *values, int64_t valuesSize); - FFI_EXPORT int64_t FfiOHOSRelationalStoreQuery(int64_t id, int64_t predicatesId, char** columns, - int64_t columnsSize, int32_t *errCode); +FFI_EXPORT int32_t FfiOHOSRelationalStoreNotEqualTo(int64_t id, const char *field, ValueType value); - FFI_EXPORT int64_t FfiOHOSRelationalStoreRemoteQuery(int64_t id, char* device, int64_t predicatesId, char** columns, - int64_t columnsSize); +FFI_EXPORT int64_t FfiOHOSRelationalStoreQuery( + int64_t id, int64_t predicatesId, char **columns, int64_t columnsSize, int32_t *errCode); - FFI_EXPORT int64_t FfiOHOSRelationalStoreUpdate(int64_t id, ValuesBucket valuesBucket, int64_t predicatesId, - NativeRdb::ConflictResolution conflictResolution, 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 FfiOHOSRelationalStoreDelete(int64_t id, int64_t predicatesId, int32_t *errCode); +FFI_EXPORT int64_t FfiOHOSRelationalStoreUpdate(int64_t id, ValuesBucket valuesBucket, int64_t predicatesId, + NativeRdb::ConflictResolution conflictResolution, int32_t *errCode); - FFI_EXPORT int32_t FfiOHOSRelationalStoreSetDistributedTables(int64_t id, char** tables, int64_t tablesSize); +FFI_EXPORT int64_t FfiOHOSRelationalStoreDelete(int64_t id, int64_t predicatesId, int32_t *errCode); - FFI_EXPORT int32_t FfiOHOSRelationalStoreSetDistributedTablesType(int64_t id, char** tables, int64_t tablesSize, - int32_t type); +FFI_EXPORT int32_t FfiOHOSRelationalStoreSetDistributedTables(int64_t id, char **tables, int64_t tablesSize); - FFI_EXPORT int32_t FfiOHOSRelationalStoreSetDistributedTablesConfig(int64_t id, char** tables, int64_t tablesSize, - int32_t type, RetDistributedConfig distributedConfig); +FFI_EXPORT int32_t FfiOHOSRelationalStoreSetDistributedTablesType( + int64_t id, char **tables, int64_t tablesSize, int32_t type); - FFI_EXPORT char* FfiOHOSRelationalStoreObtainDistributedTableName(int64_t id, const char* device, char* table); +FFI_EXPORT int32_t FfiOHOSRelationalStoreSetDistributedTablesConfig( + int64_t id, char **tables, int64_t tablesSize, int32_t type, RetDistributedConfig distributedConfig); - FFI_EXPORT int32_t FfiOHOSRelationalStoreRollBack(int64_t id); +FFI_EXPORT char *FfiOHOSRelationalStoreObtainDistributedTableName(int64_t id, const char *device, char *table); - FFI_EXPORT int32_t FfiOHOSRelationalStoreCommit(int64_t id); +FFI_EXPORT int32_t FfiOHOSRelationalStoreRollBack(int64_t id); - FFI_EXPORT int32_t FfiOHOSRelationalStoreBeginTransaction(int64_t id); +FFI_EXPORT int32_t FfiOHOSRelationalStoreCommit(int64_t id); - FFI_EXPORT int32_t FfiOHOSRelationalStoreBackUp(int64_t id, const char* destName); +FFI_EXPORT int32_t FfiOHOSRelationalStoreBeginTransaction(int64_t id); - FFI_EXPORT int32_t FfiOHOSRelationalStoreReStore(int64_t id, const char* srcName); +FFI_EXPORT int32_t FfiOHOSRelationalStoreBackUp(int64_t id, const char *destName); - FFI_EXPORT int64_t FfiOHOSRelationalStoreInsert(int64_t id, const char* table, ValuesBucket valuesBucket, - int32_t conflict, int32_t *errCode); +FFI_EXPORT int32_t FfiOHOSRelationalStoreReStore(int64_t id, const char *srcName); - FFI_EXPORT void FfiOHOSRelationalStoreExecuteSql(int64_t id, const char* sql, int32_t *errCode); +FFI_EXPORT int64_t FfiOHOSRelationalStoreInsert( + int64_t id, const char *table, ValuesBucket valuesBucket, int32_t conflict, int32_t *errCode); - FFI_EXPORT CArrSyncResult FfiOHOSRelationalStoreSync(int64_t id, int32_t mode, int64_t predicatesId, - int32_t *errCode); +FFI_EXPORT void FfiOHOSRelationalStoreExecuteSql(int64_t id, const char *sql, int32_t *errCode); - FFI_EXPORT double FfiOHOSRelationalStoreGetDouble(int64_t id, int32_t columnIndex, int32_t* rtnCode); +FFI_EXPORT CArrSyncResult FfiOHOSRelationalStoreSync(int64_t id, int32_t mode, int64_t predicatesId, int32_t *errCode); - FFI_EXPORT bool FfiOHOSRelationalStoreGoToRow(int64_t id, int32_t position, int32_t* rtnCode); +FFI_EXPORT double FfiOHOSRelationalStoreGetDouble(int64_t id, int32_t columnIndex, int32_t *rtnCode); - FFI_EXPORT bool FfiOHOSRelationalStoreGoToPreviousRow(int64_t id, int32_t* rtnCode); +FFI_EXPORT bool FfiOHOSRelationalStoreGoToRow(int64_t id, int32_t position, int32_t *rtnCode); - FFI_EXPORT bool FfiOHOSRelationalStoreGoToLastRow(int64_t id, int32_t* rtnCode); +FFI_EXPORT bool FfiOHOSRelationalStoreGoToPreviousRow(int64_t id, int32_t *rtnCode); - FFI_EXPORT char* FfiOHOSRelationalStoreGetColumnName(int64_t id, int32_t columnIndex, int32_t* rtnCode); +FFI_EXPORT bool FfiOHOSRelationalStoreGoToLastRow(int64_t id, int32_t *rtnCode); - FFI_EXPORT bool FfiOHOSRelationalStoreIsColumnNull(int64_t id, int32_t columnIndex, int32_t* rtnCode); +FFI_EXPORT char *FfiOHOSRelationalStoreGetColumnName(int64_t id, int32_t columnIndex, int32_t *rtnCode); - FFI_EXPORT Asset FfiOHOSRelationalStoreGetAsset(int64_t id, int32_t columnIndex, int32_t* rtnCode); +FFI_EXPORT bool FfiOHOSRelationalStoreIsColumnNull(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 Asset FfiOHOSRelationalStoreGetAsset(int64_t id, int32_t columnIndex, int32_t *rtnCode); - FFI_EXPORT char* FfiOHOSRelationalStoreGetString(int64_t id, int32_t columnIndex, int32_t* rtnCode); +FFI_EXPORT int32_t FfiOHOSRelationalStoreClose(int64_t id); - FFI_EXPORT bool FfiOHOSRelationalStoreGoToFirstRow(int64_t id, int32_t* rtnCode); +FFI_EXPORT int32_t FfiOHOSRelationalStoreGetColumnIndex(int64_t id, char *columnName, int32_t *rtnCode); - FFI_EXPORT int64_t FfiOHOSRelationalStoreGetLong(int64_t id, int32_t columnIndex, int32_t* rtnCode); +FFI_EXPORT char *FfiOHOSRelationalStoreGetString(int64_t id, int32_t columnIndex, int32_t *rtnCode); - FFI_EXPORT bool FfiOHOSRelationalStoreGoToNextRow(int64_t id, int32_t* rtnCode); +FFI_EXPORT bool FfiOHOSRelationalStoreGoToFirstRow(int64_t id, int32_t *rtnCode); - FFI_EXPORT CArrUI8 FfiOHOSRelationalStoreGetBlob(int64_t id, int32_t columnIndex, int32_t* rtnCode); +FFI_EXPORT int64_t FfiOHOSRelationalStoreGetLong(int64_t id, int32_t columnIndex, int32_t *rtnCode); - FFI_EXPORT bool FfiOHOSRelationalStoreGoTo(int64_t id, int32_t offset, int32_t* rtnCode); +FFI_EXPORT bool FfiOHOSRelationalStoreGoToNextRow(int64_t id, int32_t *rtnCode); - FFI_EXPORT Assets FfiOHOSRelationalStoreGetAssets(int64_t id, int32_t columnIndex, int32_t* rtnCode); +FFI_EXPORT CArrUI8 FfiOHOSRelationalStoreGetBlob(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 bool FfiOHOSRelationalStoreGoTo(int64_t id, int32_t offset, int32_t *rtnCode); - FFI_EXPORT int32_t FfiOHOSRelationalStoreBatchInsert(int64_t id, const char* tableName, ValuesBucket* values, - int64_t valuesSize, int64_t* insertNum); +FFI_EXPORT Assets FfiOHOSRelationalStoreGetAssets(int64_t id, int32_t columnIndex, int32_t *rtnCode); - FFI_EXPORT int64_t FfiOHOSRelationalStoreQuerySql(int64_t id, const char *sql, ValueType *bindArgs, int64_t size, - int32_t* errCode); +FFI_EXPORT int32_t FfiOHOSRelationalStoreCleanDirtyData(int64_t id, const char *tableName, uint64_t cursor); - FFI_EXPORT void FfiOHOSRelationalStoreExecuteSqlBindArgs(int64_t id, char* sql, ValueType* bindArgs, - int64_t bindArgsSize, int32_t *errCode); +FFI_EXPORT int32_t FfiOHOSRelationalStoreBatchInsert( + int64_t id, const char *tableName, ValuesBucket *values, int64_t valuesSize, int64_t *insertNum); - FFI_EXPORT ValuesBucket FfiOHOSRelationalStoreGetRow(int64_t id, int32_t *errCode); +FFI_EXPORT int64_t FfiOHOSRelationalStoreQuerySql( + int64_t id, const char *sql, ValueType *bindArgs, int64_t size, int32_t *errCode); - FFI_EXPORT int32_t FfiOHOSRelationalStoreOn(int64_t id, const char *event, bool interProcess, void (*callback)(), - void (*callbackRef)()); +FFI_EXPORT void FfiOHOSRelationalStoreExecuteSqlBindArgs( + int64_t id, char *sql, ValueType *bindArgs, int64_t bindArgsSize, int32_t *errCode); - FFI_EXPORT int32_t FfiOHOSRelationalStoreOnArrStr(int64_t id, int32_t subscribeType, int64_t callbackId); +FFI_EXPORT ValuesBucket FfiOHOSRelationalStoreGetRow(int64_t id, int32_t *errCode); - FFI_EXPORT int32_t FfiOHOSRelationalStoreOnChangeInfo(int64_t id, int32_t subscribeType, int64_t callbackId); +FFI_EXPORT int32_t FfiOHOSRelationalStoreOn( + int64_t id, const char *event, bool interProcess, void (*callback)(), void (*callbackRef)()); - FFI_EXPORT int32_t FfiOHOSRelationalStoreOnProgressDetails(int64_t id, int64_t callbackId); +FFI_EXPORT int32_t FfiOHOSRelationalStoreOnArrStr(int64_t id, int32_t subscribeType, int64_t callbackId); - FFI_EXPORT int32_t FfiOHOSRelationalStoreOff(int64_t id, const char *event, bool interProcess, void (*callback)()); +FFI_EXPORT int32_t FfiOHOSRelationalStoreOnChangeInfo(int64_t id, int32_t subscribeType, int64_t callbackId); - FFI_EXPORT int32_t FfiOHOSRelationalStoreOffAll(int64_t id, const char *event, bool interProcess); +FFI_EXPORT int32_t FfiOHOSRelationalStoreOnProgressDetails(int64_t id, int64_t callbackId); - FFI_EXPORT int32_t FfiOHOSRelationalStoreOffArrStrChangeInfo(int64_t id, int32_t subscribeType, int64_t callbackId); +FFI_EXPORT int32_t FfiOHOSRelationalStoreOff(int64_t id, const char *event, bool interProcess, void (*callback)()); - FFI_EXPORT int32_t FfiOHOSRelationalStoreOffArrStrChangeInfoAll(int64_t id, int32_t subscribeType); +FFI_EXPORT int32_t FfiOHOSRelationalStoreOffAll(int64_t id, const char *event, bool interProcess); - FFI_EXPORT int32_t FfiOHOSRelationalStoreOffProgressDetails(int64_t id, int64_t callbackId); +FFI_EXPORT int32_t FfiOHOSRelationalStoreOffArrStrChangeInfo(int64_t id, int32_t subscribeType, int64_t callbackId); - FFI_EXPORT int32_t FfiOHOSRelationalStoreOffProgressDetailsAll(int64_t id); +FFI_EXPORT int32_t FfiOHOSRelationalStoreOffArrStrChangeInfoAll(int64_t id, int32_t subscribeType); - FFI_EXPORT int32_t FfiOHOSRelationalStoreEmit(int64_t id, const char *event); +FFI_EXPORT int32_t FfiOHOSRelationalStoreOffProgressDetails(int64_t id, int64_t callbackId); - FFI_EXPORT int32_t FfiOHOSRelationalStoreCloudSync(int64_t id, int32_t mode, CArrStr tables, int64_t callbackId); +FFI_EXPORT int32_t FfiOHOSRelationalStoreOffProgressDetailsAll(int64_t id); - FFI_EXPORT int32_t FfiOHOSRelationalStoreGetVersion(int64_t id, int32_t *errCode); +FFI_EXPORT int32_t FfiOHOSRelationalStoreEmit(int64_t id, const char *event); - FFI_EXPORT void FfiOHOSRelationalStoreSetVersion(int64_t id, int32_t value, int32_t *errCode); +FFI_EXPORT int32_t FfiOHOSRelationalStoreCloudSync(int64_t id, int32_t mode, CArrStr tables, int64_t callbackId); - FFI_EXPORT ModifyTime FfiOHOSRelationalStoreGetModifyTime(int64_t id, char *cTable, char* cColumnName, - CArrPRIKeyType cPrimaryKeys, int32_t *errCode); -} -} +FFI_EXPORT int32_t FfiOHOSRelationalStoreGetVersion(int64_t id, int32_t *errCode); + +FFI_EXPORT void FfiOHOSRelationalStoreSetVersion(int64_t id, int32_t value, int32_t *errCode); + +FFI_EXPORT ModifyTime FfiOHOSRelationalStoreGetModifyTime( + int64_t id, char *cTable, char *cColumnName, CArrPRIKeyType cPrimaryKeys, int32_t *errCode); } +} // namespace Relational +} // namespace OHOS #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 index 2e776ccc..0fb1ce6d 100644 --- a/relational_store/frameworks/cj/include/relational_store_impl_rdbpredicatesproxy.h +++ b/relational_store/frameworks/cj/include/relational_store_impl_rdbpredicatesproxy.h @@ -16,97 +16,99 @@ #ifndef RELATIONAL_STORE_IMPL_RDBPREDICATES_FFI_H #define RELATIONAL_STORE_IMPL_RDBPREDICATES_FFI_H -#include "relational_store_utils.h" #include +#include + #include "ffi_remote_data.h" #include "rdb_predicates.h" -#include +#include "relational_store_utils.h" #include "value_object.h" namespace OHOS { namespace Relational { - class RdbPredicatesImpl : public OHOS::FFI::FFIData { - public: - OHOS::FFI::RuntimeType* GetRuntimeType() override - { - return GetClassType(); - } +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); - explicit RdbPredicatesImpl(const char* tableName); + void InDevices(const char **devicesArray, int64_t devicesSize); - explicit RdbPredicatesImpl(std::shared_ptr predicates); + void InAllDevices(); - void InDevices(const char** devicesArray, int64_t devicesSize); + void BeginWrap(); - void InAllDevices(); + void EndWrap(); - void BeginWrap(); + void Or(); - void EndWrap(); + void And(); - void Or(); + void Contains(const char *field, const char *value); - void And(); + void BeginsWith(const char *field, const char *value); - void Contains(const char* field, const char* value); + void EndsWith(const char *field, const char *value); - void BeginsWith(const char* field, const char* value); + void IsNull(const char *field); - void EndsWith(const char* field, const char* value); + void IsNotNull(const char *field); - void IsNull(const char* field); + void Like(const char *field, const char *value); - void IsNotNull(const char* field); + void Glob(const char *field, const char *value); - void Like(const char* field, const char* value); + void OrderByAsc(const char *field); - void Glob(const char* field, const char* value); + void OrderByDesc(const char *field); - void OrderByAsc(const char* field); + void Distinct(); - void OrderByDesc(const char* field); + void LimitAs(int32_t value); - void Distinct(); + void OffsetAs(int32_t rowOffset); - void LimitAs(int32_t value); + void GroupBy(const char **fieldsArray, int64_t fieldsSize); - void OffsetAs(int32_t rowOffset); - - void GroupBy(const char** fieldsArray, int64_t fieldsSize); + void IndexedBy(const char *field); - void IndexedBy(const char* field); + void LessThanOrEqualTo(const char *field, ValueType value); - void LessThanOrEqualTo(const char* field, ValueType value); + void EqualTo(const char *field, ValueType value); - void EqualTo(const char* field, ValueType value); + void GreaterThanOrEqualTo(const char *field, ValueType value); - void GreaterThanOrEqualTo(const char* field, ValueType value); + void GreaterThan(const char *field, ValueType value); - void GreaterThan(const char* field, ValueType value); + void NotBetween(const char *field, ValueType lowValue, ValueType highValue); - void NotBetween(const char* field, ValueType lowValue, ValueType highValue); + void LessThan(const char *field, ValueType value); - void LessThan(const char* field, ValueType value); + void Between(const char *field, ValueType lowValue, ValueType highValue); - void Between(const char* field, ValueType lowValue, ValueType highValue); + void In(const char *field, ValueType *values, int64_t valuesSize); - void In(const char* field, ValueType* values, int64_t valuesSize); + void NotIn(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); - void NotEqualTo(const char* field, ValueType value); + std::shared_ptr GetPredicates(); - std::shared_ptr GetPredicates(); - private: - std::shared_ptr predicates_; +private: + std::shared_ptr predicates_; - friend class OHOS::FFI::RuntimeType; + friend class OHOS::FFI::RuntimeType; - friend class OHOS::FFI::TypeBase; + friend class OHOS::FFI::TypeBase; - static OHOS::FFI::RuntimeType* GetClassType(); - }; -} -} + static OHOS::FFI::RuntimeType *GetClassType(); +}; +} // namespace Relational +} // namespace OHOS #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 index 405f9711..762ca4ea 100644 --- a/relational_store/frameworks/cj/include/relational_store_impl_rdbstore.h +++ b/relational_store/frameworks/cj/include/relational_store_impl_rdbstore.h @@ -17,164 +17,160 @@ #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 "cj_lambda.h" #include "ffi_remote_data.h" #include "napi_base_context.h" +#include "napi_rdb_js_utils.h" +#include "rdb_common.h" #include "rdb_store.h" +#include "rdb_store_config.h" #include "rdb_types.h" -#include "rdb_common.h" -#include "napi_rdb_js_utils.h" -#include "cj_lambda.h" +#include "relational_store_impl_resultsetproxy.h" +#include "relational_store_utils.h" namespace OHOS { namespace Relational { - class RdbStoreObserverImpl : public DistributedRdb::RdbStoreObserver { - public: - enum FuncType : int32_t { - NoParam = 0, - ParamArrStr, - ParamChangeInfo - }; - RdbStoreObserverImpl(std::function *callback, const std::function& callbackRef); - RdbStoreObserverImpl(int64_t id, FuncType type, int32_t mode = DistributedRdb::REMOTE); - ~RdbStoreObserverImpl() override = default; - void OnChange() override - { - m_callbackRef(); - }; - void OnChange(const std::vector &devices) override - { - carrStrFunc(devices); - }; - void OnChange(const DistributedRdb::Origin &origin, const PrimaryFields &fields, - DistributedRdb::RdbStoreObserver::ChangeInfo &&changeInfo) override - { - if (mode_ != DistributedRdb::CLOUD_DETAIL && mode_ != DistributedRdb::LOCAL_DETAIL) { - RdbStoreObserver::OnChange(origin, fields, std::move(changeInfo)); - return; - } - changeInfoFunc(origin, fields, std::move(changeInfo)); - }; - - int64_t GetCallBackId() - { - return callbackId; - }; - std::function *GetCallBack(); - private: - std::function *m_callback; - std::function m_callbackRef; - int32_t mode_ = DistributedRdb::REMOTE; - int64_t callbackId; - FuncType funcType; - std::function func; - std::function &devices)> carrStrFunc; - std::function changeInfoFunc; +class RdbStoreObserverImpl : public DistributedRdb::RdbStoreObserver { +public: + enum FuncType : int32_t { NoParam = 0, ParamArrStr, ParamChangeInfo }; + RdbStoreObserverImpl(std::function *callback, const std::function &callbackRef); + RdbStoreObserverImpl(int64_t id, FuncType type, int32_t mode = DistributedRdb::REMOTE); + ~RdbStoreObserverImpl() override = default; + void OnChange() override + { + m_callbackRef(); + }; + void OnChange(const std::vector &devices) override + { + carrStrFunc(devices); + }; + void OnChange(const DistributedRdb::Origin &origin, const PrimaryFields &fields, + DistributedRdb::RdbStoreObserver::ChangeInfo &&changeInfo) override + { + if (mode_ != DistributedRdb::CLOUD_DETAIL && mode_ != DistributedRdb::LOCAL_DETAIL) { + RdbStoreObserver::OnChange(origin, fields, std::move(changeInfo)); + return; + } + changeInfoFunc(origin, fields, std::move(changeInfo)); }; - class SyncObserverImpl : public DistributedRdb::DetailProgressObserver { - public: - SyncObserverImpl(int64_t id); - ~SyncObserverImpl() override = default; - void ProgressNotification(const DistributedRdb::Details &details) override - { - func(details); - }; - - int64_t GetCallBackId() - { - return callbackId; - }; - private: - int64_t callbackId; - std::function func; + int64_t GetCallBackId() + { + return callbackId; }; + std::function *GetCallBack(); - class RdbStoreImpl : public OHOS::FFI::FFIData { - public: - OHOS::FFI::RuntimeType* GetRuntimeType() override - { - return GetClassType(); - } +private: + std::function *m_callback; + std::function m_callbackRef; + int32_t mode_ = DistributedRdb::REMOTE; + int64_t callbackId; + FuncType funcType; + std::function func; + std::function &devices)> carrStrFunc; + std::function + changeInfoFunc; +}; - 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); - int32_t SetDistributedTables(char** tables, int64_t tablesSize); - int32_t SetDistributedTables(char** tables, int64_t tablesSize, int32_t type); - int32_t 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); - int32_t RegisterObserverArrStr(int32_t subscribeType, int64_t callbackId); - int32_t RegisterObserverChangeInfo(int32_t subscribeType, int64_t callbackId); - int32_t RegisterObserverProgressDetails(int64_t callbackId); - 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); - int32_t UnRegisterObserverArrStrChangeInfo(int32_t subscribeType, int64_t callbackId); - int32_t UnRegisterObserverArrStrChangeInfoAll(int32_t subscribeType); - int32_t UnRegisterObserverProgressDetails(int64_t callbackId); - int32_t UnRegisterObserverProgressDetailsAll(); - int32_t CloudSync(int32_t mode, CArrStr tables, int64_t callbackId); - int32_t GetVersion(int32_t &errCode); - void SetVersion(int32_t value, int32_t &errCode); - ModifyTime GetModifyTime(char *cTable, char *cColumnName, CArrPRIKeyType &cPrimaryKeys, int32_t &errCode); - - private: - friend class OHOS::FFI::RuntimeType; - friend class OHOS::FFI::TypeBase; - static OHOS::FFI::RuntimeType* GetClassType(); - std::vector bindArgs; - std::shared_ptr rdbStore_; - std::vector newKey; - std::list> observers_[DistributedRdb::SUBSCRIBE_MODE_MAX]; - std::map>> localObservers_; - std::map>> localSharedObservers_; - std::list> syncObservers_; +class SyncObserverImpl : public DistributedRdb::DetailProgressObserver { +public: + SyncObserverImpl(int64_t id); + ~SyncObserverImpl() override = default; + void ProgressNotification(const DistributedRdb::Details &details) override + { + func(details); }; - int64_t GetRdbStore(OHOS::AbilityRuntime::Context* context, StoreConfig config, - int32_t *errCode); + int64_t GetCallBackId() + { + return callbackId; + }; - void DeleteRdbStore(OHOS::AbilityRuntime::Context* context, const char* name, - int32_t *errCode); +private: + int64_t callbackId; + std::function func; +}; - void DeleteRdbStoreConfig(OHOS::AbilityRuntime::Context* context, StoreConfig config, - int32_t *errCode); -} -} +class RdbStoreImpl : public OHOS::FFI::FFIData { +public: + OHOS::FFI::RuntimeType *GetRuntimeType() override + { + return GetClassType(); + } -#endif + 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); + int32_t SetDistributedTables(char **tables, int64_t tablesSize); + int32_t SetDistributedTables(char **tables, int64_t tablesSize, int32_t type); + int32_t 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); + int32_t RegisterObserverArrStr(int32_t subscribeType, int64_t callbackId); + int32_t RegisterObserverChangeInfo(int32_t subscribeType, int64_t callbackId); + int32_t RegisterObserverProgressDetails(int64_t callbackId); + 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); + int32_t UnRegisterObserverArrStrChangeInfo(int32_t subscribeType, int64_t callbackId); + int32_t UnRegisterObserverArrStrChangeInfoAll(int32_t subscribeType); + int32_t UnRegisterObserverProgressDetails(int64_t callbackId); + int32_t UnRegisterObserverProgressDetailsAll(); + int32_t CloudSync(int32_t mode, CArrStr tables, int64_t callbackId); + int32_t GetVersion(int32_t &errCode); + void SetVersion(int32_t value, int32_t &errCode); + ModifyTime GetModifyTime(char *cTable, char *cColumnName, CArrPRIKeyType &cPrimaryKeys, int32_t &errCode); + +private: + friend class OHOS::FFI::RuntimeType; + friend class OHOS::FFI::TypeBase; + static OHOS::FFI::RuntimeType *GetClassType(); + std::vector bindArgs; + std::shared_ptr rdbStore_; + std::vector newKey; + std::list> observers_[DistributedRdb::SUBSCRIBE_MODE_MAX]; + std::map>> localObservers_; + std::map>> localSharedObservers_; + std::list> syncObservers_; +}; + +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); +} // namespace Relational +} // namespace OHOS + +#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 index 73d1f154..041f4f0b 100644 --- a/relational_store/frameworks/cj/include/relational_store_impl_resultsetproxy.h +++ b/relational_store/frameworks/cj/include/relational_store_impl_resultsetproxy.h @@ -16,18 +16,19 @@ #ifndef RELATIONAL_STORE_IMPL_RESULTSET_FFI_H #define RELATIONAL_STORE_IMPL_RESULTSET_FFI_H +#include + +#include "ffi_remote_data.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 + OHOS::FFI::RuntimeType *GetRuntimeType() override { return GetClassType(); } @@ -49,51 +50,51 @@ public: bool IsEnded(); bool IsStarted(); - + bool IsClosed(); - double GetDouble(int32_t columnIndex, int32_t* rtnCode); + double GetDouble(int32_t columnIndex, int32_t *rtnCode); - bool GoToRow(int32_t position, int32_t* rtnCode); + bool GoToRow(int32_t position, int32_t *rtnCode); - bool GoToPreviousRow(int32_t* rtnCode); + bool GoToPreviousRow(int32_t *rtnCode); - bool GoToLastRow(int32_t* rtnCode); + bool GoToLastRow(int32_t *rtnCode); - char* GetColumnName(int32_t columnIndex, int32_t* rtnCode); + char *GetColumnName(int32_t columnIndex, int32_t *rtnCode); - bool IsColumnNull(int32_t columnIndex, int32_t* rtnCode); + bool IsColumnNull(int32_t columnIndex, int32_t *rtnCode); - Asset GetAsset(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); + int32_t GetColumnIndex(char *columnName, int32_t *rtnCode); - char* GetString(int32_t columnIndex, int32_t* rtnCode); + char *GetString(int32_t columnIndex, int32_t *rtnCode); - bool GoToFirstRow(int32_t* rtnCode); + bool GoToFirstRow(int32_t *rtnCode); - int64_t GetLong(int32_t columnIndex, int32_t* rtnCode); + int64_t GetLong(int32_t columnIndex, int32_t *rtnCode); - bool GoToNextRow(int32_t* rtnCode); + bool GoToNextRow(int32_t *rtnCode); - CArrUI8 GetBlob(int32_t columnIndex, int32_t* rtnCode); + CArrUI8 GetBlob(int32_t columnIndex, int32_t *rtnCode); - bool GoTo(int32_t offset, int32_t* rtnCode); + bool GoTo(int32_t offset, int32_t *rtnCode); - Assets GetAssets(int32_t columnIndex, int32_t* rtnCode); + Assets GetAssets(int32_t columnIndex, int32_t *rtnCode); - ValuesBucket GetRow(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(); + static OHOS::FFI::RuntimeType *GetClassType(); }; -} -} +} // namespace Relational +} // namespace OHOS #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 index 6376030e..c76fc437 100644 --- a/relational_store/frameworks/cj/include/relational_store_utils.h +++ b/relational_store/frameworks/cj/include/relational_store_utils.h @@ -16,173 +16,171 @@ #ifndef RELATIONAL_STORE_UTILS_H #define RELATIONAL_STORE_UTILS_H -#include "value_object.h" -#include "securec.h" #include "rdb_store.h" #include "rdb_types.h" +#include "securec.h" +#include "value_object.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; - }; - - CArrStr VectorToCArrStr(const std::vector &devices); - - std::vector CArrStrToVector(CArrStr carr); - - 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); - - struct RetPRIKeyType { - int64_t integer; - double dou; - char* string; - uint8_t tag; - }; - - std::variant RetPRIKeyTypeToVariant(RetPRIKeyType &value); - - RetPRIKeyType VariantToRetPRIKeyType(const std::variant &value); - - struct CArrPRIKeyType { - RetPRIKeyType* head; - int64_t size; - }; - - std::vector CArrPRIKeyTypeToPRIKeyArray(CArrPRIKeyType &cPrimaryKeys); - - struct ModifyTime { - RetPRIKeyType* key; - uint64_t* value; - int64_t size; - }; - - ModifyTime MapToModifyTime(std::map &map, int32_t &errCode); - - struct RetChangeInfo { - char* table; - int32_t type; - CArrPRIKeyType inserted; - CArrPRIKeyType updated; - CArrPRIKeyType deleted; - }; - - struct CArrRetChangeInfo { - RetChangeInfo* head; - int64_t size; - }; - - CArrPRIKeyType VectorToCArrPRIKeyType(std::vector arr); - - RetChangeInfo ToRetChangeInfo(const DistributedRdb::Origin &origin, - DistributedRdb::RdbStoreObserver::ChangeInfo::iterator info); - - CArrRetChangeInfo ToCArrRetChangeInfo(const DistributedRdb::Origin &origin, - const DistributedRdb::RdbStoreObserver::PrimaryFields &fields, - DistributedRdb::RdbStoreObserver::ChangeInfo &&changeInfo); - - struct CStatistic { - uint32_t total; - uint32_t successful; - uint32_t failed; - uint32_t remained; - }; - - CStatistic ToStatistic(DistributedRdb::Statistic statistic); - - struct CTableDetails { - CStatistic upload; - CStatistic download; - }; - - CTableDetails ToCTableDetails(DistributedRdb::TableDetail detail); - - struct CDetails { - char** key; - CTableDetails* value; - int64_t size; - }; - - CDetails ToCDetails(DistributedRdb::TableDetails details); - - struct CProgressDetails { - int32_t schedule; - int32_t code; - CDetails details; - }; - - CProgressDetails ToCProgressDetails(const DistributedRdb::Details &details); - - struct RetDistributedConfig { - bool autoSync; - }; -} -} +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; +}; + +CArrStr VectorToCArrStr(const std::vector &devices); + +std::vector CArrStrToVector(CArrStr carr); + +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); + +struct RetPRIKeyType { + int64_t integer; + double dou; + char *string; + uint8_t tag; +}; + +std::variant RetPRIKeyTypeToVariant(RetPRIKeyType &value); + +RetPRIKeyType VariantToRetPRIKeyType(const std::variant &value); + +struct CArrPRIKeyType { + RetPRIKeyType *head; + int64_t size; +}; + +std::vector CArrPRIKeyTypeToPRIKeyArray(CArrPRIKeyType &cPrimaryKeys); + +struct ModifyTime { + RetPRIKeyType *key; + uint64_t *value; + int64_t size; +}; + +ModifyTime MapToModifyTime(std::map &map, int32_t &errCode); + +struct RetChangeInfo { + char *table; + int32_t type; + CArrPRIKeyType inserted; + CArrPRIKeyType updated; + CArrPRIKeyType deleted; +}; + +struct CArrRetChangeInfo { + RetChangeInfo *head; + int64_t size; +}; + +CArrPRIKeyType VectorToCArrPRIKeyType(std::vector arr); + +RetChangeInfo ToRetChangeInfo( + const DistributedRdb::Origin &origin, DistributedRdb::RdbStoreObserver::ChangeInfo::iterator info); + +CArrRetChangeInfo ToCArrRetChangeInfo(const DistributedRdb::Origin &origin, + const DistributedRdb::RdbStoreObserver::PrimaryFields &fields, + DistributedRdb::RdbStoreObserver::ChangeInfo &&changeInfo); + +struct CStatistic { + uint32_t total; + uint32_t successful; + uint32_t failed; + uint32_t remained; +}; + +CStatistic ToStatistic(DistributedRdb::Statistic statistic); + +struct CTableDetails { + CStatistic upload; + CStatistic download; +}; + +CTableDetails ToCTableDetails(DistributedRdb::TableDetail detail); + +struct CDetails { + char **key; + CTableDetails *value; + int64_t size; +}; + +CDetails ToCDetails(DistributedRdb::TableDetails details); + +struct CProgressDetails { + int32_t schedule; + int32_t code; + CDetails details; +}; + +CProgressDetails ToCProgressDetails(const DistributedRdb::Details &details); + +struct RetDistributedConfig { + bool autoSync; +}; +} // namespace Relational +} // namespace OHOS #endif \ 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 index 21a6f058..25149ce4 100644 --- a/relational_store/frameworks/cj/src/relational_store_ffi.cpp +++ b/relational_store/frameworks/cj/src/relational_store_ffi.cpp @@ -14,995 +14,992 @@ */ #include "relational_store_ffi.h" -#include "relational_store_utils.h" + +#include +#include + +#include "cj_lambda.h" #include "napi_rdb_js_utils.h" #include "rdb_errno.h" -#include "cj_lambda.h" -#include -#include +#include "relational_store_utils.h" 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; - } - return nativeRdbStore->SetDistributedTables(tables, tablesSize); - } - - int32_t FfiOHOSRelationalStoreSetDistributedTablesType(int64_t id, char** tables, int64_t tablesSize, int32_t type) - { - auto nativeRdbStore = FFIData::GetData(id); - if (nativeRdbStore == nullptr) { - return -1; - } - return nativeRdbStore->SetDistributedTables(tables, tablesSize, type); - } - - int32_t FfiOHOSRelationalStoreSetDistributedTablesConfig(int64_t id, char** tables, int64_t tablesSize, - int32_t type, RetDistributedConfig distributedConfig) - { - auto nativeRdbStore = FFIData::GetData(id); - if (nativeRdbStore == nullptr) { - return -1; - } - DistributedRdb::DistributedConfig config{distributedConfig.autoSync}; - return nativeRdbStore->SetDistributedTables(tables, tablesSize, type, config); - } - - 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, int32_t *errCode) - { - auto nativeResultSet = FFIData::GetData(id); - if (nativeResultSet == nullptr) { - *errCode = -1; - return -1; - } - return nativeResultSet->GetColumnCount(); - } - - int32_t FfiOHOSRelationalStoreGetRowCount(int64_t id, int32_t *errCode) - { - auto nativeResultSet = FFIData::GetData(id); - if (nativeResultSet == nullptr) { - *errCode = -1; - return -1; - } - return nativeResultSet->GetRowCount(); - } - - int32_t FfiOHOSRelationalStoreGetRowIndex(int64_t id, int32_t *errCode) - { - auto nativeResultSet = FFIData::GetData(id); - if (nativeResultSet == nullptr) { - *errCode = -1; - 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 FfiOHOSRelationalStoreOnArrStr(int64_t id, int32_t subscribeType, int64_t callbackId) - { - auto nativeRdbStore = FFIData::GetData(id); - if (nativeRdbStore == nullptr) { - return -1; - } - return nativeRdbStore->RegisterObserverArrStr(subscribeType, callbackId); - } - - int32_t FfiOHOSRelationalStoreOnChangeInfo(int64_t id, int32_t subscribeType, int64_t callbackId) - { - auto nativeRdbStore = FFIData::GetData(id); - if (nativeRdbStore == nullptr) { - return -1; - } - return nativeRdbStore->RegisterObserverChangeInfo(subscribeType, callbackId); - } - - int32_t FfiOHOSRelationalStoreOnProgressDetails(int64_t id, int64_t callbackId) - { - auto nativeRdbStore = FFIData::GetData(id); - if (nativeRdbStore == nullptr) { - return -1; - } - return nativeRdbStore->RegisterObserverProgressDetails(callbackId); - } - - 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 FfiOHOSRelationalStoreOffArrStrChangeInfo(int64_t id, int32_t subscribeType, int64_t callbackId) - { - auto nativeRdbStore = FFIData::GetData(id); - if (nativeRdbStore == nullptr) { - return -1; - } - return nativeRdbStore->UnRegisterObserverArrStrChangeInfo(subscribeType, callbackId); - } - - int32_t FfiOHOSRelationalStoreOffArrStrChangeInfoAll(int64_t id, int32_t subscribeType) - { - auto nativeRdbStore = FFIData::GetData(id); - if (nativeRdbStore == nullptr) { - return -1; - } - return nativeRdbStore->UnRegisterObserverArrStrChangeInfoAll(subscribeType); - } - - int32_t FfiOHOSRelationalStoreOffProgressDetails(int64_t id, int64_t callbackId) - { - auto nativeRdbStore = FFIData::GetData(id); - if (nativeRdbStore == nullptr) { - return -1; - } - return nativeRdbStore->UnRegisterObserverProgressDetails(callbackId); - } - - int32_t FfiOHOSRelationalStoreOffProgressDetailsAll(int64_t id) - { - auto nativeRdbStore = FFIData::GetData(id); - if (nativeRdbStore == nullptr) { - return -1; - } - return nativeRdbStore->UnRegisterObserverProgressDetailsAll(); - } - - int32_t FfiOHOSRelationalStoreEmit(int64_t id, const char *event) - { - auto nativeRdbStore = FFIData::GetData(id); - if (nativeRdbStore == nullptr) { - return -1; - } - return nativeRdbStore->Emit(event); - } - - int32_t FfiOHOSRelationalStoreCloudSync(int64_t id, int32_t mode, CArrStr tables, int64_t callbackId) - { - auto nativeRdbStore = FFIData::GetData(id); - if (nativeRdbStore == nullptr) { - return -1; - } - return nativeRdbStore->CloudSync(mode, tables, callbackId); - } - - int32_t FfiOHOSRelationalStoreGetVersion(int64_t id, int32_t *errCode) - { - auto nativeRdbStore = FFIData::GetData(id); - if (nativeRdbStore == nullptr) { - *errCode = -1; - return -1; - } - return nativeRdbStore->GetVersion(*errCode); - } - - void FfiOHOSRelationalStoreSetVersion(int64_t id, int32_t value, int32_t *errCode) - { - auto nativeRdbStore = FFIData::GetData(id); - if (nativeRdbStore == nullptr) { - *errCode = -1; - return; - } - nativeRdbStore->SetVersion(value, *errCode); - } - - ModifyTime FfiOHOSRelationalStoreGetModifyTime(int64_t id, char *cTable, char* cColumnName, - CArrPRIKeyType cPrimaryKeys, int32_t *errCode) - { - auto nativeRdbStore = FFIData::GetData(id); - if (nativeRdbStore == nullptr) { - *errCode = -1; - return ModifyTime{0}; - } - return nativeRdbStore->GetModifyTime(cTable, cColumnName, cPrimaryKeys, *errCode); +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; + } + return nativeRdbStore->SetDistributedTables(tables, tablesSize); +} + +int32_t FfiOHOSRelationalStoreSetDistributedTablesType(int64_t id, char **tables, int64_t tablesSize, int32_t type) +{ + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + return -1; + } + return nativeRdbStore->SetDistributedTables(tables, tablesSize, type); +} + +int32_t FfiOHOSRelationalStoreSetDistributedTablesConfig( + int64_t id, char **tables, int64_t tablesSize, int32_t type, RetDistributedConfig distributedConfig) +{ + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + return -1; + } + DistributedRdb::DistributedConfig config{ distributedConfig.autoSync }; + return nativeRdbStore->SetDistributedTables(tables, tablesSize, type, config); +} + +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, int32_t *errCode) +{ + auto nativeResultSet = FFIData::GetData(id); + if (nativeResultSet == nullptr) { + *errCode = -1; + return -1; + } + return nativeResultSet->GetColumnCount(); +} + +int32_t FfiOHOSRelationalStoreGetRowCount(int64_t id, int32_t *errCode) +{ + auto nativeResultSet = FFIData::GetData(id); + if (nativeResultSet == nullptr) { + *errCode = -1; + return -1; + } + return nativeResultSet->GetRowCount(); +} + +int32_t FfiOHOSRelationalStoreGetRowIndex(int64_t id, int32_t *errCode) +{ + auto nativeResultSet = FFIData::GetData(id); + if (nativeResultSet == nullptr) { + *errCode = -1; + 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 FfiOHOSRelationalStoreOnArrStr(int64_t id, int32_t subscribeType, int64_t callbackId) +{ + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + return -1; + } + return nativeRdbStore->RegisterObserverArrStr(subscribeType, callbackId); +} + +int32_t FfiOHOSRelationalStoreOnChangeInfo(int64_t id, int32_t subscribeType, int64_t callbackId) +{ + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + return -1; + } + return nativeRdbStore->RegisterObserverChangeInfo(subscribeType, callbackId); +} + +int32_t FfiOHOSRelationalStoreOnProgressDetails(int64_t id, int64_t callbackId) +{ + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + return -1; + } + return nativeRdbStore->RegisterObserverProgressDetails(callbackId); +} + +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 FfiOHOSRelationalStoreOffArrStrChangeInfo(int64_t id, int32_t subscribeType, int64_t callbackId) +{ + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + return -1; + } + return nativeRdbStore->UnRegisterObserverArrStrChangeInfo(subscribeType, callbackId); +} + +int32_t FfiOHOSRelationalStoreOffArrStrChangeInfoAll(int64_t id, int32_t subscribeType) +{ + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + return -1; + } + return nativeRdbStore->UnRegisterObserverArrStrChangeInfoAll(subscribeType); +} + +int32_t FfiOHOSRelationalStoreOffProgressDetails(int64_t id, int64_t callbackId) +{ + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + return -1; + } + return nativeRdbStore->UnRegisterObserverProgressDetails(callbackId); +} + +int32_t FfiOHOSRelationalStoreOffProgressDetailsAll(int64_t id) +{ + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + return -1; + } + return nativeRdbStore->UnRegisterObserverProgressDetailsAll(); +} + +int32_t FfiOHOSRelationalStoreEmit(int64_t id, const char *event) +{ + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + return -1; + } + return nativeRdbStore->Emit(event); +} + +int32_t FfiOHOSRelationalStoreCloudSync(int64_t id, int32_t mode, CArrStr tables, int64_t callbackId) +{ + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + return -1; + } + return nativeRdbStore->CloudSync(mode, tables, callbackId); +} + +int32_t FfiOHOSRelationalStoreGetVersion(int64_t id, int32_t *errCode) +{ + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + *errCode = -1; + return -1; + } + return nativeRdbStore->GetVersion(*errCode); +} + +void FfiOHOSRelationalStoreSetVersion(int64_t id, int32_t value, int32_t *errCode) +{ + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + *errCode = -1; + return; + } + nativeRdbStore->SetVersion(value, *errCode); +} + +ModifyTime FfiOHOSRelationalStoreGetModifyTime( + int64_t id, char *cTable, char *cColumnName, CArrPRIKeyType cPrimaryKeys, int32_t *errCode) +{ + auto nativeRdbStore = FFIData::GetData(id); + if (nativeRdbStore == nullptr) { + *errCode = -1; + return ModifyTime{ 0 }; + } + return nativeRdbStore->GetModifyTime(cTable, cColumnName, cPrimaryKeys, *errCode); } } +} // namespace Relational +} // namespace OHOS diff --git a/relational_store/frameworks/js/napi/relationalstore/src/entry_point.cpp b/relational_store/frameworks/js/napi/relationalstore/src/entry_point.cpp index 713b0da8..bea9362c 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/entry_point.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/entry_point.cpp @@ -13,13 +13,13 @@ * limitations under the License. */ +#include "napi/native_api.h" +#include "napi_rdb_const_properties.h" #include "napi_rdb_predicates.h" #include "napi_rdb_store.h" #include "napi_rdb_store_helper.h" -#include "napi_rdb_const_properties.h" #include "napi_result_set.h" #include "napi_transaction.h" -#include "napi/native_api.h" using namespace OHOS::RelationalStoreJsKit; 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 1a88b3da..f9d2d82d 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 @@ -155,8 +155,8 @@ napi_value AsyncCall::Async(napi_env env, std::shared_ptr context) } auto report = (record_.total_.times_.load() - record_.completed_.times_.load()) / EXCEPT_DELTA; if (report > record_.reportTimes_ && record_.executed_ != nullptr) { - LOG_WARN("Warning:Times:(C:%{public}" PRId64 ", E:%{public}" PRId64 ", F:%{public}" PRId64") Last time(" - "C:%{public}" PRId64 ", E:%{public}" PRId64 ", F:%{public}" PRId64")", + LOG_WARN("Warning:Times:(C:%{public}" PRId64 ", E:%{public}" PRId64 ", F:%{public}" PRId64 ") Last time(" + "C:%{public}" PRId64 ", E:%{public}" PRId64 ", F:%{public}" PRId64 ")", record_.total_.times_.load(), record_.executed_->times_.load(), record_.completed_.times_.load(), record_.total_.lastTime_, record_.executed_->lastTime_, record_.completed_.lastTime_); } 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 4e6f768b..f4b963fb 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 @@ -14,23 +14,24 @@ */ #include "napi_rdb_const_properties.h" + +#include "js_utils.h" #include "rdb_common.h" #include "rdb_store.h" -#include "js_utils.h" #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) #include "rdb_store_config.h" #include "rdb_types.h" -using OHOS::DistributedRdb::SyncMode; using OHOS::DistributedRdb::SubscribeMode; +using OHOS::DistributedRdb::SyncMode; #endif -using OHOS::NativeRdb::SecurityLevel; -using OHOS::NativeRdb::ConflictResolution; -using OHOS::DistributedRdb::ProgressCode; using OHOS::DistributedRdb::DistributedTableType; +using OHOS::DistributedRdb::ProgressCode; +using OHOS::NativeRdb::ConflictResolution; +using OHOS::NativeRdb::SecurityLevel; -#define SET_NAPI_PROPERTY(object, prop, value) \ +#define SET_NAPI_PROPERTY(object, prop, value) \ napi_set_named_property((env), (object), (prop), AppDataMgrJsKit::JSUtils::Convert2JSValue((env), (value))) namespace OHOS::RelationalStoreJsKit { 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 8ad6b20a..795433e7 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,8 +21,8 @@ namespace OHOS { namespace RelationalStoreJsKit { using JsErrorCode = OHOS::RelationalStoreJsKit::JsErrorCode; static constexpr JsErrorCode JS_ERROR_CODE_MSGS[] = { - { E_NOT_STAGE_MODE, 14801001, "Only supported in stage mode." }, - { E_DATA_GROUP_ID_INVALID, 14801002, "The data group id is invalid." }, + { E_NOT_STAGE_MODE, 14801001, "The operation is supported in the stage model only." }, + { E_DATA_GROUP_ID_INVALID, 14801002, "Invalid data ground ID." }, { 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." }, @@ -34,8 +34,8 @@ static constexpr JsErrorCode JS_ERROR_CODE_MSGS[] = { { NativeRdb::E_GET_DATAOBSMGRCLIENT_FAIL, 14801050, "Failed to get DataObsMgrClient." }, { NativeRdb::E_TYPE_MISMATCH, 14800051, "The type of the distributed table does not match." }, { NativeRdb::E_SQLITE_FULL, 14800029, "SQLite: The database is full." }, - { NativeRdb::E_NOT_SUPPORT_THE_SQL, 14800021, "SQLite: Generic error."}, - { NativeRdb::E_ATTACHED_DATABASE_EXIST, 14800016, "The database is already attached." }, + { NativeRdb::E_NOT_SUPPORT_THE_SQL, 14800021, "SQLite: Generic error." }, + { NativeRdb::E_ATTACHED_DATABASE_EXIST, 14800016, "The database alias already exists." }, { NativeRdb::E_SQLITE_ERROR, 14800021, "SQLite: Generic error." }, { NativeRdb::E_SQLITE_CORRUPT, 14800011, "Database corrupted." }, { NativeRdb::E_SQLITE_ABORT, 14800022, "SQLite: Callback routine requested an abort." }, @@ -54,18 +54,6 @@ static constexpr JsErrorCode JS_ERROR_CODE_MSGS[] = { { NativeRdb::E_NOT_SUPPORT, 801, "Capability not support." }, }; -static constexpr bool IsIncreasing() -{ - for (size_t i = 1; i < sizeof(JS_ERROR_CODE_MSGS) / sizeof(JsErrorCode); i++) { - if (JS_ERROR_CODE_MSGS[i].status <= JS_ERROR_CODE_MSGS[i - 1].status) { - return false; - } - } - return true; -} - -static_assert(IsIncreasing()); - const std::optional GetJsErrorCode(int32_t errorCode) { auto jsErrorCode = JsErrorCode{ errorCode, -1, "" }; 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 2e2fd8eb..17dfdd59 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 @@ -333,7 +333,7 @@ int32_t Convert2Value(napi_env env, napi_value input, CryptoParam &cryptoParam) NAPI_CALL_RETURN_ERR(GetNamedProperty(env, input, "kdfAlgo", cryptoParam.kdfAlgo, true), napi_invalid_arg); NAPI_CALL_RETURN_ERR( GetNamedProperty(env, input, "cryptoPageSize", cryptoParam.cryptoPageSize, true), napi_invalid_arg); - + return napi_ok; } @@ -375,7 +375,7 @@ int32_t Convert2Value(napi_env env, napi_value jsValue, RdbConfig &rdbConfig) GetNamedProperty(env, jsValue, "pluginLibs", rdbConfig.pluginLibs, true); ASSERT(OK == status, "get pluginLibs failed.", napi_invalid_arg); - + status = GetNamedProperty(env, jsValue, "haMode", rdbConfig.haMode, true); ASSERT(OK == status, "get haMode failed.", napi_invalid_arg); @@ -388,7 +388,9 @@ template<> int32_t Convert2Value(napi_env env, napi_value jsValue, TransactionOptions &transactionOptions) { int32_t status = GetNamedProperty(env, jsValue, "transactionType", transactionOptions.transactionType, true); - ASSERT(OK == status, "get transactionType failed.", napi_invalid_arg); + bool checked = transactionOptions.transactionType >= Transaction::DEFERRED && + transactionOptions.transactionType <= Transaction::EXCLUSIVE; + ASSERT(OK == status && checked, "get transactionType failed.", napi_invalid_arg); return napi_ok; } diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_predicates.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_predicates.cpp index 1c239ee1..c31850be 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_predicates.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_predicates.cpp @@ -15,11 +15,11 @@ #define LOG_TAG "NapiRdbPredicates" #include "napi_rdb_predicates.h" +#include "js_df_manager.h" #include "js_utils.h" #include "logger.h" #include "napi_rdb_error.h" #include "napi_rdb_trace.h" -#include "js_df_manager.h" using namespace OHOS::Rdb; using namespace OHOS::NativeRdb; @@ -483,7 +483,6 @@ napi_value RdbPredicatesProxy::NotLike(napi_env env, napi_callback_info info) return thiz; } - napi_value RdbPredicatesProxy::Glob(napi_env env, napi_callback_info info) { napi_value thiz = nullptr; 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 3980c9b3..9cabb705 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 @@ -22,6 +22,7 @@ #include #include +#include "js_df_manager.h" #include "js_native_api.h" #include "js_native_api_types.h" #include "js_utils.h" @@ -35,7 +36,6 @@ #include "rdb_errno.h" #include "rdb_sql_statistic.h" #include "securec.h" -#include "js_df_manager.h" #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) #include "rdb_utils.h" @@ -621,7 +621,7 @@ napi_value RdbStoreProxy::Insert(napi_env env, napi_callback_info info) CHECK_RETURN(OK == ParseTableName(env, argv[0], context)); CHECK_RETURN(OK == ParseValuesBucket(env, argv[1], context)); CHECK_RETURN_SET_E(!HasDuplicateAssets(context->valuesBucket), std::make_shared("Duplicate assets " - "are not allowed")); + "are not allowed")); if (argc == 3) { CHECK_RETURN(OK == ParseConflictResolution(env, argv[2], context)); } @@ -647,10 +647,8 @@ int ParseTransactionOptions( { context->transactionOptions.transactionType = Transaction::DEFERRED; if (argc > 0 && !JSUtils::IsNull(env, argv[0])) { - auto code = JSUtils::Convert2Value(env, argv[0], context->transactionOptions); - bool isValid = context->transactionOptions.transactionType >= Transaction::DEFERRED && - context->transactionOptions.transactionType <= Transaction::EXCLUSIVE; - CHECK_RETURN_SET(code == napi_ok && isValid, std::make_shared("options", "a transactionOptions")); + auto status = JSUtils::Convert2Value(env, argv[0], context->transactionOptions); + CHECK_RETURN_SET(status == napi_ok, std::make_shared("options", "a transactionOptions")); } return OK; } @@ -664,7 +662,7 @@ napi_value RdbStoreProxy::BatchInsert(napi_env env, napi_callback_info info) CHECK_RETURN(OK == ParseTableName(env, argv[0], context)); CHECK_RETURN(OK == ParseValuesBuckets(env, argv[1], context)); CHECK_RETURN_SET_E(!HasDuplicateAssets(context->sharedValuesBuckets), - std::make_shared("Duplicate assets are not allowed")); + std::make_shared("Duplicate assets are not allowed")); }; auto exec = [context]() -> int { CHECK_RETURN_ERR(context->rdbStore != nullptr); @@ -968,7 +966,11 @@ napi_value RdbStoreProxy::Backup(napi_env env, napi_callback_info info) auto exec = [context]() -> int { CHECK_RETURN_ERR(context->rdbStore != nullptr); auto rdbStore = std::move(context->rdbStore); - return rdbStore->Backup(context->tableName, context->newKey); + auto res = rdbStore->Backup(context->tableName, context->newKey); + if (res == E_DB_NOT_EXIST) { + return E_OK; + } + return res; }; auto output = [context](napi_env env, napi_value &result) { napi_status status = napi_get_undefined(env, &result); @@ -2200,4 +2202,4 @@ napi_value RdbStoreProxy::CreateTransaction(napi_env env, napi_callback_info inf return ASYNC_CALL(env, context); } } // namespace RelationalStoreJsKit -} // namespace OHOS +} // namespace OHOS \ No newline at end of file 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 cd4fea76..fc0dc23e 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 @@ -19,6 +19,7 @@ #include #include #include + #include "logger.h" #include "napi_async_call.h" #include "napi_rdb_error.h" 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 669ade03..d4753435 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 @@ -103,7 +103,6 @@ void NapiRdbStoreObserver::OnChange() [](napi_env env, int &argc, napi_value *argv) {}); } - NapiRdbStoreObserver::JSChangeInfo::JSChangeInfo(const Origin &origin, ChangeInfo::iterator info) { table = info->first; 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 ff24ca2b..29a5f318 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 @@ -17,13 +17,13 @@ #include +#include "js_df_manager.h" #include "js_utils.h" #include "logger.h" #include "napi_rdb_error.h" #include "napi_rdb_js_utils.h" #include "napi_rdb_sendable_utils.h" #include "napi_rdb_trace.h" -#include "js_df_manager.h" #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) #include "rdb_result_set_bridge.h" #include "string_ex.h" @@ -92,8 +92,8 @@ napi_value ResultSetProxy::Initialize(napi_env env, napi_callback_info info) LOG_ERROR("(T:%{public}d) freed! data:0x%016" PRIXPTR, tid, uintptr_t(data) & LOWER_24_BITS_MASK); } if (data != hint) { - LOG_ERROR("RdbStoreProxy memory corrupted! data:0x%016" PRIXPTR "hint:0x%016" PRIXPTR, - uintptr_t(data), uintptr_t(hint)); + LOG_ERROR("RdbStoreProxy memory corrupted! data:0x%016" PRIXPTR "hint:0x%016" PRIXPTR, uintptr_t(data), + uintptr_t(hint)); return; } ResultSetProxy *proxy = reinterpret_cast(data); diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_transaction.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_transaction.cpp index f4b6f4e7..53188809 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_transaction.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_transaction.cpp @@ -260,8 +260,7 @@ napi_value TransactionProxy::Initialize(napi_env env, napi_callback_info info) LOG_ERROR("(T:%{public}d) freed! data:0x%016" PRIXPTR, tid, uintptr_t(data) & LOWER_24_BITS_MASK); } if (data != hint) { - LOG_ERROR("memory corrupted! data:0x%016" PRIXPTR "hint:0x%016" PRIXPTR, uintptr_t(data), - uintptr_t(hint)); + LOG_ERROR("memory corrupted! data:0x%016" PRIXPTR "hint:0x%016" PRIXPTR, uintptr_t(data), uintptr_t(hint)); return; } TransactionProxy *proxy = reinterpret_cast(data); @@ -282,8 +281,7 @@ struct CommitContext : public TransactionContext { int32_t Parse(napi_env env, size_t argc, napi_value *argv, napi_value self) { GetInstance(self); - ASSERT_RETURN_SET_ERROR( - transaction_ != nullptr, std::make_shared("transaction", "a transaction.")); + ASSERT_RETURN_SET_ERROR(transaction_ != nullptr, std::make_shared("transaction", "a transaction.")); return OK; } }; @@ -316,8 +314,7 @@ struct RollbackContext : public TransactionContext { int32_t Parse(napi_env env, size_t argc, napi_value *argv, napi_value self) { GetInstance(self); - ASSERT_RETURN_SET_ERROR( - transaction_ != nullptr, std::make_shared("transaction", "a transaction.")); + ASSERT_RETURN_SET_ERROR(transaction_ != nullptr, std::make_shared("transaction", "a transaction.")); return OK; } }; @@ -352,8 +349,7 @@ struct DeleteContext : public TransactionContext { { ASSERT_RETURN_SET_ERROR(argc == 1, std::make_shared("1")); GetInstance(self); - ASSERT_RETURN_SET_ERROR( - transaction_ != nullptr, std::make_shared("transaction", "a transaction.")); + ASSERT_RETURN_SET_ERROR(transaction_ != nullptr, std::make_shared("transaction", "a transaction.")); CHECK_RETURN_ERR(ParseRdbPredicatesProxy(env, argv[0], rdbPredicates) == OK); return OK; } @@ -394,8 +390,7 @@ struct UpdateContext : public TransactionContext { { ASSERT_RETURN_SET_ERROR(argc == 2 || argc == 3, std::make_shared("2 to 3")); GetInstance(self); - ASSERT_RETURN_SET_ERROR( - transaction_ != nullptr, std::make_shared("transaction", "a transaction.")); + ASSERT_RETURN_SET_ERROR(transaction_ != nullptr, std::make_shared("transaction", "a transaction.")); CHECK_RETURN_ERR(ParseValuesBucket(env, argv[0], valuesBucket) == OK); CHECK_RETURN_ERR(ParseRdbPredicatesProxy(env, argv[1], rdbPredicates) == OK); // 'argv[2]' is an optional parameter @@ -445,8 +440,7 @@ struct InsertContext : public TransactionContext { { ASSERT_RETURN_SET_ERROR(argc == 2 || argc == 3, std::make_shared("2 to 3")); GetInstance(self); - ASSERT_RETURN_SET_ERROR( - transaction_ != nullptr, std::make_shared("transaction", "a transaction.")); + ASSERT_RETURN_SET_ERROR(transaction_ != nullptr, std::make_shared("transaction", "a transaction.")); CHECK_RETURN_ERR(JSUtils::Convert2Value(env, argv[0], tableName) == OK); CHECK_RETURN_ERR(ParseValuesBucket(env, argv[1], valuesBucket) == OK); // 'argv[2]' is an optional parameter @@ -496,8 +490,7 @@ struct BatchInsertContext : public TransactionContext { { ASSERT_RETURN_SET_ERROR(argc == 2, std::make_shared("2")); GetInstance(self); - ASSERT_RETURN_SET_ERROR( - transaction_ != nullptr, std::make_shared("transaction", "a transaction.")); + ASSERT_RETURN_SET_ERROR(transaction_ != nullptr, std::make_shared("transaction", "a transaction.")); ASSERT_RETURN_SET_ERROR( JSUtils::Convert2Value(env, argv[0], tableName) == OK, std::make_shared("table", "a string.")); CHECK_RETURN_ERR(ParseValuesBuckets(env, argv[1], valuesBuckets) == OK); @@ -541,8 +534,7 @@ struct QueryContext : public TransactionContext { { ASSERT_RETURN_SET_ERROR(argc == 1 || argc == 2, std::make_shared("1 to 2")); GetInstance(self); - ASSERT_RETURN_SET_ERROR( - transaction_ != nullptr, std::make_shared("transaction", "a transaction.")); + ASSERT_RETURN_SET_ERROR(transaction_ != nullptr, std::make_shared("transaction", "a transaction.")); CHECK_RETURN_ERR(ParseRdbPredicatesProxy(env, argv[0], rdbPredicates) == OK); if (argc > 1 && !JSUtils::IsNull(env, argv[1])) { ASSERT_RETURN_SET_ERROR(JSUtils::Convert2Value(env, argv[1], columns) == OK, @@ -587,8 +579,7 @@ struct QuerySqlContext : public TransactionContext { { ASSERT_RETURN_SET_ERROR(argc == 1 || argc == 2, std::make_shared("1 to 2")); GetInstance(self); - ASSERT_RETURN_SET_ERROR( - transaction_ != nullptr, std::make_shared("transaction", "a transaction.")); + ASSERT_RETURN_SET_ERROR(transaction_ != nullptr, std::make_shared("transaction", "a transaction.")); ASSERT_RETURN_SET_ERROR( JSUtils::Convert2Value(env, argv[0], sql) == OK, std::make_shared("sql", "a string.")); if (argc > 1 && !JSUtils::IsNull(env, argv[1])) { diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_uv_queue.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_uv_queue.cpp index 86073da7..adc23eb4 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_uv_queue.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_uv_queue.cpp @@ -21,8 +21,7 @@ namespace OHOS::RelationalStoreJsKit { using namespace OHOS::Rdb; -NapiUvQueue::NapiUvQueue(napi_env env, napi_value callback) - : env_(env) +NapiUvQueue::NapiUvQueue(napi_env env, napi_value callback) : env_(env) { napi_create_reference(env, callback, 1, &callback_); napi_get_uv_event_loop(env, &loop_); @@ -45,7 +44,7 @@ bool NapiUvQueue::operator==(napi_value value) void NapiUvQueue::CallFunction(NapiArgsGenerator genArgs) { - uv_work_t* work = new (std::nothrow) uv_work_t; + uv_work_t *work = new (std::nothrow) uv_work_t; if (work == nullptr) { return; } diff --git a/relational_store/frameworks/native/dfx/src/rdb_fault_hiview_reporter.cpp b/relational_store/frameworks/native/dfx/src/rdb_fault_hiview_reporter.cpp index 030d8441..168dbdef 100644 --- a/relational_store/frameworks/native/dfx/src/rdb_fault_hiview_reporter.cpp +++ b/relational_store/frameworks/native/dfx/src/rdb_fault_hiview_reporter.cpp @@ -108,8 +108,12 @@ std::string RdbFaultHiViewReporter::GetFileStatInfo(const DebugInfo &debugInfo) if (debugInfo.inode_ != debugInfo.oldInode_ && debugInfo.oldInode_ != 0) { oss << "<>0x" << std::hex << debugInfo.oldInode_; } + auto tokenId = IPCSkeleton::GetCallingTokenID(); + NativeTokenInfo tokenInfo; + AccessTokenKit::GetNativeTokenInfo(tokenId, tokenInfo); oss << " mode:0" << std::oct << (debugInfo.mode_ & permission) << " size:" << std::dec << debugInfo.size_ << " uid:" << std::dec << debugInfo.uid_ << " gid:" << std::dec << debugInfo.gid_ + << " process:" << tokenInfo.processName << " atim:" << GetTimeWithMilliseconds(debugInfo.atime_.sec_, debugInfo.atime_.nsec_) << " mtim:" << GetTimeWithMilliseconds(debugInfo.mtime_.sec_, debugInfo.mtime_.nsec_) << " ctim:" << GetTimeWithMilliseconds(debugInfo.ctime_.sec_, debugInfo.ctime_.nsec_); @@ -229,12 +233,9 @@ std::string RdbFaultHiViewReporter::GetBundleName(const RdbCorruptedEvent &event return eventInfo.bundleName; } auto tokenId = IPCSkeleton::GetCallingTokenID(); - auto tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId); - if ((tokenType == TOKEN_NATIVE) || (tokenType == TOKEN_SHELL)) { - NativeTokenInfo tokenInfo; - if (AccessTokenKit::GetNativeTokenInfo(tokenId, tokenInfo) == 0) { - return tokenInfo.processName; - } + NativeTokenInfo tokenInfo; + if (AccessTokenKit::GetNativeTokenInfo(tokenId, tokenInfo) == 0) { + return tokenInfo.processName; } return SqliteUtils::Anonymous(eventInfo.storeName); } diff --git a/relational_store/frameworks/native/rdb/include/connection.h b/relational_store/frameworks/native/rdb/include/connection.h index bf1678d8..7cb1291a 100644 --- a/relational_store/frameworks/native/rdb/include/connection.h +++ b/relational_store/frameworks/native/rdb/include/connection.h @@ -38,14 +38,17 @@ public: using Repairer = int32_t (*)(const RdbStoreConfig &config); using Deleter = int32_t (*)(const RdbStoreConfig &config); using Collector = std::map (*)(const RdbStoreConfig &config); + using Restorer = int32_t (*)(const RdbStoreConfig &config, const std::string &srcPath, const std::string &destPath); static std::pair Create(const RdbStoreConfig &config, bool isWriter); static int32_t Repair(const RdbStoreConfig &config); static int32_t Delete(const RdbStoreConfig &config); + static int32_t Restore(const RdbStoreConfig &config, const std::string &srcPath, const std::string &destPath); static std::map Collect(const RdbStoreConfig &config); static int32_t RegisterCreator(int32_t dbType, Creator creator); static int32_t RegisterRepairer(int32_t dbType, Repairer repairer); static int32_t RegisterDeleter(int32_t dbType, Deleter deleter); static int32_t RegisterCollector(int32_t dbType, Collector collector); + static int32_t RegisterRestorer(int32_t dbType, Restorer restorer); int32_t SetId(int32_t id); int32_t GetId() const; diff --git a/relational_store/frameworks/native/rdb/include/connection_pool.h b/relational_store/frameworks/native/rdb/include/connection_pool.h index df0ef137..231627df 100644 --- a/relational_store/frameworks/native/rdb/include/connection_pool.h +++ b/relational_store/frameworks/native/rdb/include/connection_pool.h @@ -66,19 +66,17 @@ public: private: struct ConnNode { - static constexpr uint32_t CHECK_POINT_INTERVAL = 5; // 5 min bool using_ = false; int32_t tid_ = 0; int32_t id_ = 0; std::chrono::steady_clock::time_point time_ = std::chrono::steady_clock::now(); - std::chrono::steady_clock::time_point failedTime_; std::shared_ptr connect_; explicit ConnNode(std::shared_ptr conn); std::shared_ptr GetConnect(); int64_t GetUsingTime() const; bool IsWriter() const; - int32_t Unused(int32_t count); + int32_t Unused(int32_t count, bool timeout); }; struct Container { @@ -123,10 +121,10 @@ private: int32_t GetMaxReaders(const RdbStoreConfig &config); std::shared_ptr Convert2AutoConn(std::shared_ptr node, bool isTrans = false); void ReleaseNode(std::shared_ptr node, bool reuse = true); - int RestoreByDbSqliteType(const std::string &newPath, const std::string &backupPath, SlaveStatus &slaveStatus); - int RestoreMasterDb(const std::string &newPath, const std::string &backupPath); + int RestoreMasterDb(const std::string &newPath, const std::string &backupPath, SlaveStatus &slaveStatus); bool CheckIntegrity(const std::string &dbPath); + static constexpr uint32_t CHECK_POINT_INTERVAL = 5; // 5 min static constexpr int LIMITATION = 1024; static constexpr uint32_t ITER_V1 = 5000; static constexpr uint32_t ITERS_COUNT = 2; @@ -144,6 +142,7 @@ private: bool transactionUsed_; std::atomic isInTransaction_ = false; std::atomic transCount_ = 0; + std::atomic failedTime_; }; } // namespace NativeRdb 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 338794a4..9bc0137b 100644 --- a/relational_store/frameworks/native/rdb/include/rdb_store_impl.h +++ b/relational_store/frameworks/native/rdb/include/rdb_store_impl.h @@ -158,6 +158,20 @@ protected: private: using Stmt = std::shared_ptr; using RdbParam = DistributedRdb::RdbSyncerParam; + using Options = DistributedRdb::RdbService::Option; + using Memo = DistributedRdb::PredicatesMemo; + class CloudTables { + public: + int32_t AddTables(const std::vector &tables); + int32_t RmvTables(const std::vector &tables); + bool Change(const std::string &table); + std::set Steal(); + + private: + std::mutex mutex_; + std::set tables_; + std::set changes_; + }; static void AfterOpen(const RdbParam ¶m, int32_t retry = 0); int InnerOpen(); @@ -170,7 +184,7 @@ private: std::pair BeginExecuteSql(const std::string &sql); int GetDataBasePath(const std::string &databasePath, std::string &backupFilePath); void DoCloudSync(const std::string &table); - int InnerSync(const DistributedRdb::RdbService::Option &option, const DistributedRdb::PredicatesMemo &predicates, + static int InnerSync(const RdbParam ¶m, const Options &option, const Memo &predicates, const AsyncDetail &async); int InnerBackup(const std::string &databasePath, const std::vector &destEncryptKey = std::vector()); @@ -227,8 +241,7 @@ private: std::mutex mutex_; std::shared_ptr connectionPool_ = nullptr; std::shared_ptr delayNotifier_ = nullptr; - std::shared_ptr> syncTables_ = nullptr; - std::set cloudTables_; + std::shared_ptr cloudInfo_ = std::make_shared(); std::map>> localObservers_; std::map>> localSharedObservers_; ConcurrentMap attachedInfo_; diff --git a/relational_store/frameworks/native/rdb/include/rdb_store_manager.h b/relational_store/frameworks/native/rdb/include/rdb_store_manager.h index b49aeb10..66153395 100644 --- a/relational_store/frameworks/native/rdb/include/rdb_store_manager.h +++ b/relational_store/frameworks/native/rdb/include/rdb_store_manager.h @@ -47,8 +47,8 @@ private: int ProcessOpenCallback(RdbStore &rdbStore, const RdbStoreConfig &config, int version, RdbOpenCallback &openCallback); bool IsConfigInvalidChanged(const std::string &path, RdbStoreConfig &config); + bool IsPermitted(const DistributedRdb::RdbSyncerParam ¶m); int32_t GetParamFromService(DistributedRdb::RdbSyncerParam ¶m); - int32_t GetPromiseFromService(DistributedRdb::RdbSyncerParam ¶m); static Param GetSyncParam(const RdbStoreConfig &config); static std::map Collector(const RdbStoreConfig &config); std::shared_ptr GetStoreFromCache(const RdbStoreConfig &config, const std::string &path); diff --git a/relational_store/frameworks/native/rdb/include/sqlite_connection.h b/relational_store/frameworks/native/rdb/include/sqlite_connection.h index 785ff1c0..7ac63b1f 100644 --- a/relational_store/frameworks/native/rdb/include/sqlite_connection.h +++ b/relational_store/frameworks/native/rdb/include/sqlite_connection.h @@ -44,6 +44,7 @@ public: static int32_t Delete(const RdbStoreConfig &config); static int32_t Delete(const std::string &path); static int32_t Repair(const RdbStoreConfig &config); + static int32_t Restore(const RdbStoreConfig &config, const std::string &srcPath, const std::string &destPath); static std::map Collect(const RdbStoreConfig &config); SqliteConnection(const RdbStoreConfig &config, bool isWriteConnection); ~SqliteConnection(); @@ -127,6 +128,7 @@ private: bool IsDbVersionBelowSlave(); static std::pair> InnerCreate(const RdbStoreConfig &config, bool isWrite); + static int CopyDb(const RdbStoreConfig &config, const std::string &srcPath, const std::string &destPath); static constexpr SqliteConnection::Suffix FILE_SUFFIXES[] = { {"", "DB"}, {"-shm", "SHM"}, @@ -138,6 +140,7 @@ private: }; static constexpr const char *MERGE_ASSETS_FUNC = "merge_assets"; static constexpr const char *MERGE_ASSET_FUNC = "merge_asset"; + static constexpr int CHECKPOINT_TIME = 1000; static constexpr int DEFAULT_BUSY_TIMEOUT_MS = 2000; static constexpr int BACKUP_PAGES_PRE_STEP = 12800; // 1024 * 4 * 12800 == 50m static constexpr int BACKUP_PRE_WAIT_TIME = 10; @@ -146,10 +149,12 @@ private: static constexpr uint32_t NO_ITER = 0; static constexpr uint32_t DB_INDEX = 0; static constexpr uint32_t WAL_INDEX = 2; + static constexpr uint32_t ITER_V1 = 5000; static const int32_t regCreator_; static const int32_t regRepairer_; static const int32_t regDeleter_; static const int32_t regCollector_; + static const int32_t regRestorer_; std::atomic backupId_; sqlite3 *dbHandle_; 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 effef70e..373b4627 100644 --- a/relational_store/frameworks/native/rdb/include/sqlite_global_config.h +++ b/relational_store/frameworks/native/rdb/include/sqlite_global_config.h @@ -31,7 +31,8 @@ public: static constexpr int DB_JOURNAL_SIZE = 1024 * 1024; /* default file size : 1M */ static constexpr ssize_t DB_WAL_SIZE_LIMIT_MIN = 20 * 1024 * 1024; /* default wal file maximum size : 20M */ static constexpr ssize_t DB_WAL_WARNING_SIZE = 256 * 1024 * 1024; /* default wal file maximum size : 256M */ - static constexpr ssize_t DB_WAL_SIZE_LIMIT_MAX = 512 * 1024 * 1024; /* default wal file maximum size : 512M */ + static constexpr ssize_t DB_WAL_DEFAULT_SIZE = 0x20000000; /* default wal file size 512M */ + static constexpr ssize_t DB_WAL_SIZE_LIMIT_MAX = 0x7FFFFFFF; /* default wal file maximum size : 2G - 1 */ static constexpr int WAL_AUTO_CHECKPOINT = 100; /* 100 pages */ static constexpr int APP_DEFAULT_UMASK = 0002; static constexpr int SQLITE_MAX_COLUMN = 2000; diff --git a/relational_store/frameworks/native/rdb/include/sqlite_utils.h b/relational_store/frameworks/native/rdb/include/sqlite_utils.h index 3db62bd5..cfa7cf8e 100644 --- a/relational_store/frameworks/native/rdb/include/sqlite_utils.h +++ b/relational_store/frameworks/native/rdb/include/sqlite_utils.h @@ -57,6 +57,7 @@ public: static bool RenameFile(const std::string &srcFile, const std::string &destFile); static bool CopyFile(const std::string &srcFile, const std::string &destFile); static std::string Anonymous(const std::string &srcFile); + static std::string AnonySql(const std::string &sql); static ssize_t GetFileSize(const std::string &fileName); static bool IsSlaveDbName(const std::string &fileName); static std::string GetSlavePath(const std::string& name); 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 c274dd62..57a963f2 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 @@ -84,6 +84,18 @@ public: private: using Stmt = std::shared_ptr; using RdbParam = DistributedRdb::RdbSyncerParam; + class CloudTables { + public: + int32_t AddTables(const std::vector &tables); + int32_t RmvTables(const std::vector &tables); + bool Change(const std::string &table); + std::set Steal(); + + private: + std::mutex mutex_; + std::set tables_; + std::set changes_; + }; int InnerOpen(); void InitSyncerParam(const RdbStoreConfig &config, bool created); @@ -133,8 +145,7 @@ private: std::string fileType_; std::mutex mutex_; std::shared_ptr connectionPool_ = nullptr; - std::shared_ptr> syncTables_ = nullptr; - std::set cloudTables_; + std::shared_ptr cloudInfo_ = std::make_shared(); ConcurrentMap attachedInfo_; ConcurrentMap> trxConnMap_ = {}; std::list> transactions_; diff --git a/relational_store/frameworks/native/rdb/src/abs_predicates.cpp b/relational_store/frameworks/native/rdb/src/abs_predicates.cpp index 2f25b6be..b0e366d9 100644 --- a/relational_store/frameworks/native/rdb/src/abs_predicates.cpp +++ b/relational_store/frameworks/native/rdb/src/abs_predicates.cpp @@ -28,7 +28,7 @@ namespace OHOS { namespace NativeRdb { using namespace OHOS::Rdb; -static constexpr const char* FLAG[AbsPredicates::Origin::BUTT] = { "0x02", "0x0", "0x0" }; +static constexpr const char *FLAG[AbsPredicates::Origin::BUTT] = { "0x02", "0x0", "0x0" }; AbsPredicates::AbsPredicates() { Initial(); @@ -563,7 +563,7 @@ void AbsPredicates::AppendWhereClauseWithInOrNotIn( whereClause += field + StringUtils::SurroundWithFunction(methodName, ",", replaceValues); } -std::string AbsPredicates::GetStatement() const +std::string AbsPredicates::GetStatement() const { return SqliteSqlBuilder::BuildSqlStringFromPredicates(*this); } 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 11c2c298..f11e26b2 100644 --- a/relational_store/frameworks/native/rdb/src/abs_rdb_predicates.cpp +++ b/relational_store/frameworks/native/rdb/src/abs_rdb_predicates.cpp @@ -140,7 +140,7 @@ std::string AbsRdbPredicates::GetTableName() const std::string AbsRdbPredicates::ToString() const { std::string args; - for (const auto& item : GetWhereArgs()) { + for (const auto &item : GetWhereArgs()) { args += item + ", "; } return "TableName = " + GetTableName() + ", {WhereClause:" + GetWhereClause() + ", bindArgs:{" + args + "}" @@ -150,29 +150,29 @@ std::string AbsRdbPredicates::ToString() const + ", isSorted:" + std::to_string(IsSorted()) + "}"; } -AbsRdbPredicates* AbsRdbPredicates::InDevices(std::vector &devices) +AbsRdbPredicates *AbsRdbPredicates::InDevices(std::vector &devices) { predicates_.devices_ = devices; return this; } -AbsRdbPredicates* AbsRdbPredicates::InAllDevices() +AbsRdbPredicates *AbsRdbPredicates::InAllDevices() { predicates_.devices_.clear(); return this; } -const DistributedRdb::PredicatesMemo& AbsRdbPredicates::GetDistributedPredicates() const +const DistributedRdb::PredicatesMemo &AbsRdbPredicates::GetDistributedPredicates() const { int limit = GetLimit(); if (limit >= 0) { - predicates_.AddOperation(DistributedRdb::RdbPredicateOperator::LIMIT, - std::to_string(limit), std::to_string(GetOffset())); + predicates_.AddOperation( + DistributedRdb::RdbPredicateOperator::LIMIT, std::to_string(limit), std::to_string(GetOffset())); } return predicates_; } -AbsRdbPredicates* AbsRdbPredicates::EqualTo(const std::string &field, const ValueObject &value) +AbsRdbPredicates *AbsRdbPredicates::EqualTo(const std::string &field, const ValueObject &value) { if (auto pval = std::get_if(&value.value)) { predicates_.AddOperation(DistributedRdb::EQUAL_TO, field, *pval); @@ -180,7 +180,7 @@ AbsRdbPredicates* AbsRdbPredicates::EqualTo(const std::string &field, const Valu return (AbsRdbPredicates *)AbsPredicates::EqualTo(field, value); } -AbsRdbPredicates* AbsRdbPredicates::NotEqualTo(const std::string &field, const ValueObject &value) +AbsRdbPredicates *AbsRdbPredicates::NotEqualTo(const std::string &field, const ValueObject &value) { if (auto pval = std::get_if(&value.value)) { predicates_.AddOperation(DistributedRdb::NOT_EQUAL_TO, field, *pval); @@ -188,26 +188,26 @@ AbsRdbPredicates* AbsRdbPredicates::NotEqualTo(const std::string &field, const V return (AbsRdbPredicates *)AbsPredicates::NotEqualTo(field, value); } -AbsRdbPredicates* AbsRdbPredicates::And() +AbsRdbPredicates *AbsRdbPredicates::And() { predicates_.AddOperation(DistributedRdb::AND, "", ""); return (AbsRdbPredicates *)AbsPredicates::And(); } -AbsRdbPredicates* AbsRdbPredicates::Or() +AbsRdbPredicates *AbsRdbPredicates::Or() { predicates_.AddOperation(DistributedRdb::OR, "", ""); return (AbsRdbPredicates *)AbsPredicates::Or(); } -AbsRdbPredicates* AbsRdbPredicates::OrderByAsc(const std::string &field) +AbsRdbPredicates *AbsRdbPredicates::OrderByAsc(const std::string &field) { std::string isAsc = "true"; predicates_.AddOperation(DistributedRdb::ORDER_BY, field, isAsc); return (AbsRdbPredicates *)AbsPredicates::OrderByAsc(field); } -AbsRdbPredicates* AbsRdbPredicates::OrderByDesc(const std::string &field) +AbsRdbPredicates *AbsRdbPredicates::OrderByDesc(const std::string &field) { std::string isAsc = "false"; predicates_.AddOperation(DistributedRdb::ORDER_BY, field, isAsc); 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 71e22d2f..3b32a5c9 100644 --- a/relational_store/frameworks/native/rdb/src/abs_result_set.cpp +++ b/relational_store/frameworks/native/rdb/src/abs_result_set.cpp @@ -29,10 +29,10 @@ namespace OHOS { namespace NativeRdb { using namespace OHOS::Rdb; -void RowEntity::Put(const std::string& name, int32_t index, ValueObject&& value) +void RowEntity::Put(const std::string &name, int32_t index, ValueObject &&value) { if (index < 0 || index >= static_cast(indexs_.size())) { - return ; + return; } auto it = values_.emplace(name, std::move(value)); indexs_[index] = it.first; @@ -144,13 +144,13 @@ int AbsResultSet::InitColumnNames() } for (size_t i = 0; i < names.size(); ++i) { - columnMap_.insert(std::pair{names[i], i}); + columnMap_.insert(std::pair{ names[i], i }); } columnCount_ = static_cast(names.size()); return E_OK; } -int AbsResultSet::GetBlob(int columnIndex, std::vector& blob) +int AbsResultSet::GetBlob(int columnIndex, std::vector &blob) { ValueObject object; int errorCode = Get(columnIndex, object); @@ -196,7 +196,7 @@ int AbsResultSet::GetInt(int columnIndex, int &value) return E_OK; } -int AbsResultSet::GetLong(int columnIndex, int64_t& value) +int AbsResultSet::GetLong(int columnIndex, int64_t &value) { ValueObject object; int errorCode = Get(columnIndex, object); @@ -213,7 +213,7 @@ int AbsResultSet::GetLong(int columnIndex, int64_t& value) return E_OK; } -int AbsResultSet::GetDouble(int columnIndex, double& value) +int AbsResultSet::GetDouble(int columnIndex, double &value) { ValueObject object; int errorCode = Get(columnIndex, object); @@ -399,7 +399,7 @@ int AbsResultSet::GetColumnIndex(const std::string &columnName, int &columnIndex lowerName = lowerName.substr(periodIndex + 1); } std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), ::tolower); - for (const auto& [name, index] : columnMap_) { + for (const auto &[name, index] : columnMap_) { std::string temp = name; std::transform(name.begin(), name.end(), temp.begin(), ::tolower); if (lowerName == temp) { @@ -425,7 +425,7 @@ int AbsResultSet::GetColumnName(int columnIndex, std::string &columnName) return E_COLUMN_OUT_RANGE; } - for (const auto& [name, index] : columnMap_) { + for (const auto &[name, index] : columnMap_) { if (index == columnIndex) { columnName = name; return 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 f98ac511..5e4d9925 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 @@ -82,7 +82,7 @@ int AbsSharedResultSet::GetColumnType(int columnIndex, ColumnType &columnType) if (errorCode != E_OK) { return errorCode; } - SharedBlock::CellUnit* cellUnit = block->GetCellUnit(block->GetBlockPos(), (uint32_t)columnIndex); + SharedBlock::CellUnit *cellUnit = block->GetCellUnit(block->GetBlockPos(), (uint32_t)columnIndex); if (!cellUnit) { LOG_ERROR("AbsSharedResultSet::GetColumnType cellUnit is null!"); return E_ERROR; @@ -140,7 +140,7 @@ int AbsSharedResultSet::GetString(int columnIndex, std::string &value) return AbsResultSet::GetString(columnIndex, value); } -int AbsSharedResultSet::Get(int32_t col, ValueObject& value) +int AbsSharedResultSet::Get(int32_t col, ValueObject &value) { auto block = GetBlock(); int errorCode = CheckState(col); @@ -251,7 +251,7 @@ void AbsSharedResultSet::Finalize() Close(); } -int AbsSharedResultSet::GetCustomerValue(int index, ValueObject& value, SharedBlock *block) +int AbsSharedResultSet::GetCustomerValue(int index, ValueObject &value, SharedBlock *block) { auto *cellUnit = block->GetCellUnit(block->GetBlockPos(), index); if (cellUnit == nullptr) { @@ -310,7 +310,7 @@ int AbsSharedResultSet::CheckState(int columnIndex) if (rowPos_ < 0 || rowPos_ >= count) { return E_ROW_OUT_RANGE; } - + GetColumnCount(count); if (columnIndex >= count || columnIndex < 0) { return E_COLUMN_OUT_RANGE; diff --git a/relational_store/frameworks/native/rdb/src/big_integer.cpp b/relational_store/frameworks/native/rdb/src/big_integer.cpp index 074efa2d..982a3cd4 100644 --- a/relational_store/frameworks/native/rdb/src/big_integer.cpp +++ b/relational_store/frameworks/native/rdb/src/big_integer.cpp @@ -30,17 +30,17 @@ BigInteger::BigInteger(int32_t sign, std::vector&& trueForm) { } -BigInteger::BigInteger(const BigInteger& other) +BigInteger::BigInteger(const BigInteger &other) { operator=(other); } -BigInteger::BigInteger(BigInteger&& other) +BigInteger::BigInteger(BigInteger &&other) { operator=(std::move(other)); } -BigInteger& BigInteger::operator=(const BigInteger& other) +BigInteger &BigInteger::operator=(const BigInteger &other) { if (this == &other) { return *this; @@ -50,7 +50,7 @@ BigInteger& BigInteger::operator=(const BigInteger& other) return *this; } -BigInteger& BigInteger::operator=(BigInteger&& other) +BigInteger &BigInteger::operator=(BigInteger &&other) { if (this == &other) { return *this; @@ -61,7 +61,7 @@ BigInteger& BigInteger::operator=(BigInteger&& other) return *this; } -bool BigInteger::operator==(const BigInteger& other) +bool BigInteger::operator==(const BigInteger &other) { if (sign_ != other.sign_) { return false; @@ -84,7 +84,7 @@ size_t BigInteger::Size() const return value_.size(); } -const uint64_t* BigInteger::TrueForm() const +const uint64_t *BigInteger::TrueForm() const { return value_.data(); } @@ -93,4 +93,4 @@ std::vector BigInteger::Value() const { return value_; } -} \ No newline at end of file +} // namespace OHOS::NativeRdb 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 176898ba..50e8720a 100644 --- a/relational_store/frameworks/native/rdb/src/cache_result_set.cpp +++ b/relational_store/frameworks/native/rdb/src/cache_result_set.cpp @@ -330,5 +330,5 @@ int CacheResultSet::GetSize(int columnIndex, size_t &size) { return E_NOT_SUPPORT; } -} +} // namespace NativeRdb } // namespace OHOS \ No newline at end of file diff --git a/relational_store/frameworks/native/rdb/src/connection.cpp b/relational_store/frameworks/native/rdb/src/connection.cpp index 2df3ba07..713472d1 100644 --- a/relational_store/frameworks/native/rdb/src/connection.cpp +++ b/relational_store/frameworks/native/rdb/src/connection.cpp @@ -22,6 +22,7 @@ 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 }; static Connection::Collector g_collectors[DB_BUTT] = { nullptr, nullptr }; +static Connection::Restorer g_restorer[DB_BUTT] = { nullptr, nullptr }; std::pair> Connection::Create(const RdbStoreConfig &config, bool isWriter) { auto dbType = config.GetDBType(); @@ -81,6 +82,21 @@ std::map Connection::Collect(const RdbStoreConfig return collector(config); } +int32_t Connection::Restore(const RdbStoreConfig &config, const std::string &srcPath, const std::string &destPath) +{ + auto dbType = config.GetDBType(); + if (dbType < static_cast(DB_SQLITE) || dbType >= static_cast(DB_BUTT)) { + return E_INVALID_ARGS; + } + + auto restorer = g_restorer[dbType]; + if (restorer == nullptr) { + return E_NOT_SUPPORT; + } + + return restorer(config, srcPath, destPath); +} + int32_t Connection::RegisterCreator(int32_t dbType, Creator creator) { if (dbType < static_cast(DB_SQLITE) || dbType >= static_cast(DB_BUTT)) { @@ -90,7 +106,7 @@ int32_t Connection::RegisterCreator(int32_t dbType, Creator creator) if (g_creators[dbType] != nullptr) { return E_OK; } - + g_creators[dbType] = creator; return E_OK; } @@ -137,6 +153,20 @@ int32_t Connection::RegisterCollector(int32_t dbType, Collector collector) return E_OK; } +int32_t Connection::RegisterRestorer(int32_t dbType, Restorer restorer) +{ + if (dbType < static_cast(DB_SQLITE) || dbType >= static_cast(DB_BUTT)) { + return E_INVALID_ARGS; + } + + if (g_restorer[dbType] != nullptr) { + return E_OK; + } + + g_restorer[dbType] = restorer; + return E_OK; +} + int Connection::SetId(int id) { id_ = id; diff --git a/relational_store/frameworks/native/rdb/src/connection_pool.cpp b/relational_store/frameworks/native/rdb/src/connection_pool.cpp index b410f653..a1a6e564 100644 --- a/relational_store/frameworks/native/rdb/src/connection_pool.cpp +++ b/relational_store/frameworks/native/rdb/src/connection_pool.cpp @@ -16,7 +16,6 @@ #include "connection_pool.h" #include - #include #include #include @@ -181,10 +180,10 @@ std::shared_ptr ConnPool::Convert2AutoConn(std::shared_ptr if (realPool == nullptr) { return; } + realPool->ReleaseNode(node, !isTrans); if (isTrans) { realPool->transCount_--; } - realPool->ReleaseNode(node, !isTrans); node = nullptr; }); } @@ -295,16 +294,24 @@ SharedConn ConnPool::AcquireRef(bool isReadOnly, std::chrono::milliseconds ms) }); } -void ConnPool::ReleaseNode(std::shared_ptr node, bool reuse) +void ConnPool::ReleaseNode(std::shared_ptr node, bool reuse) { if (node == nullptr) { return; } + auto now = steady_clock::now(); + auto timeout = now > (failedTime_.load() + minutes(CHECK_POINT_INTERVAL)) || now < failedTime_.load(); auto transCount = transCount_ + isInTransaction_; - auto errCode = node->Unused(transCount); + auto remainCount = reuse ? transCount : transCount - 1; + auto errCode = node->Unused(remainCount, timeout); if (errCode == E_SQLITE_LOCKED || errCode == E_SQLITE_BUSY) { writers_.Dump("WAL writers_", transCount); + readers_.Dump("WAL readers_", transCount); + } + + if (node->IsWriter() && (errCode != E_INNER_WARNING && errCode != E_NOT_SUPPORT)) { + failedTime_ = errCode != E_OK ? now : steady_clock::time_point(); } auto &container = node->IsWriter() ? writers_ : readers_; @@ -371,7 +378,7 @@ int ConnPool::ChangeDbFileForRestore(const std::string &newPath, const std::stri CloseAllConnections(); auto [retVal, conn] = Connection::Create(config_, false); if (retVal != E_OK) { - LOG_ERROR("create connection fail, erroce:%{public}d", retVal); + LOG_ERROR("create connection fail, errCode:%{public}d", retVal); return retVal; } @@ -389,12 +396,12 @@ int ConnPool::ChangeDbFileForRestore(const std::string &newPath, const std::stri } return retVal; } - return RestoreByDbSqliteType(newPath, backupPath, slaveStatus); + return RestoreMasterDb(newPath, backupPath, slaveStatus); } -int ConnPool::RestoreByDbSqliteType(const std::string &newPath, const std::string &backupPath, SlaveStatus &slaveStatus) +int ConnPool::RestoreMasterDb(const std::string &newPath, const std::string &backupPath, SlaveStatus &slaveStatus) { - if (SqliteUtils::IsSlaveDbName(backupPath) && config_.GetHaMode() != HAMode::SINGLE) { + if (SqliteUtils::IsSlaveDbName(backupPath) && config_.GetHaMode() == HAMode::MAIN_REPLICA) { auto connection = AcquireConnection(false); if (connection == nullptr) { return E_DATABASE_BUSY; @@ -402,38 +409,28 @@ int ConnPool::RestoreByDbSqliteType(const std::string &newPath, const std::strin return connection->Restore(backupPath, {}, slaveStatus); } - return RestoreMasterDb(newPath, backupPath); -} - -int ConnPool::RestoreMasterDb(const std::string &newPath, const std::string &backupPath) -{ - if (!CheckIntegrity(backupPath)) { - LOG_ERROR("backup file is corrupted, %{public}s", SqliteUtils::Anonymous(backupPath).c_str()); - return E_SQLITE_CORRUPT; - } - SqliteUtils::DeleteFile(backupPath + "-shm"); - SqliteUtils::DeleteFile(backupPath + "-wal"); - CloseAllConnections(); - Connection::Delete(config_); - - if (config_.GetPath() != newPath) { - RdbStoreConfig config(newPath); - config.SetPath(newPath); - Connection::Delete(config); - } - - int ret = E_OK; - if (!SqliteUtils::CopyFile(backupPath, newPath)) { - ret = E_ERROR; + int ret = Connection::Restore(config_, backupPath, newPath); + int32_t errCode = E_OK; + std::shared_ptr pool; + for (uint32_t retry = 0; retry < ITERS_COUNT; ++retry) { + std::tie(errCode, pool) = Init(); + if (errCode == E_OK) { + break; + } + if (errCode != E_SQLITE_CORRUPT || !config_.IsEncrypt()) { + break; + } + config_.SetIter(ITER_V1); } - auto result = Init(); - if (result.first != E_OK) { + if (errCode != E_OK) { CloseAllConnections(); Connection::Delete(config_); - result = Init(); + std::tie(errCode, pool) = Init(); + LOG_WARN("restore failed! rebuild res:%{public}d, path:%{public}s.", errCode, + SqliteUtils::Anonymous(backupPath).c_str()); } - return ret == E_OK ? result.first : ret; + return ret == E_OK ? errCode : ret; } std::stack &ConnPool::GetTransactionStack() @@ -481,28 +478,22 @@ int64_t ConnPool::ConnNode::GetUsingTime() const return duration_cast(time).count(); } -int32_t ConnPool::ConnNode::Unused(int32_t count) +int32_t ConnPool::ConnNode::Unused(int32_t count, bool timeout) { - time_ = steady_clock::now(); if (connect_ == nullptr) { return E_OK; } connect_->ClearCache(); - if (!connect_->IsWriter()) { - tid_ = 0; + int32_t errCode = E_INNER_WARNING; + if (count <= 0) { + errCode = connect_->TryCheckPoint(timeout); } - if (count > 0) { - return E_OK; - } - auto timeout = time_ > (failedTime_ + minutes(CHECK_POINT_INTERVAL)) || time_ < failedTime_; - int32_t errCode = connect_->TryCheckPoint(timeout); - if (errCode == E_INNER_WARNING || errCode == E_NOT_SUPPORT) { - return E_OK; + time_ = steady_clock::now(); + if (!connect_->IsWriter()) { + tid_ = 0; } - - failedTime_ = errCode != E_OK ? time_ : steady_clock::time_point(); return errCode; } @@ -734,8 +725,18 @@ bool ConnectionPool::CheckIntegrity(const std::string &dbPath) RdbStoreConfig config(config_); config.SetPath(dbPath); config.SetIntegrityCheck(IntegrityCheck::FULL); - auto [ret, connection] = Connection::Create(config, true); - return ret == E_OK; + config.SetHaMode(HAMode::SINGLE); + for (uint32_t retry = 0; retry < ITERS_COUNT; ++retry) { + auto [ret, connection] = Connection::Create(config, true); + if (ret == E_OK) { + return true; + } + if (ret != E_SQLITE_CORRUPT || !config.IsEncrypt()) { + break; + } + config.SetIter(ITER_V1); + } + return false; } int32_t ConnPool::Container::Clear() diff --git a/relational_store/frameworks/native/rdb/src/delay_notify.cpp b/relational_store/frameworks/native/rdb/src/delay_notify.cpp index 785bcb70..718c1d9e 100644 --- a/relational_store/frameworks/native/rdb/src/delay_notify.cpp +++ b/relational_store/frameworks/native/rdb/src/delay_notify.cpp @@ -14,6 +14,7 @@ */ #define LOG_TAG "DelayNotify" #include "delay_notify.h" + #include "logger.h" namespace OHOS::NativeRdb { using namespace OHOS::Rdb; @@ -45,7 +46,7 @@ void DelayNotify::UpdateNotify(const DistributedRdb::RdbChangedData &changedData LOG_DEBUG("Update changed data."); { std::lock_guard lock(mutex_); - for (auto& [k, v] : changedData.tableData) { + for (auto &[k, v] : changedData.tableData) { if (!v.isTrackedDataChange) { continue; } @@ -93,7 +94,7 @@ void DelayNotify::StartTimer() pool_->Reset(delaySyncTaskId_, std::chrono::milliseconds(autoSyncInterval_)); } - if (autoSyncInterval_ == AUTO_SYNC_INTERVAL || changedData.tableData.empty()) { + if (changedData.tableData.empty()) { return; } @@ -148,7 +149,7 @@ void DelayNotify::ExecuteTask() if (errCode != 0) { LOG_ERROR("NotifyDataChange is failed, err is %{public}d.", errCode); std::lock_guard lock(mutex_); - for (auto& [k, v] : changedData.tableData) { + for (auto &[k, v] : changedData.tableData) { changedData_.tableData.insert_or_assign(k, v); } return; @@ -194,4 +195,4 @@ PauseDelayNotify::~PauseDelayNotify() delayNotifier_->Resume(); } } -} \ No newline at end of file +} // namespace OHOS::NativeRdb \ No newline at end of file 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 667c8bfb..440f7b27 100644 --- a/relational_store/frameworks/native/rdb/src/grd_api_manager.cpp +++ b/relational_store/frameworks/native/rdb/src/grd_api_manager.cpp @@ -14,6 +14,7 @@ */ #define LOG_TAG "GRD_API_MANAGER" #include "grd_api_manager.h" + #include "logger.h" #ifndef _WIN32 @@ -92,4 +93,3 @@ GRD_APIInfo GetApiInfoInstance() } // namespace NativeRdb } // namespace OHOS - diff --git a/relational_store/frameworks/native/rdb/src/raw_data_parser.cpp b/relational_store/frameworks/native/rdb/src/raw_data_parser.cpp index 15d31650..8b207291 100644 --- a/relational_store/frameworks/native/rdb/src/raw_data_parser.cpp +++ b/relational_store/frameworks/native/rdb/src/raw_data_parser.cpp @@ -63,8 +63,8 @@ size_t RawDataParser::ParserRawData(const uint8_t *data, size_t length, Assets & return 0; } std::vector alignData; - alignData.assign(data, data + sizeof (ASSETS_MAGIC)); - used += sizeof (ASSETS_MAGIC); + alignData.assign(data, data + sizeof(ASSETS_MAGIC)); + used += sizeof(ASSETS_MAGIC); auto hostMagicWord = Endian::LeToH(*(reinterpret_cast(alignData.data()))); if (hostMagicWord != ASSETS_MAGIC) { return 0; @@ -99,8 +99,8 @@ std::vector RawDataParser::PackageRawData(const Asset &asset) auto leMagic = Endian::HToLe(ASSET_MAGIC); auto magicU8 = reinterpret_cast(const_cast(&leMagic)); rawData.insert(rawData.end(), magicU8, magicU8 + sizeof(ASSET_MAGIC)); - rawData.insert(rawData.end(), reinterpret_cast(&size), - reinterpret_cast(&size) + sizeof(size)); + rawData.insert( + rawData.end(), reinterpret_cast(&size), reinterpret_cast(&size) + sizeof(size)); rawData.insert(rawData.end(), data.begin(), data.end()); return rawData; } @@ -132,7 +132,7 @@ size_t RawDataParser::ParserRawData(const uint8_t *data, size_t length, std::map return used; } -size_t RawDataParser::ParserRawData(const uint8_t* data, size_t length, BigInteger& bigint) +size_t RawDataParser::ParserRawData(const uint8_t *data, size_t length, BigInteger &bigint) { size_t used = 0; if (sizeof(BIG_INT) > length - used) { @@ -176,7 +176,7 @@ size_t RawDataParser::ParserRawData(const uint8_t* data, size_t length, BigInteg return used; } -size_t RawDataParser::ParserRawData(const uint8_t* data, size_t length, RawDataParser::Floats& floats) +size_t RawDataParser::ParserRawData(const uint8_t *data, size_t length, RawDataParser::Floats &floats) { size_t used = 0; if (sizeof(FLOUT32_ARRAY) > length - used) { @@ -219,12 +219,12 @@ std::vector RawDataParser::PackageRawData(const std::map RawDataParser::PackageRawData(const BigInteger& bigint) +std::vector RawDataParser::PackageRawData(const BigInteger &bigint) { size_t offset = 0; auto size = sizeof(BIG_INT) + sizeof(uint32_t) + sizeof(uint64_t) * (bigint.Size() + 1); std::vector rawData(size, 0); - uint8_t* data = rawData.data(); + uint8_t *data = rawData.data(); *(reinterpret_cast(&data[offset])) = Endian::HToLe(BIG_INT); offset += sizeof(BIG_INT); *(reinterpret_cast(&data[offset])) = Endian::HToLe(uint32_t(bigint.Sign())); @@ -242,12 +242,12 @@ std::vector RawDataParser::PackageRawData(const BigInteger& bigint) return rawData; } -std::vector RawDataParser::PackageRawData(const RawDataParser::Floats& floats) +std::vector RawDataParser::PackageRawData(const RawDataParser::Floats &floats) { size_t offset = 0; auto size = sizeof(FLOUT32_ARRAY) + sizeof(uint32_t) + sizeof(float) * floats.size(); std::vector rawData(size, 0); - uint8_t* data = rawData.data(); + uint8_t *data = rawData.data(); *(reinterpret_cast(&data[offset])) = Endian::HToLe(FLOUT32_ARRAY); offset += sizeof(FLOUT32_ARRAY); *(reinterpret_cast(&data[offset])) = Endian::HToLe(uint32_t(floats.size())); diff --git a/relational_store/frameworks/native/rdb/src/rd_connection.cpp b/relational_store/frameworks/native/rdb/src/rd_connection.cpp index 659915aa..11327653 100644 --- a/relational_store/frameworks/native/rdb/src/rd_connection.cpp +++ b/relational_store/frameworks/native/rdb/src/rd_connection.cpp @@ -16,10 +16,11 @@ #include "rd_connection.h" #include + #include -#include "logger.h" #include "grd_api_manager.h" +#include "logger.h" #include "rd_statement.h" #include "rdb_errno.h" #include "rdb_security_manager.h" @@ -36,14 +37,14 @@ const int32_t RdConnection::regRepairer_ = Connection::RegisterRepairer(DB_VECTO __attribute__((used)) const int32_t RdConnection::regDeleter_ = Connection::RegisterDeleter(DB_VECTOR, RdConnection::Delete); -std::pair> RdConnection::Create(const RdbStoreConfig& config, bool isWrite) +std::pair> RdConnection::Create(const RdbStoreConfig &config, bool isWrite) { std::pair> result = { E_ERROR, nullptr }; if (!IsUsingArkData() || config.GetStorageMode() == StorageMode::MODE_MEMORY) { result.first = E_NOT_SUPPORT; return result; } - auto& [errCode, conn] = result; + auto &[errCode, conn] = result; for (size_t i = 0; i < ITERS_COUNT; i++) { std::shared_ptr connection = std::make_shared(config, isWrite); if (connection == nullptr) { @@ -59,7 +60,7 @@ std::pair> RdConnection::Create(const RdbSt return result; } -int32_t RdConnection::Repair(const RdbStoreConfig& config) +int32_t RdConnection::Repair(const RdbStoreConfig &config) { std::string dbPath = ""; auto errCode = SqliteGlobalConfig::GetDbPath(config, dbPath); @@ -131,7 +132,6 @@ std::string RdConnection::GetConfigStr(const std::vector &keys, bool is return config; } - int RdConnection::InnerOpen(const RdbStoreConfig &config) { std::string dbPath = ""; @@ -177,7 +177,7 @@ int32_t RdConnection::OnInitialize() return E_NOT_SUPPORT; } -std::pair RdConnection::CreateStatement(const std::string& sql, Connection::SConn conn) +std::pair RdConnection::CreateStatement(const std::string &sql, Connection::SConn conn) { auto stmt = std::make_shared(); stmt->conn_ = conn; @@ -205,7 +205,7 @@ bool RdConnection::IsWriter() const return isWriter_; } -int32_t RdConnection::ReSetKey(const RdbStoreConfig& config) +int32_t RdConnection::ReSetKey(const RdbStoreConfig &config) { if (!IsWriter()) { return E_OK; @@ -243,17 +243,17 @@ int32_t RdConnection::LimitWalSize() return E_NOT_SUPPORT; } -int32_t RdConnection::ConfigLocale(const std::string& localeStr) +int32_t RdConnection::ConfigLocale(const std::string &localeStr) { return E_NOT_SUPPORT; } -int32_t RdConnection::CleanDirtyData(const std::string& table, uint64_t cursor) +int32_t RdConnection::CleanDirtyData(const std::string &table, uint64_t cursor) { return E_NOT_SUPPORT; } -int32_t RdConnection::SubscribeTableChanges(const Connection::Notifier& notifier) +int32_t RdConnection::SubscribeTableChanges(const Connection::Notifier ¬ifier) { return E_NOT_SUPPORT; } @@ -273,20 +273,20 @@ int32_t RdConnection::ClearCache() return E_NOT_SUPPORT; } -int32_t RdConnection::Subscribe(const std::string& event, - const std::shared_ptr& observer) +int32_t RdConnection::Subscribe( + const std::string &event, const std::shared_ptr &observer) { return E_NOT_SUPPORT; } -int32_t RdConnection::Unsubscribe(const std::string& event, - const std::shared_ptr& observer) +int32_t RdConnection::Unsubscribe( + const std::string &event, const std::shared_ptr &observer) { return E_NOT_SUPPORT; } -int32_t RdConnection::Backup(const std::string &databasePath, const std::vector &destEncryptKey, - bool isAsync, SlaveStatus &slaveStatus) +int32_t RdConnection::Backup(const std::string &databasePath, const std::vector &destEncryptKey, bool isAsync, + SlaveStatus &slaveStatus) { if (!destEncryptKey.empty() && !config_.IsEncrypt()) { return RdUtils::RdDbBackup(dbHandle_, databasePath.c_str(), destEncryptKey); @@ -300,8 +300,8 @@ int32_t RdConnection::Backup(const std::string &databasePath, const std::vector< return RdUtils::RdDbBackup(dbHandle_, databasePath.c_str(), {}); } -int32_t RdConnection::Restore(const std::string &databasePath, const std::vector &destEncryptKey, - SlaveStatus &slaveStatus) +int32_t RdConnection::Restore( + const std::string &databasePath, const std::vector &destEncryptKey, SlaveStatus &slaveStatus) { auto ret = RdUtils::RdDbClose(dbHandle_, 0); if (ret != E_OK) { diff --git a/relational_store/frameworks/native/rdb/src/rd_statement.cpp b/relational_store/frameworks/native/rdb/src/rd_statement.cpp index c6b0384c..a34c93dc 100644 --- a/relational_store/frameworks/native/rdb/src/rd_statement.cpp +++ b/relational_store/frameworks/native/rdb/src/rd_statement.cpp @@ -15,19 +15,19 @@ #define LOG_TAG "RdStatement" #include "rd_statement.h" -#include -#include #include #include +#include +#include + #include "logger.h" #include "raw_data_parser.h" -#include "rdb_errno.h" #include "rd_connection.h" #include "rd_utils.h" -#include "sqlite_global_config.h" -#include "sqlite_utils.h" +#include "rdb_errno.h" #include "rdb_fault_hiview_reporter.h" #include "sqlite_global_config.h" +#include "sqlite_utils.h" namespace OHOS { namespace NativeRdb { @@ -181,8 +181,8 @@ int RdStatement::InnerBindBlobTypeArgs(const ValueObject &arg, uint32_t index) c case ValueObjectType::TYPE_BLOB: { std::vector blob; arg.GetBlob(blob); - ret = RdUtils::RdSqlBindBlob(stmtHandle_, index, static_cast(blob.data()), blob.size(), - nullptr); + ret = RdUtils::RdSqlBindBlob( + stmtHandle_, index, static_cast(blob.data()), blob.size(), nullptr); break; } case ValueObjectType::TYPE_BOOL: { @@ -195,23 +195,23 @@ int RdStatement::InnerBindBlobTypeArgs(const ValueObject &arg, uint32_t index) c ValueObject::Asset asset; arg.GetAsset(asset); auto rawData = RawDataParser::PackageRawData(asset); - ret = RdUtils::RdSqlBindBlob(stmtHandle_, index, static_cast(rawData.data()), - rawData.size(), nullptr); + ret = RdUtils::RdSqlBindBlob( + stmtHandle_, index, static_cast(rawData.data()), rawData.size(), nullptr); break; } case ValueObjectType::TYPE_ASSETS: { ValueObject::Assets assets; arg.GetAssets(assets); auto rawData = RawDataParser::PackageRawData(assets); - ret = RdUtils::RdSqlBindBlob(stmtHandle_, index, static_cast(rawData.data()), - rawData.size(), nullptr); + ret = RdUtils::RdSqlBindBlob( + stmtHandle_, index, static_cast(rawData.data()), rawData.size(), nullptr); break; } case ValueObjectType::TYPE_VECS: { ValueObject::FloatVector vectors; arg.GetVecs(vectors); - ret = RdUtils::RdSqlBindFloatVector(stmtHandle_, index, - static_cast(vectors.data()), vectors.size(), nullptr); + ret = RdUtils::RdSqlBindFloatVector( + stmtHandle_, index, static_cast(vectors.data()), vectors.size(), nullptr); break; } default: { @@ -237,7 +237,7 @@ int RdStatement::IsValid(int index) const return E_OK; } -int32_t RdStatement::Prepare(const std::string& sql) +int32_t RdStatement::Prepare(const std::string &sql) { if (dbHandle_ == nullptr) { return E_ERROR; @@ -245,16 +245,16 @@ int32_t RdStatement::Prepare(const std::string& sql) return Prepare(dbHandle_, sql); } -int32_t RdStatement::Bind(const std::vector& args) +int32_t RdStatement::Bind(const std::vector &args) { std::vector> refArgs; for (auto &object : args) { - refArgs.emplace_back(std::ref(const_cast(object))); + refArgs.emplace_back(std::ref(const_cast(object))); } return Bind(refArgs); } -int32_t RdStatement::Bind(const std::vector>& args) +int32_t RdStatement::Bind(const std::vector> &args) { uint32_t index = 1; int ret = E_OK; @@ -322,16 +322,16 @@ int32_t RdStatement::Reset() return RdUtils::RdSqlReset(stmtHandle_); } -int32_t RdStatement::Execute(const std::vector& args) +int32_t RdStatement::Execute(const std::vector &args) { std::vector> refArgs; for (auto &object : args) { - refArgs.emplace_back(std::ref(const_cast(object))); + refArgs.emplace_back(std::ref(const_cast(object))); } return Execute(refArgs); } -int32_t RdStatement::Execute(const std::vector>& args) +int32_t RdStatement::Execute(const std::vector> &args) { if (!readOnly_ && strcmp(sql_.c_str(), GlobalExpr::PRAGMA_VERSION) == 0) { // It has already set version in prepare procedure @@ -351,7 +351,7 @@ int32_t RdStatement::Execute(const std::vector RdStatement::ExecuteForValue(const std::vector& args) +std::pair RdStatement::ExecuteForValue(const std::vector &args) { int ret = E_OK; if (readOnly_ && strcmp(sql_.c_str(), GlobalExpr::PRAGMA_VERSION) == 0) { @@ -397,7 +397,7 @@ std::pair RdStatement::GetColumnName(int32_t index) const if (ret != E_OK) { return { ret, "" }; } - const char* name = RdUtils::RdSqlColName(stmtHandle_, index); + const char *name = RdUtils::RdSqlColName(stmtHandle_, index); if (name == nullptr) { LOG_ERROR("column_name is null."); return { E_ERROR, "" }; @@ -464,8 +464,7 @@ std::pair RdStatement::GetColumn(int32_t index) const break; case ColumnType::TYPE_FLOAT32_ARRAY: { uint32_t dim = 0; - auto vectors = - reinterpret_cast(RdUtils::RdSqlColumnFloatVector(stmtHandle_, index, &dim)); + auto vectors = reinterpret_cast(RdUtils::RdSqlColumnFloatVector(stmtHandle_, index, &dim)); std::vector vecData; if (dim > 0 || vectors != nullptr) { vecData.resize(dim); @@ -501,7 +500,7 @@ bool RdStatement::SupportBlockInfo() const return false; } -int32_t RdStatement::FillBlockInfo(SharedBlockInfo* info) const +int32_t RdStatement::FillBlockInfo(SharedBlockInfo *info) const { return E_NOT_SUPPORT; } diff --git a/relational_store/frameworks/native/rdb/src/rd_utils.cpp b/relational_store/frameworks/native/rdb/src/rd_utils.cpp index 66d1fc16..2c33cbbb 100644 --- a/relational_store/frameworks/native/rdb/src/rd_utils.cpp +++ b/relational_store/frameworks/native/rdb/src/rd_utils.cpp @@ -16,14 +16,15 @@ #define LOG_TAG "RdUtils" #include "rd_utils.h" +#include + #include #include -#include #include #include -#include "grd_error.h" #include "grd_api_manager.h" +#include "grd_error.h" #include "logger.h" #include "remote_result_set.h" @@ -40,13 +41,13 @@ struct GrdErrnoPair { const GrdErrnoPair GRD_ERRNO_MAP[] = { { GRD_OK, E_OK }, - { GRD_REBUILD_DATABASE, E_OK}, + { GRD_REBUILD_DATABASE, E_OK }, { GRD_NO_DATA, E_NO_MORE_ROWS }, { GRD_DATA_CORRUPTED, E_SQLITE_CORRUPT }, - { GRD_INVALID_FILE_FORMAT, E_SQLITE_CORRUPT }, - { GRD_PRIMARY_KEY_VIOLATION, E_SQLITE_CONSTRAINT}, - { GRD_RESTRICT_VIOLATION, E_SQLITE_CONSTRAINT}, - { GRD_CONSTRAINT_CHECK_VIOLATION, E_SQLITE_CONSTRAINT}, + { GRD_INVALID_FILE_FORMAT, E_SQLITE_CORRUPT }, + { GRD_PRIMARY_KEY_VIOLATION, E_SQLITE_CONSTRAINT }, + { GRD_RESTRICT_VIOLATION, E_SQLITE_CONSTRAINT }, + { GRD_CONSTRAINT_CHECK_VIOLATION, E_SQLITE_CONSTRAINT }, { GRD_NOT_SUPPORT, E_NOT_SUPPORT }, { GRD_OVER_LIMIT, E_SQLITE_CONSTRAINT }, { GRD_INVALID_ARGS, E_INVALID_ARGS }, @@ -62,12 +63,12 @@ const GrdErrnoPair GRD_ERRNO_MAP[] = { { GRD_PASSWORD_UNMATCHED, E_SQLITE_CANTOPEN }, { GRD_PASSWORD_NEED_REKEY, E_CHANGE_UNENCRYPTED_TO_ENCRYPTED }, - { GRD_NAME_TOO_LONG, E_SQLITE_CONSTRAINT}, - { GRD_INVALID_TABLE_DEFINITION, E_SQLITE_SCHEMA}, - { GRD_SEMANTIC_ERROR, E_NOT_SUPPORT_THE_SQL}, - { GRD_SYNTAX_ERROR, E_NOT_SUPPORT_THE_SQL}, - { GRD_DATA_MISMATCH, E_SQLITE_MISMATCH}, - { GRD_WRONG_STMT_OBJECT, E_INVALID_OBJECT_TYPE}, + { GRD_NAME_TOO_LONG, E_SQLITE_CONSTRAINT }, + { GRD_INVALID_TABLE_DEFINITION, E_SQLITE_SCHEMA }, + { GRD_SEMANTIC_ERROR, E_NOT_SUPPORT_THE_SQL }, + { GRD_SYNTAX_ERROR, E_NOT_SUPPORT_THE_SQL }, + { GRD_DATA_MISMATCH, E_SQLITE_MISMATCH }, + { GRD_WRONG_STMT_OBJECT, E_INVALID_OBJECT_TYPE }, { GRD_DATA_CONFLICT, E_INVALID_CONFLICT_FLAG }, { GRD_INNER_ERR, E_ERROR }, @@ -292,8 +293,7 @@ void RdSqlFreeFloatArr(void *floatElement) delete[] ((float *)floatElement); } -int RdUtils::RdSqlBindFloatVector(GRD_SqlStmt *stmt, uint32_t idx, float *val, - uint32_t dim, void (*freeFunc)(void *)) +int RdUtils::RdSqlBindFloatVector(GRD_SqlStmt *stmt, uint32_t idx, float *val, uint32_t dim, void (*freeFunc)(void *)) { if (GRD_KVApiInfo.DBSqlBindFloatVector == nullptr) { GRD_KVApiInfo = GetApiInfoInstance(); @@ -536,7 +536,6 @@ int RdUtils::RdDbRekey(const char *dbFile, const char *configStr, const std::vec return ret; } - int RdUtils::RdDbGetVersion(GRD_DB *db, GRD_ConfigTypeE type, int &version) { if (GRD_KVApiInfo.DBGetConfigApi == nullptr) { 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 804016ed..526e2e08 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_manager_impl.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_manager_impl.cpp @@ -28,7 +28,7 @@ namespace OHOS::DistributedRdb { using namespace OHOS::Rdb; -using RdbServiceProxy = DistributedRdb::RdbServiceProxy; +using RdbServiceProxy = DistributedRdb::RdbServiceProxy; using namespace OHOS::NativeRdb; using namespace OHOS::DistributedRdb::RelationalStore; @@ -36,8 +36,7 @@ class DeathStub : public IRemoteBroker { public: DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.DistributedRdb.DeathStub"); }; -class DeathStubImpl : public IRemoteStub { -}; +class DeathStubImpl : public IRemoteStub {}; std::shared_ptr RdbManagerImpl::GetDistributedDataManager(const std::string &bundleName) { auto manager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); @@ -61,11 +60,11 @@ std::shared_ptr RdbManagerImpl::GetDistributedDataMana return std::shared_ptr(dataService.GetRefPtr(), [dataService, observer](const auto *) {}); } -static void LinkToDeath(const sptr& remote) +static void LinkToDeath(const sptr &remote) { - auto& manager = RdbManagerImpl::GetInstance(); - sptr deathRecipient = - new(std::nothrow) RdbManagerImpl::ServiceDeathRecipient(&manager); + auto &manager = RdbManagerImpl::GetInstance(); + sptr deathRecipient = new (std::nothrow) + RdbManagerImpl::ServiceDeathRecipient(&manager); if (deathRecipient == nullptr) { LOG_ERROR("new ServiceDeathRecipient failed."); return; @@ -84,7 +83,7 @@ RdbManagerImpl::~RdbManagerImpl() LOG_INFO("destroy."); } -RdbManagerImpl& RdbManagerImpl::GetInstance() +RdbManagerImpl &RdbManagerImpl::GetInstance() { static RdbManagerImpl manager; return manager; @@ -187,9 +186,9 @@ sptr RdbStoreDataServiceProxy::GetFeatureInterface(const std::str } MessageParcel reply; - MessageOption mo { MessageOption::TF_SYNC }; - int32_t error = Remote()->SendRequest( - static_cast(KvStoreInterfaceCode::GET_FEATURE_INTERFACE), data, reply, mo); + MessageOption mo{ MessageOption::TF_SYNC }; + int32_t error = + Remote()->SendRequest(static_cast(KvStoreInterfaceCode::GET_FEATURE_INTERFACE), data, reply, mo); if (error != 0) { LOG_ERROR("SendRequest returned %{public}d", error); return nullptr; @@ -217,9 +216,9 @@ int32_t RdbStoreDataServiceProxy::RegisterDeathObserver(const std::string &bundl } MessageParcel reply; - MessageOption mo { MessageOption::TF_SYNC }; - int32_t error = Remote()->SendRequest( - static_cast(KvStoreInterfaceCode::REGISTER_DEATH_OBSERVER), data, reply, mo); + MessageOption mo{ MessageOption::TF_SYNC }; + int32_t error = + Remote()->SendRequest(static_cast(KvStoreInterfaceCode::REGISTER_DEATH_OBSERVER), data, reply, mo); if (error != 0) { LOG_ERROR("SendRequest returned %{public}d", error); return E_ERROR; diff --git a/relational_store/frameworks/native/rdb/src/rdb_notifier_stub.cpp b/relational_store/frameworks/native/rdb/src/rdb_notifier_stub.cpp index 12938620..56467e66 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_notifier_stub.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_notifier_stub.cpp @@ -34,7 +34,7 @@ RdbNotifierStub::~RdbNotifierStub() noexcept { } -bool RdbNotifierStub::CheckInterfaceToken(MessageParcel& data) +bool RdbNotifierStub::CheckInterfaceToken(MessageParcel &data) { auto localDescriptor = GetDescriptor(); auto remoteDescriptor = data.ReadInterfaceToken(); @@ -45,8 +45,7 @@ bool RdbNotifierStub::CheckInterfaceToken(MessageParcel& data) return true; } -int RdbNotifierStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, - MessageOption &option) +int RdbNotifierStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) { LOG_DEBUG("code:%{public}u, callingPid:%{public}d", code, IPCSkeleton::GetCallingPid()); if (!CheckInterfaceToken(data)) { 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 c3e2f5c4..dd8279e7 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_security_manager.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_security_manager.cpp @@ -17,11 +17,12 @@ #include #include -#include #include #include #include +#include + #include "directory_ex.h" #include "file_ex.h" #include "hks_api.h" @@ -106,7 +107,7 @@ int32_t RdbSecurityManager::HksLoopUpdate(const struct HksBlob *handle, const st return HKS_ERROR_INVALID_ARGUMENT; } - struct HksBlob input = {MAX_UPDATE_SIZE, inData->data}; + struct HksBlob input = { MAX_UPDATE_SIZE, inData->data }; uint8_t *end = inData->data + inData->size - 1; outData->size = 0; struct HksBlob output = { MAX_OUTDATA_SIZE, outData->data }; @@ -162,7 +163,7 @@ int32_t RdbSecurityManager::HksDecryptThreeStage(const struct HksBlob *keyAlias, RdbSecurityManager::RdbSecurityManager() : nonce_(RDB_HKS_BLOB_TYPE_NONCE, RDB_HKS_BLOB_TYPE_NONCE + strlen(RDB_HKS_BLOB_TYPE_NONCE)), - aad_(RDB_HKS_BLOB_TYPE_AAD, RDB_HKS_BLOB_TYPE_AAD + strlen(RDB_HKS_BLOB_TYPE_AAD)){}; + aad_(RDB_HKS_BLOB_TYPE_AAD, RDB_HKS_BLOB_TYPE_AAD + strlen(RDB_HKS_BLOB_TYPE_AAD)) {}; RdbSecurityManager::~RdbSecurityManager() = default; 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 d268a394..dd8690a8 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_service_proxy.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_service_proxy.cpp @@ -17,8 +17,8 @@ #include "itypes_util.h" #include "logger.h" -#include "sqlite_utils.h" #include "result_set_proxy.h" +#include "sqlite_utils.h" namespace OHOS::DistributedRdb { using namespace OHOS::Rdb; @@ -90,8 +90,8 @@ int32_t RdbServiceProxy::InitNotifier(const RdbSyncerParam ¶m) int32_t RdbServiceProxy::InitNotifier(const RdbSyncerParam ¶m, sptr notifier) { MessageParcel reply; - int32_t status = IPC_SEND( - static_cast(RdbServiceCode::RDB_SERVICE_CMD_INIT_NOTIFIER), reply, param, notifier); + int32_t status = + IPC_SEND(static_cast(RdbServiceCode::RDB_SERVICE_CMD_INIT_NOTIFIER), reply, param, notifier); if (status != RDB_OK) { LOG_ERROR("status:%{public}d, bundleName:%{public}s", status, param.bundleName_.c_str()); } @@ -107,16 +107,16 @@ uint32_t RdbServiceProxy::GetSeqNum() return value; } -std::pair RdbServiceProxy::DoSync(const RdbSyncerParam& param, const Option &option, - const PredicatesMemo &predicates) +std::pair RdbServiceProxy::DoSync( + const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &predicates) { - std::pair result{RDB_ERROR, {}}; + std::pair result{ RDB_ERROR, {} }; MessageParcel reply; auto &[status, details] = result; status = IPC_SEND(static_cast(RdbServiceCode::RDB_SERVICE_CMD_SYNC), reply, param, option, predicates); if (status != RDB_OK) { - LOG_ERROR("status:%{public}d, bundleName:%{public}s, storeName:%{public}s", - status, param.bundleName_.c_str(), SqliteUtils::Anonymous(param.storeName_).c_str()); + LOG_ERROR("status:%{public}d, bundleName:%{public}s, storeName:%{public}s", status, param.bundleName_.c_str(), + SqliteUtils::Anonymous(param.storeName_).c_str()); return result; } @@ -128,8 +128,8 @@ std::pair RdbServiceProxy::DoSync(const RdbSyncerParam& param, return result; } -int32_t RdbServiceProxy::DoSync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &predicates, - const AsyncDetail &async) +int32_t RdbServiceProxy::DoSync( + const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &predicates, const AsyncDetail &async) { auto [status, details] = DoSync(param, option, predicates); if (status != RDB_OK) { @@ -146,8 +146,8 @@ int32_t RdbServiceProxy::DoSync(const RdbSyncerParam ¶m, const Option &optio int32_t RdbServiceProxy::DoAsync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &predicates) { MessageParcel reply; - int32_t status = IPC_SEND( - static_cast(RdbServiceCode::RDB_SERVICE_CMD_ASYNC), reply, param, option, predicates); + int32_t status = + IPC_SEND(static_cast(RdbServiceCode::RDB_SERVICE_CMD_ASYNC), reply, param, option, predicates); if (status != RDB_OK) { LOG_ERROR("status:%{public}d, bundleName:%{public}s, storeName:%{public}s, seqNum:%{public}u", status, param.bundleName_.c_str(), SqliteUtils::Anonymous(param.storeName_).c_str(), option.seqNum); @@ -155,8 +155,8 @@ int32_t RdbServiceProxy::DoAsync(const RdbSyncerParam ¶m, const Option &opti return status; } -int32_t RdbServiceProxy::DoAsync(const RdbSyncerParam& param, const Option &option, - const PredicatesMemo &predicates, const AsyncDetail & callback) +int32_t RdbServiceProxy::DoAsync( + const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &predicates, const AsyncDetail &callback) { Option asyncOption = option; if (callback != nullptr) { @@ -176,22 +176,21 @@ int32_t RdbServiceProxy::DoAsync(const RdbSyncerParam& param, const Option &opti return RDB_OK; } -int32_t RdbServiceProxy::SetDistributedTables(const RdbSyncerParam& param, const std::vector &tables, +int32_t RdbServiceProxy::SetDistributedTables(const RdbSyncerParam ¶m, const std::vector &tables, const std::vector &references, bool isRebuild, int32_t type) { MessageParcel reply; - int32_t status = IPC_SEND( - static_cast(RdbServiceCode::RDB_SERVICE_CMD_SET_DIST_TABLE), reply, param, tables, references, - type, isRebuild); + int32_t status = IPC_SEND(static_cast(RdbServiceCode::RDB_SERVICE_CMD_SET_DIST_TABLE), reply, param, + tables, references, type, isRebuild); if (status != RDB_OK) { - LOG_ERROR("status:%{public}d, bundleName:%{public}s, storeName:%{public}s, type:%{public}d", - status, param.bundleName_.c_str(), SqliteUtils::Anonymous(param.storeName_).c_str(), type); + LOG_ERROR("status:%{public}d, bundleName:%{public}s, storeName:%{public}s, type:%{public}d", status, + param.bundleName_.c_str(), SqliteUtils::Anonymous(param.storeName_).c_str(), type); } return status; } -int32_t RdbServiceProxy::Sync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &predicates, - const AsyncDetail &async) +int32_t RdbServiceProxy::Sync( + const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &predicates, const AsyncDetail &async) { if (option.isAsync) { return DoAsync(param, option, predicates, async); @@ -199,7 +198,7 @@ int32_t RdbServiceProxy::Sync(const RdbSyncerParam ¶m, const Option &option, return DoSync(param, option, predicates, async); } -std::string RdbServiceProxy::RemoveSuffix(const std::string& name) +std::string RdbServiceProxy::RemoveSuffix(const std::string &name) { std::string suffix(".db"); auto pos = name.rfind(suffix); @@ -209,8 +208,8 @@ std::string RdbServiceProxy::RemoveSuffix(const std::string& name) return { name, 0, pos }; } -int32_t RdbServiceProxy::Subscribe(const RdbSyncerParam ¶m, const SubscribeOption &option, - RdbStoreObserver *observer) +int32_t RdbServiceProxy::Subscribe( + const RdbSyncerParam ¶m, const SubscribeOption &option, RdbStoreObserver *observer) { if (observer == nullptr) { return RDB_ERROR; @@ -239,17 +238,16 @@ int32_t RdbServiceProxy::Subscribe(const RdbSyncerParam ¶m, const SubscribeO int32_t RdbServiceProxy::DoSubscribe(const RdbSyncerParam ¶m, const SubscribeOption &option) { MessageParcel reply; - int32_t status = IPC_SEND( - static_cast(RdbServiceCode::RDB_SERVICE_CMD_SUBSCRIBE), reply, param, option); + int32_t status = IPC_SEND(static_cast(RdbServiceCode::RDB_SERVICE_CMD_SUBSCRIBE), reply, param, option); if (status != RDB_OK) { - LOG_ERROR("status:%{public}d, bundleName:%{public}s, storeName:%{public}s", - status, param.bundleName_.c_str(), SqliteUtils::Anonymous(param.storeName_).c_str()); + LOG_ERROR("status:%{public}d, bundleName:%{public}s, storeName:%{public}s", status, param.bundleName_.c_str(), + SqliteUtils::Anonymous(param.storeName_).c_str()); } return status; } -int32_t RdbServiceProxy::UnSubscribe(const RdbSyncerParam ¶m, const SubscribeOption &option, - RdbStoreObserver *observer) +int32_t RdbServiceProxy::UnSubscribe( + const RdbSyncerParam ¶m, const SubscribeOption &option, RdbStoreObserver *observer) { if (observer == nullptr) { LOG_ERROR("observer is null."); @@ -261,9 +259,7 @@ int32_t RdbServiceProxy::UnSubscribe(const RdbSyncerParam ¶m, const Subscrib auto name = RemoveSuffix(param.storeName_); observers_.ComputeIfPresent(name, [observer](const auto &key, std::list &value) { LOG_INFO("before remove size=%{public}d", static_cast(value.size())); - value.remove_if([observer](const ObserverParam ¶m) { - return param.observer == observer; - }); + value.remove_if([observer](const ObserverParam ¶m) { return param.observer == observer; }); LOG_INFO("after remove size=%{public}d", static_cast(value.size())); return !(value.empty()); }); @@ -460,11 +456,11 @@ void RdbServiceProxy::OnDataChange( { LOG_DEBUG("store:%{public}s data change from :%{public}s, dataType:%{public}d, origin:%{public}d.", SqliteUtils::Anonymous(origin.store).c_str(), - origin.id.empty() ? "empty" : SqliteUtils::Anonymous(*origin.id.begin()).c_str(), - origin.dataType, origin.origin); + origin.id.empty() ? "empty" : SqliteUtils::Anonymous(*origin.id.begin()).c_str(), origin.dataType, + origin.origin); auto name = RdbServiceProxy::RemoveSuffix(origin.store); observers_.ComputeIfPresent(name, [&origin, &primaries, info = std::move(changeInfo)]( - const auto &key, const std::list &value) mutable { + const auto &key, const std::list &value) mutable { auto size = value.size(); for (const auto ¶ms : value) { params.observer->OnChange(origin, primaries, --size > 0 ? ChangeInfo(info) : std::move(info)); @@ -475,10 +471,10 @@ void RdbServiceProxy::OnDataChange( void RdbServiceProxy::OnSyncComplete(uint32_t seqNum, Details &&result) { - syncCallbacks_.ComputeIfPresent(seqNum, [&result] (const auto& key, const AsyncDetail& callback) { + syncCallbacks_.ComputeIfPresent(seqNum, [&result](const auto &key, const AsyncDetail &callback) { auto finished = result.empty() || (result.begin()->second.progress == SYNC_FINISH); LOG_DEBUG("Sync complete, seqNum%{public}d, result size:%{public}zu", key, result.size()); - if (callback!=nullptr) { + if (callback != nullptr) { callback(std::move(result)); } return !finished; @@ -499,11 +495,11 @@ void RdbServiceProxy::OnSyncComplete(const std::string &storeName, Details &&res }); } -int32_t RdbServiceProxy::SetSearchable(const RdbSyncerParam& param, bool isSearchable) +int32_t RdbServiceProxy::SetSearchable(const RdbSyncerParam ¶m, bool isSearchable) { MessageParcel reply; - int32_t status = IPC_SEND(static_cast(RdbServiceCode::RDB_SERVICE_CMD_SET_SEARCHABLE), - reply, param, isSearchable); + int32_t status = + IPC_SEND(static_cast(RdbServiceCode::RDB_SERVICE_CMD_SET_SEARCHABLE), reply, param, isSearchable); if (status != RDB_OK) { LOG_ERROR("RdbServiceProxy SetSearchable fail, status:%{public}d, " "bundleName:%{public}s, storeName:%{public}s", @@ -512,12 +508,12 @@ int32_t RdbServiceProxy::SetSearchable(const RdbSyncerParam& param, bool isSearc return status; } -int32_t RdbServiceProxy::NotifyDataChange(const RdbSyncerParam ¶m, const RdbChangedData &rdbChangedData, - const RdbNotifyConfig &rdbNotifyConfig) +int32_t RdbServiceProxy::NotifyDataChange( + const RdbSyncerParam ¶m, const RdbChangedData &rdbChangedData, const RdbNotifyConfig &rdbNotifyConfig) { MessageParcel reply; - int32_t status = IPC_SEND(static_cast(RdbServiceCode::RDB_SERVICE_CMD_NOTIFY_DATA_CHANGE), - reply, param, rdbChangedData, rdbNotifyConfig); + int32_t status = IPC_SEND(static_cast(RdbServiceCode::RDB_SERVICE_CMD_NOTIFY_DATA_CHANGE), reply, param, + rdbChangedData, rdbNotifyConfig); if (status != RDB_OK) { LOG_ERROR("RdbServiceProxy NotifyDataChange fail, status:%{public}d, " "bundleName:%{public}s, storeName:%{public}s", @@ -526,7 +522,7 @@ int32_t RdbServiceProxy::NotifyDataChange(const RdbSyncerParam ¶m, const Rdb return status; } -int32_t RdbServiceProxy::Disable(const RdbSyncerParam& param) +int32_t RdbServiceProxy::Disable(const RdbSyncerParam ¶m) { MessageParcel reply; int32_t status = IPC_SEND(static_cast(RdbServiceCode::RDB_SERVICE_CMD_DISABLE), reply, param); @@ -537,7 +533,7 @@ int32_t RdbServiceProxy::Disable(const RdbSyncerParam& param) return status; } -int32_t RdbServiceProxy::Enable(const RdbSyncerParam& param) +int32_t RdbServiceProxy::Enable(const RdbSyncerParam ¶m) { MessageParcel reply; int32_t status = IPC_SEND(static_cast(RdbServiceCode::RDB_SERVICE_CMD_ENABLE), reply, param); @@ -564,12 +560,12 @@ int32_t RdbServiceProxy::GetPassword(const RdbSyncerParam ¶m, std::vector RdbServiceProxy::LockCloudContainer(const RdbSyncerParam& param) +std::pair RdbServiceProxy::LockCloudContainer(const RdbSyncerParam ¶m) { MessageParcel reply; uint32_t expiredTime = 0; - int32_t status = IPC_SEND(static_cast(RdbServiceCode::RDB_SERVICE_CMD_LOCK_CLOUD_CONTAINER), reply, - param, expiredTime); + int32_t status = IPC_SEND( + static_cast(RdbServiceCode::RDB_SERVICE_CMD_LOCK_CLOUD_CONTAINER), reply, param, expiredTime); if (status != RDB_OK) { LOG_ERROR("fail, status:%{public}d, bundleName:%{public}s, storeName:%{public}s", status, param.bundleName_.c_str(), SqliteUtils::Anonymous(param.storeName_).c_str()); @@ -582,11 +578,11 @@ std::pair RdbServiceProxy::LockCloudContainer(const RdbSyncer return { status, expiredTime }; } -int32_t RdbServiceProxy::UnlockCloudContainer(const RdbSyncerParam& param) +int32_t RdbServiceProxy::UnlockCloudContainer(const RdbSyncerParam ¶m) { MessageParcel reply; - int32_t status = IPC_SEND(static_cast(RdbServiceCode::RDB_SERVICE_CMD_UNLOCK_CLOUD_CONTAINER), - reply, param); + int32_t status = + IPC_SEND(static_cast(RdbServiceCode::RDB_SERVICE_CMD_UNLOCK_CLOUD_CONTAINER), reply, param); if (status != RDB_OK) { LOG_ERROR("fail, status:%{public}d, bundleName:%{public}s, storeName:%{public}s", status, param.bundleName_.c_str(), SqliteUtils::Anonymous(param.storeName_).c_str()); 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 dc8ad28c..a0834c8b 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_sql_utils.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_sql_utils.cpp @@ -48,7 +48,7 @@ int RdbSqlUtils::CreateDirectory(const std::string &databaseDir) directories.push_back(tempDirectory); std::string databaseDirectory; - for (const std::string& directory : directories) { + for (const std::string &directory : directories) { databaseDirectory = databaseDirectory + "/" + directory; if (access(databaseDirectory.c_str(), F_OK) != 0) { if (MkDir(databaseDirectory)) { @@ -69,8 +69,8 @@ int RdbSqlUtils::CreateDirectory(const std::string &databaseDir) /** * @brief get custom data base path. */ -std::pair RdbSqlUtils::GetDefaultDatabasePath(const std::string &baseDir, const std::string &name, - const std::string &customDir) +std::pair RdbSqlUtils::GetDefaultDatabasePath( + const std::string &baseDir, const std::string &name, const std::string &customDir) { int errorCode = E_OK; if (customDir.empty()) { diff --git a/relational_store/frameworks/native/rdb/src/rdb_store.cpp b/relational_store/frameworks/native/rdb/src/rdb_store.cpp index 72136314..75109659 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_store.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_store.cpp @@ -18,8 +18,8 @@ #include "sqlite_utils.h" #include "traits.h" namespace OHOS::NativeRdb { -RdbStore::ModifyTime::ModifyTime(std::shared_ptr result, std::map, PRIKey> hashKeys, - bool isFromRowId) +RdbStore::ModifyTime::ModifyTime( + std::shared_ptr result, std::map, PRIKey> hashKeys, bool isFromRowId) : result_(std::move(result)), hash_(std::move(hashKeys)), isFromRowId_(isFromRowId) { for (auto &[_, priKey] : hash_) { @@ -119,8 +119,8 @@ int RdbStore::Insert(int64_t &outRowId, const std::string &table, const Row &row return errCode; } -int RdbStore::InsertWithConflictResolution(int64_t &outRowId, const std::string &table, const Row &row, - Resolution resolution) +int RdbStore::InsertWithConflictResolution( + int64_t &outRowId, const std::string &table, const Row &row, Resolution resolution) { auto [errCode, rowid] = Insert(table, row, resolution); if (errCode == E_OK) { @@ -156,8 +156,8 @@ std::pair RdbStore::BatchInsert(const std::string &table, const Re return { E_NOT_SUPPORT, -1 }; } -std::pair RdbStore::Update(const std::string &table, const Row &row, const std::string &where, - const Values &args, Resolution resolution) +std::pair RdbStore::Update( + const std::string &table, const Row &row, const std::string &where, const Values &args, Resolution resolution) { (void)table; (void)row; @@ -167,8 +167,8 @@ std::pair RdbStore::Update(const std::string &table, const Row &row, c return { E_NOT_SUPPORT, 0 }; } -int RdbStore::Update(int &changedRows, const std::string &table, const Row &row, const std::string &whereClause, - const Values &args) +int RdbStore::Update( + int &changedRows, const std::string &table, const Row &row, const std::string &whereClause, const Values &args) { auto [errCode, changes] = Update(table, row, whereClause, args, NO_ACTION); if (errCode == E_OK) { @@ -182,8 +182,8 @@ int RdbStore::Update(int &changedRows, const Row &row, const AbsRdbPredicates &p return Update(changedRows, predicates.GetTableName(), row, predicates.GetWhereClause(), predicates.GetBindArgs()); } -int RdbStore::Update(int &changedRows, const std::string &table, const Row &row, const std::string &whereClause, - const Olds &args) +int RdbStore::Update( + int &changedRows, const std::string &table, const Row &row, const std::string &whereClause, const Olds &args) { return Update(changedRows, table, row, whereClause, ToValues(args)); }; @@ -223,8 +223,8 @@ std::shared_ptr RdbStore::Query(int &errCode, bool distinct, const std::string &indexName, const std::string &orderBy, const int &limit, const int &offset) { std::string sql; - errCode = SqliteSqlBuilder::BuildQueryString(distinct, table, "", columns, whereClause, groupBy, indexName, - orderBy, limit, offset, sql); + errCode = SqliteSqlBuilder::BuildQueryString( + distinct, table, "", columns, whereClause, groupBy, indexName, orderBy, limit, offset, sql); if (errCode != E_OK) { return nullptr; } @@ -268,8 +268,8 @@ std::shared_ptr RdbStore::QueryByStep(const AbsRdbPredicates &predica return QueryByStep(sql, predicates.GetBindArgs()); } -std::shared_ptr RdbStore::RemoteQuery(const std::string &device, const AbsRdbPredicates &predicates, - const Fields &columns, int &errCode) +std::shared_ptr RdbStore::RemoteQuery( + const std::string &device, const AbsRdbPredicates &predicates, const Fields &columns, int &errCode) { (void)device; (void)predicates; @@ -278,8 +278,8 @@ std::shared_ptr RdbStore::RemoteQuery(const std::string &device, cons return nullptr; } -std::pair> RdbStore::QuerySharingResource(const AbsRdbPredicates &predicates, - const Fields &columns) +std::pair> RdbStore::QuerySharingResource( + const AbsRdbPredicates &predicates, const Fields &columns) { (void)predicates; (void)columns; @@ -430,8 +430,8 @@ int RdbStore::Restore(const std::string &backupPath, const std::vector return E_NOT_SUPPORT; } -int RdbStore::SetDistributedTables(const std::vector &tables, int32_t type, - const DistributedRdb::DistributedConfig &distributedConfig) +int RdbStore::SetDistributedTables( + const std::vector &tables, int32_t type, const DistributedRdb::DistributedConfig &distributedConfig) { (void)tables; (void)type; @@ -469,28 +469,28 @@ int RdbStore::Sync(const SyncOption &option, const AbsRdbPredicates &predicate, return E_NOT_SUPPORT; } -int RdbStore::Subscribe(const SubscribeOption& option, RdbStoreObserver *observer) +int RdbStore::Subscribe(const SubscribeOption &option, RdbStoreObserver *observer) { (void)option; (void)observer; return E_NOT_SUPPORT; } -int RdbStore::UnSubscribe(const SubscribeOption& option, RdbStoreObserver *observer) +int RdbStore::UnSubscribe(const SubscribeOption &option, RdbStoreObserver *observer) { (void)option; (void)observer; return E_NOT_SUPPORT; } -int RdbStore::SubscribeObserver(const SubscribeOption& option, const std::shared_ptr &observer) +int RdbStore::SubscribeObserver(const SubscribeOption &option, const std::shared_ptr &observer) { (void)option; (void)observer; return E_NOT_SUPPORT; } -int RdbStore::UnsubscribeObserver(const SubscribeOption& option, const std::shared_ptr &observer) +int RdbStore::UnsubscribeObserver(const SubscribeOption &option, const std::shared_ptr &observer) { (void)option; (void)observer; @@ -545,8 +545,8 @@ int32_t RdbStore::GetBackupStatus() const return SlaveStatus::UNDEFINED; } -RdbStore::ModifyTime RdbStore::GetModifyTime(const std::string &table, const std::string &column, - std::vector &keys) +RdbStore::ModifyTime RdbStore::GetModifyTime( + const std::string &table, const std::string &column, std::vector &keys) { (void)table; (void)column; @@ -567,8 +567,8 @@ int RdbStore::GetRebuilt(RebuiltType &rebuilt) return E_NOT_SUPPORT; } -std::pair RdbStore::Attach(const RdbStoreConfig &config, const std::string &attachName, - int32_t waitTime) +std::pair RdbStore::Attach( + const RdbStoreConfig &config, const std::string &attachName, int32_t waitTime) { (void)config; (void)attachName; @@ -600,4 +600,4 @@ std::string RdbStore::GetLogTableName(const std::string &tableName) { return "naturalbase_rdb_aux_" + tableName + "_log"; } -} \ No newline at end of file +} // namespace OHOS::NativeRdb \ No newline at end of file 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 01b0b2ba..0ef113d9 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_store_config.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_store_config.cpp @@ -21,6 +21,7 @@ #include "rdb_errno.h" #include "rdb_security_manager.h" #include "string_utils.h" +#include "sqlite_global_config.h" namespace OHOS::NativeRdb { using namespace OHOS::Rdb; @@ -35,6 +36,9 @@ RdbStoreConfig::RdbStoreConfig(const std::string &name, StorageMode storageMode, { name_ = StringUtils::ExtractFileName(name); cryptoParam_.encryptKey_ = encryptKey; + walLimitSize_ = GlobalExpr::DB_WAL_DEFAULT_SIZE; + checkpointSize_ = GlobalExpr::DB_WAL_WARNING_SIZE; + startCheckpointSize_ = GlobalExpr::DB_WAL_SIZE_LIMIT_MIN; } RdbStoreConfig::~RdbStoreConfig() @@ -245,7 +249,7 @@ std::string RdbStoreConfig::GetJournalModeValue(JournalMode journalMode) case JournalMode::MODE_TRUNCATE: return "TRUNCATE"; case JournalMode::MODE_PERSIST: - return "PERSIST"; + return "PERSIST"; case JournalMode::MODE_MEMORY: return "MEMORY"; case JournalMode::MODE_WAL: @@ -331,7 +335,7 @@ int RdbStoreConfig::GetReadConSize() const void RdbStoreConfig::SetReadConSize(int readConSize) { - readConSize_= readConSize; + readConSize_ = readConSize; } void RdbStoreConfig::SetEncryptKey(const std::vector &encryptKey) @@ -592,6 +596,36 @@ void RdbStoreConfig::SetPromiseInfo(PromiseInfo promiseInfo) promiseInfo_ = promiseInfo; } +ssize_t RdbStoreConfig::GetWalLimitSize() const +{ + return walLimitSize_; +} + +void RdbStoreConfig::SetWalLimitSize(ssize_t size) +{ + if (size < GlobalExpr::DB_WAL_DEFAULT_SIZE) { + size = GlobalExpr::DB_WAL_DEFAULT_SIZE; + } + if (size > GlobalExpr::DB_WAL_SIZE_LIMIT_MAX) { + size = GlobalExpr::DB_WAL_SIZE_LIMIT_MAX; + } + walLimitSize_ = size; + // '(size >> 1) + (size >> 2)' Size of the WAL file that does not checkpoint within 5 minutes when sqlite_busy + checkpointSize_ = (size >> 1) + (size >> 2); + // '(size >> 5) + (size >> 7)' Size of the WAL file for starting checkpoint. + startCheckpointSize_ = (size >> 5) + (size >> 7); +} + +ssize_t RdbStoreConfig::GetCheckpointSize() const +{ + return checkpointSize_; +} + +ssize_t RdbStoreConfig::GetStartCheckpointSize() const +{ + return startCheckpointSize_; +} + void RdbStoreConfig::EnableRekey(bool enable) { autoRekey_ = enable; 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 d91403e1..a5503baf 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_store_impl.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_store_impl.cpp @@ -15,6 +15,8 @@ #define LOG_TAG "RdbStoreImpl" #include "rdb_store_impl.h" +#include + #include #include #include @@ -23,7 +25,6 @@ #include #include #include -#include #include "cache_result_set.h" #include "directory_ex.h" @@ -43,10 +44,10 @@ #include "sqlite_statement.h" #include "sqlite_utils.h" #include "step_result_set.h" -#include "values_buckets.h" #include "task_executor.h" #include "traits.h" #include "transaction.h" +#include "values_buckets.h" #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) #include "delay_notify.h" #include "raw_data_parser.h" @@ -77,6 +78,7 @@ using RdbMgr = DistributedRdb::RdbManagerImpl; static constexpr const char *BEGIN_TRANSACTION_SQL = "begin;"; static constexpr const char *COMMIT_TRANSACTION_SQL = "commit;"; static constexpr const char *ROLLBACK_TRANSACTION_SQL = "rollback;"; +static constexpr const char *BACKUP_RESTORE = "backup.restore"; constexpr int64_t TIME_OUT = 1500; void RdbStoreImpl::InitSyncerParam(const RdbStoreConfig &config, bool created) @@ -145,8 +147,8 @@ void RdbStoreImpl::AfterOpen(const RdbParam ¶m, int32_t retry) } } -RdbStore::ModifyTime RdbStoreImpl::GetModifyTime(const std::string &table, const std::string &columnName, - std::vector &keys) +RdbStore::ModifyTime RdbStoreImpl::GetModifyTime( + const std::string &table, const std::string &columnName, std::vector &keys) { if (table.empty() || columnName.empty() || keys.empty()) { LOG_ERROR("invalid para."); @@ -234,8 +236,8 @@ std::string RdbStoreImpl::GetLogTableName(const std::string &tableName) return DistributedDB::RelationalStoreManager::GetDistributedLogTableName(tableName); } -std::pair> RdbStoreImpl::QuerySharingResource(const AbsRdbPredicates &predicates, - const Fields &columns) +std::pair> RdbStoreImpl::QuerySharingResource( + const AbsRdbPredicates &predicates, const Fields &columns) { if (config_.GetDBType() == DB_VECTOR) { return { E_NOT_SUPPORT, nullptr }; @@ -252,8 +254,8 @@ std::pair> RdbStoreImpl::QuerySharingResourc return { status, resultSet }; } -std::shared_ptr RdbStoreImpl::RemoteQuery(const std::string &device, const AbsRdbPredicates &predicates, - const Fields &columns, int &errCode) +std::shared_ptr RdbStoreImpl::RemoteQuery( + const std::string &device, const AbsRdbPredicates &predicates, const Fields &columns, int &errCode) { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); if (config_.GetDBType() == DB_VECTOR) { @@ -288,8 +290,8 @@ void RdbStoreImpl::NotifyDataChange() } } -int RdbStoreImpl::SetDistributedTables(const std::vector &tables, int32_t type, - const DistributedRdb::DistributedConfig &distributedConfig) +int RdbStoreImpl::SetDistributedTables( + const std::vector &tables, int32_t type, const DistributedRdb::DistributedConfig &distributedConfig) { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); if (config_.GetDBType() == DB_VECTOR || isReadOnly_) { @@ -303,8 +305,8 @@ int RdbStoreImpl::SetDistributedTables(const std::vector &tables, i if (errCode != E_OK) { return errCode; } - int32_t errorCode = service->SetDistributedTables(syncerParam_, tables, distributedConfig.references, - distributedConfig.isRebuild, type); + int32_t errorCode = service->SetDistributedTables( + syncerParam_, tables, distributedConfig.references, distributedConfig.isRebuild, type); if (errorCode != E_OK) { LOG_ERROR("Fail to set distributed tables, error=%{public}d", errorCode); return errorCode; @@ -322,9 +324,9 @@ int RdbStoreImpl::SetDistributedTables(const std::vector &tables, i { std::unique_lock lock(rwMutex_); if (distributedConfig.autoSync) { - cloudTables_.insert(tables.begin(), tables.end()); + cloudInfo_->AddTables(tables); } else { - std::for_each(tables.begin(), tables.end(), [this](const auto &table) { cloudTables_.erase(table); }); + cloudInfo_->RmvTables(tables); return E_OK; } } @@ -387,23 +389,23 @@ int RdbStoreImpl::Sync(const SyncOption &option, const AbsRdbPredicates &predica rdbOption.mode = option.mode; rdbOption.isAsync = !option.isBlock; RdbRadar ret(Scene::SCENE_SYNC, __FUNCTION__, config_.GetBundleName()); - ret = InnerSync(rdbOption, predicate.GetDistributedPredicates(), async); + ret = InnerSync(syncerParam_, rdbOption, predicate.GetDistributedPredicates(), async); return ret; } -int RdbStoreImpl::InnerSync(const DistributedRdb::RdbService::Option &option, - const DistributedRdb::PredicatesMemo &predicates, const RdbStore::AsyncDetail &async) +int RdbStoreImpl::InnerSync( + const RdbParam ¶m, const Options &option, const Memo &predicates, const AsyncDetail &async) { - auto [errCode, service] = RdbMgr::GetInstance().GetRdbService(syncerParam_); + auto [errCode, service] = RdbMgr::GetInstance().GetRdbService(param); if (errCode == E_NOT_SUPPORT) { return errCode; } if (errCode != E_OK) { - LOG_ERROR("GetRdbService is failed, err is %{public}d, bundleName is %{public}s.", - errCode, syncerParam_.bundleName_.c_str()); + LOG_ERROR("GetRdbService is failed, err is %{public}d, bundleName is %{public}s.", errCode, + param.bundleName_.c_str()); return errCode; } - errCode = service->Sync(syncerParam_, option, predicates, async); + errCode = service->Sync(param, option, predicates, async); if (errCode != E_OK) { LOG_ERROR("Sync is failed, err is %{public}d.", errCode); return errCode; @@ -422,7 +424,7 @@ Uri RdbStoreImpl::GetUri(const std::string &event) return Uri(rdbUri); } -int RdbStoreImpl::SubscribeLocal(const SubscribeOption& option, RdbStoreObserver *observer) +int RdbStoreImpl::SubscribeLocal(const SubscribeOption &option, RdbStoreObserver *observer) { std::lock_guard lock(mutex_); localObservers_.try_emplace(option.event); @@ -438,7 +440,7 @@ int RdbStoreImpl::SubscribeLocal(const SubscribeOption& option, RdbStoreObserver return E_OK; } -int RdbStoreImpl::SubscribeLocalShared(const SubscribeOption& option, RdbStoreObserver *observer) +int RdbStoreImpl::SubscribeLocalShared(const SubscribeOption &option, RdbStoreObserver *observer) { std::lock_guard lock(mutex_); localSharedObservers_.try_emplace(option.event); @@ -465,8 +467,8 @@ int RdbStoreImpl::SubscribeLocalShared(const SubscribeOption& option, RdbStoreOb return E_OK; } -int32_t RdbStoreImpl::SubscribeLocalDetail(const SubscribeOption &option, - const std::shared_ptr &observer) +int32_t RdbStoreImpl::SubscribeLocalDetail( + const SubscribeOption &option, const std::shared_ptr &observer) { auto connection = connectionPool_->AcquireConnection(false); if (connection == nullptr) { @@ -480,7 +482,7 @@ int32_t RdbStoreImpl::SubscribeLocalDetail(const SubscribeOption &option, return errCode; } -int RdbStoreImpl::SubscribeRemote(const SubscribeOption& option, RdbStoreObserver *observer) +int RdbStoreImpl::SubscribeRemote(const SubscribeOption &option, RdbStoreObserver *observer) { auto [errCode, service] = RdbMgr::GetInstance().GetRdbService(syncerParam_); if (errCode != E_OK) { @@ -503,7 +505,7 @@ int RdbStoreImpl::Subscribe(const SubscribeOption &option, RdbStoreObserver *obs return SubscribeRemote(option, observer); } -int RdbStoreImpl::UnSubscribeLocal(const SubscribeOption& option, RdbStoreObserver *observer) +int RdbStoreImpl::UnSubscribeLocal(const SubscribeOption &option, RdbStoreObserver *observer) { std::lock_guard lock(mutex_); auto obs = localObservers_.find(option.event); @@ -525,7 +527,7 @@ int RdbStoreImpl::UnSubscribeLocal(const SubscribeOption& option, RdbStoreObserv return E_OK; } -int RdbStoreImpl::UnSubscribeLocalAll(const SubscribeOption& option) +int RdbStoreImpl::UnSubscribeLocalAll(const SubscribeOption &option) { std::lock_guard lock(mutex_); auto obs = localObservers_.find(option.event); @@ -537,7 +539,7 @@ int RdbStoreImpl::UnSubscribeLocalAll(const SubscribeOption& option) return E_OK; } -int RdbStoreImpl::UnSubscribeLocalShared(const SubscribeOption& option, RdbStoreObserver *observer) +int RdbStoreImpl::UnSubscribeLocalShared(const SubscribeOption &option, RdbStoreObserver *observer) { std::lock_guard lock(mutex_); auto obs = localSharedObservers_.find(option.event); @@ -569,7 +571,7 @@ int RdbStoreImpl::UnSubscribeLocalShared(const SubscribeOption& option, RdbStore return E_OK; } -int RdbStoreImpl::UnSubscribeLocalSharedAll(const SubscribeOption& option) +int RdbStoreImpl::UnSubscribeLocalSharedAll(const SubscribeOption &option) { std::lock_guard lock(mutex_); auto obs = localSharedObservers_.find(option.event); @@ -598,8 +600,8 @@ int RdbStoreImpl::UnSubscribeLocalSharedAll(const SubscribeOption& option) return E_OK; } -int32_t RdbStoreImpl::UnsubscribeLocalDetail(const SubscribeOption& option, - const std::shared_ptr &observer) +int32_t RdbStoreImpl::UnsubscribeLocalDetail( + const SubscribeOption &option, const std::shared_ptr &observer) { auto connection = connectionPool_->AcquireConnection(false); if (connection == nullptr) { @@ -613,7 +615,7 @@ int32_t RdbStoreImpl::UnsubscribeLocalDetail(const SubscribeOption& option, return errCode; } -int RdbStoreImpl::UnSubscribeRemote(const SubscribeOption& option, RdbStoreObserver *observer) +int RdbStoreImpl::UnSubscribeRemote(const SubscribeOption &option, RdbStoreObserver *observer) { auto [errCode, service] = RdbMgr::GetInstance().GetRdbService(syncerParam_); if (errCode != E_OK) { @@ -639,7 +641,7 @@ int RdbStoreImpl::UnSubscribe(const SubscribeOption &option, RdbStoreObserver *o return UnSubscribeRemote(option, observer); } -int RdbStoreImpl::SubscribeObserver(const SubscribeOption& option, const std::shared_ptr &observer) +int RdbStoreImpl::SubscribeObserver(const SubscribeOption &option, const std::shared_ptr &observer) { if (config_.GetDBType() == DB_VECTOR) { return E_NOT_SUPPORT; @@ -647,7 +649,7 @@ int RdbStoreImpl::SubscribeObserver(const SubscribeOption& option, const std::sh return SubscribeLocalDetail(option, observer); } -int RdbStoreImpl::UnsubscribeObserver(const SubscribeOption& option, const std::shared_ptr &observer) +int RdbStoreImpl::UnsubscribeObserver(const SubscribeOption &option, const std::shared_ptr &observer) { if (config_.GetDBType() == DB_VECTOR) { return E_NOT_SUPPORT; @@ -726,8 +728,8 @@ void RdbStoreImpl::InitDelayNotifier() return; } delayNotifier_->SetExecutorPool(TaskExecutor::GetInstance().GetExecutor()); - delayNotifier_->SetTask([param = syncerParam_] - (const DistributedRdb::RdbChangedData& rdbChangedData, const RdbNotifyConfig& rdbNotifyConfig) -> int { + delayNotifier_->SetTask([param = syncerParam_](const DistributedRdb::RdbChangedData &rdbChangedData, + const RdbNotifyConfig &rdbNotifyConfig) -> int { auto [errCode, service] = RdbMgr::GetInstance().GetRdbService(param); if (errCode == E_NOT_SUPPORT) { return errCode; @@ -752,7 +754,7 @@ int RdbStoreImpl::RegisterDataChangeCallback() InitDelayNotifier(); auto callBack = [delayNotifier = delayNotifier_](const std::set &tables) { DistributedRdb::RdbChangedData rdbChangedData; - for (const auto& table : tables) { + for (const auto &table : tables) { rdbChangedData.tableData[table].isTrackedDataChange = true; } if (delayNotifier != nullptr) { @@ -821,7 +823,8 @@ int RdbStoreImpl::ModifyLockStatus(const AbsRdbPredicates &predicates, bool isLo if (errCode == E_WAIT_COMPENSATED_SYNC) { LOG_DEBUG("Start compensation sync."); DistributedRdb::RdbService::Option option = { DistributedRdb::TIME_FIRST, 0, true, true, true }; - InnerSync(option, AbsRdbPredicates(predicates.GetTableName()).GetDistributedPredicates(), nullptr); + auto memo = AbsRdbPredicates(predicates.GetTableName()).GetDistributedPredicates(); + InnerSync(syncerParam_, option, memo, nullptr); return E_OK; } if (errCode != E_OK) { @@ -1021,7 +1024,9 @@ std::pair RdbStoreImpl::BatchInsert(const std::string &table, cons for (const auto &[sql, bindArgs] : executeSqlArgs) { auto [errCode, statement] = GetStatement(sql, connection); if (statement == nullptr) { - continue; + LOG_ERROR("statement is nullptr, errCode:0x%{public}x, args:%{public}zu, table:%{public}s, sql:%{public}s", + errCode, bindArgs.size(), table.c_str(), SqliteUtils::AnonySql(sql).c_str()); + return { E_OK, -1 }; } for (const auto &args : bindArgs) { auto errCode = statement->Execute(args); @@ -1031,7 +1036,7 @@ std::pair RdbStoreImpl::BatchInsert(const std::string &table, cons } if (errCode != E_OK) { LOG_ERROR("failed, errCode:%{public}d,args:%{public}zu,table:%{public}s,sql:%{public}s", errCode, - bindArgs.size(), table.c_str(), sql.c_str()); + bindArgs.size(), table.c_str(), SqliteUtils::AnonySql(sql).c_str()); return { E_OK, -1 }; } } @@ -1041,8 +1046,8 @@ std::pair RdbStoreImpl::BatchInsert(const std::string &table, cons return { E_OK, int64_t(rows.RowSize()) }; } -std::pair RdbStoreImpl::Update(const std::string &table, const Row &row, const std::string &where, - const Values &args, Resolution resolution) +std::pair RdbStoreImpl::Update( + const std::string &table, const Row &row, const std::string &where, const Values &args, Resolution resolution) { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); if (isReadOnly_ || (config_.GetDBType() == DB_VECTOR)) { @@ -1170,7 +1175,7 @@ int RdbStoreImpl::ExecuteSql(const std::string &sql, const Values &args) } errCode = statement->Execute(args); if (errCode != E_OK) { - LOG_ERROR("failed,error:0x%{public}x sql:%{public}s.", errCode, sql.c_str()); + LOG_ERROR("failed,error:0x%{public}x sql:%{public}s.", errCode, SqliteUtils::AnonySql(sql).c_str()); if (errCode == E_SQLITE_LOCKED || errCode == E_SQLITE_BUSY) { connectionPool_->Dump(true, "EXECUTE"); } @@ -1184,7 +1189,8 @@ int RdbStoreImpl::ExecuteSql(const std::string &sql, const Values &args) statement = nullptr; if (vSchema_ < static_cast(version)) { LOG_INFO("db:%{public}s exe DDL schema<%{public}" PRIi64 "->%{public}" PRIi64 "> sql:%{public}s.", - SqliteUtils::Anonymous(name_).c_str(), vSchema_, static_cast(version), sql.c_str()); + SqliteUtils::Anonymous(name_).c_str(), vSchema_, static_cast(version), + SqliteUtils::AnonySql(sql).c_str()); vSchema_ = version; errCode = connectionPool_->RestartReaders(); } @@ -1206,7 +1212,7 @@ std::pair RdbStoreImpl::Execute(const std::string &sql, co 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()); + LOG_ERROR("Not support the sqlType: %{public}d, sql: %{public}s", sqlType, SqliteUtils::AnonySql(sql).c_str()); return { E_NOT_SUPPORT_THE_SQL, object }; } @@ -1226,7 +1232,7 @@ std::pair RdbStoreImpl::Execute(const std::string &sql, co errCode = statement->Execute(args); if (errCode != E_OK) { - LOG_ERROR("failed,error:0x%{public}x sql:%{public}s.", errCode, sql.c_str()); + LOG_ERROR("failed,error:0x%{public}x sql:%{public}s.", errCode, SqliteUtils::AnonySql(sql).c_str()); if (errCode == E_SQLITE_LOCKED || errCode == E_SQLITE_BUSY) { connectionPool_->Dump(true, "EXECUTE"); } @@ -1240,8 +1246,8 @@ std::pair RdbStoreImpl::Execute(const std::string &sql, co return HandleDifferentSqlTypes(statement, sql, object, sqlType); } -std::pair RdbStoreImpl::HandleDifferentSqlTypes(std::shared_ptr statement, - const std::string &sql, const ValueObject &object, int sqlType) +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) { @@ -1260,7 +1266,7 @@ std::pair RdbStoreImpl::HandleDifferentSqlTypes(std::share } if (statement->GetColumnCount() > 1) { - LOG_ERROR("Not support the sql:%{public}s, column count more than 1", sql.c_str()); + LOG_ERROR("Not support the sql:%{public}s, column count more than 1", SqliteUtils::AnonySql(sql).c_str()); return { E_NOT_SUPPORT_THE_SQL, object }; } } @@ -1271,7 +1277,8 @@ std::pair RdbStoreImpl::HandleDifferentSqlTypes(std::share auto [err, version] = statement->ExecuteForValue(); if (vSchema_ < static_cast(version)) { LOG_INFO("db:%{public}s exe DDL schema<%{public}" PRIi64 "->%{public}" PRIi64 "> sql:%{public}s.", - SqliteUtils::Anonymous(name_).c_str(), vSchema_, static_cast(version), sql.c_str()); + SqliteUtils::Anonymous(name_).c_str(), vSchema_, static_cast(version), + SqliteUtils::AnonySql(sql).c_str()); vSchema_ = version; errCode = connectionPool_->RestartReaders(); } @@ -1290,7 +1297,7 @@ int RdbStoreImpl::ExecuteAndGetLong(int64_t &outValue, const std::string &sql, c } auto [err, object] = statement->ExecuteForValue(args); if (err != E_OK) { - LOG_ERROR("failed, sql %{public}s, ERROR is %{public}d.", sql.c_str(), err); + LOG_ERROR("failed, sql %{public}s, ERROR is %{public}d.", SqliteUtils::AnonySql(sql).c_str(), err); } outValue = object; return err; @@ -1308,7 +1315,7 @@ int RdbStoreImpl::ExecuteAndGetString(std::string &outValue, const std::string & ValueObject object; std::tie(errCode, object) = statement->ExecuteForValue(args); if (errCode != E_OK) { - LOG_ERROR("failed, sql %{public}s, ERROR is %{public}d.", sql.c_str(), errCode); + LOG_ERROR("failed, sql %{public}s, ERROR is %{public}d.", SqliteUtils::AnonySql(sql).c_str(), errCode); } outValue = static_cast(object); return errCode; @@ -1337,10 +1344,8 @@ int RdbStoreImpl::ExecuteForLastInsertedRowId(int64_t &outValue, const std::stri auto allEnd = std::chrono::steady_clock::now(); int64_t totalCostTime = std::chrono::duration_cast(begin - allEnd).count(); if (totalCostTime >= TIME_OUT) { - int64_t prepareCost = - std::chrono::duration_cast(beginExec - begin).count(); - int64_t execCost = - std::chrono::duration_cast(beginExec - beginResult).count(); + int64_t prepareCost = std::chrono::duration_cast(beginExec - begin).count(); + int64_t execCost = std::chrono::duration_cast(beginExec - beginResult).count(); int64_t resultCost = std::chrono::duration_cast(allEnd - beginResult).count(); LOG_WARN("total[%{public}" PRId64 "] stmt[%{public}" PRId64 "] exec[%{public}" PRId64 "] result[%{public}" PRId64 "] " @@ -1429,7 +1434,7 @@ int RdbStoreImpl::Backup(const std::string &databasePath, const std::vector RdbStoreImpl::CreateBackupBindArgs(const std::string &databasePath, - const std::vector &destEncryptKey) +std::vector RdbStoreImpl::CreateBackupBindArgs( + const std::string &databasePath, const std::vector &destEncryptKey) { std::vector bindArgs; bindArgs.emplace_back(databasePath); @@ -1539,7 +1544,7 @@ int RdbStoreImpl::InnerBackup(const std::string &databasePath, const std::vector return (res == E_OK) ? ret : res; } -std::pair RdbStoreImpl::BeginExecuteSql(const std::string& sql) +std::pair RdbStoreImpl::BeginExecuteSql(const std::string &sql) { int type = SqliteUtils::GetSqlStatementType(sql); if (SqliteUtils::IsSpecial(type)) { @@ -1637,7 +1642,7 @@ int RdbStoreImpl::SetDefaultEncryptAlgo(const ConnectionPool::SharedConn &conn, } sql = std::string(GlobalExpr::CIPHER_DEFAULT_ATTACH_PAGE_SIZE_PREFIX) + - std::to_string(config.GetCryptoParam().cryptoPageSize); + std::to_string(config.GetCryptoParam().cryptoPageSize); return SetDefaultEncryptSql(statement, sql, config); } @@ -1829,16 +1834,16 @@ int RdbStoreImpl::BeginTransaction() if (errCode == E_SQLITE_LOCKED || errCode == E_SQLITE_BUSY) { connectionPool_->Dump(true, "BEGIN"); } - LOG_ERROR("transaction id: %{public}zu, storeName: %{public}s, errCode: %{public}d", - transactionId, SqliteUtils::Anonymous(name_).c_str(), errCode); + LOG_ERROR("transaction id: %{public}zu, storeName: %{public}s, errCode: %{public}d", transactionId, + SqliteUtils::Anonymous(name_).c_str(), errCode); return errCode; } connectionPool_->SetInTransaction(true); connectionPool_->GetTransactionStack().push(transaction); // 1 means the number of transactions in process if (transactionId > 1) { - LOG_WARN("transaction id: %{public}zu, storeName: %{public}s, errCode: %{public}d", - transactionId, SqliteUtils::Anonymous(name_).c_str(), errCode); + LOG_WARN("transaction id: %{public}zu, storeName: %{public}s, errCode: %{public}d", transactionId, + SqliteUtils::Anonymous(name_).c_str(), errCode); } return E_OK; @@ -1848,7 +1853,7 @@ std::pair RdbStoreImpl::BeginTrans() { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); if (!config_.IsVector() || isReadOnly_) { - return {E_NOT_SUPPORT, 0}; + return { E_NOT_SUPPORT, 0 }; } int64_t tmpTrxId = 0; @@ -1856,7 +1861,7 @@ std::pair RdbStoreImpl::BeginTrans() if (connection == nullptr) { LOG_ERROR("Get null connection, storeName: %{public}s errCode:0x%{public}x.", SqliteUtils::Anonymous(name_).c_str(), errCode); - return {errCode, 0}; + return { errCode, 0 }; } tmpTrxId = newTrxId_.fetch_add(1); trxConnMap_.Insert(tmpTrxId, connection); @@ -1864,7 +1869,7 @@ std::pair RdbStoreImpl::BeginTrans() if (errCode != E_OK) { trxConnMap_.Erase(tmpTrxId); } - return {errCode, tmpTrxId}; + return { errCode, tmpTrxId }; } /** @@ -1904,8 +1909,8 @@ int RdbStoreImpl::RollBack() if (errCode == E_SQLITE_BUSY || errCode == E_SQLITE_LOCKED) { Reportor::Report(Reportor::Create(config_, errCode, "ErrorType: RollBusy")); } - LOG_ERROR("failed, id: %{public}zu, storeName: %{public}s, errCode: %{public}d", - transactionId, SqliteUtils::Anonymous(name_).c_str(), errCode); + LOG_ERROR("failed, id: %{public}zu, storeName: %{public}s, errCode: %{public}d", transactionId, + SqliteUtils::Anonymous(name_).c_str(), errCode); return errCode; } if (connectionPool_->GetTransactionStack().empty()) { @@ -1913,14 +1918,14 @@ int RdbStoreImpl::RollBack() } // 1 means the number of transactions in process if (transactionId > 1) { - LOG_WARN("transaction id: %{public}zu, storeName: %{public}s, errCode: %{public}d", - transactionId, SqliteUtils::Anonymous(name_).c_str(), errCode); + LOG_WARN("transaction id: %{public}zu, storeName: %{public}s, errCode: %{public}d", transactionId, + SqliteUtils::Anonymous(name_).c_str(), errCode); } return E_OK; } -int RdbStoreImpl::ExecuteByTrxId(const std::string &sql, int64_t trxId, bool closeConnAfterExecute, - const std::vector &bindArgs) +int RdbStoreImpl::ExecuteByTrxId( + const std::string &sql, int64_t trxId, bool closeConnAfterExecute, const std::vector &bindArgs) { if ((!config_.IsVector()) || isReadOnly_) { return E_NOT_SUPPORT; @@ -1982,8 +1987,8 @@ int RdbStoreImpl::Commit() BaseTransaction transaction = connectionPool_->GetTransactionStack().top(); std::string sqlStr = transaction.GetCommitStr(); if (sqlStr.size() <= 1) { - LOG_WARN("id: %{public}zu, storeName: %{public}s, sql: %{public}s", - transactionId, SqliteUtils::Anonymous(name_).c_str(), sqlStr.c_str()); + LOG_WARN("id: %{public}zu, storeName: %{public}s, sql: %{public}s", transactionId, + SqliteUtils::Anonymous(name_).c_str(), sqlStr.c_str()); connectionPool_->GetTransactionStack().pop(); return E_OK; } @@ -2001,8 +2006,8 @@ int RdbStoreImpl::Commit() if (errCode == E_SQLITE_BUSY || errCode == E_SQLITE_LOCKED) { Reportor::Report(Reportor::Create(config_, errCode, "ErrorType: CommitBusy")); } - LOG_ERROR("failed, id: %{public}zu, storeName: %{public}s, errCode: %{public}d", - transactionId, SqliteUtils::Anonymous(name_).c_str(), errCode); + LOG_ERROR("failed, id: %{public}zu, storeName: %{public}s, errCode: %{public}d", transactionId, + SqliteUtils::Anonymous(name_).c_str(), errCode); return errCode; } connectionPool_->SetInTransaction(false); @@ -2096,26 +2101,9 @@ std::string RdbStoreImpl::GetName() void RdbStoreImpl::DoCloudSync(const std::string &table) { #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) - { - std::shared_lock lock(rwMutex_); - if (cloudTables_.empty() || (!table.empty() && cloudTables_.find(table) == cloudTables_.end())) { - return; - } - } - { - std::lock_guard lock(mutex_); - if (syncTables_ == nullptr) { - syncTables_ = std::make_shared>(); - } - auto empty = syncTables_->empty(); - if (table.empty()) { - syncTables_->insert(cloudTables_.begin(), cloudTables_.end()); - } else { - syncTables_->insert(table); - } - if (!empty) { - return; - } + auto needSync = cloudInfo_->Change(table); + if (!needSync) { + return; } auto pool = TaskExecutor::GetInstance().GetExecutor(); if (pool == nullptr) { @@ -2123,19 +2111,18 @@ void RdbStoreImpl::DoCloudSync(const std::string &table) } auto interval = std::chrono::duration_cast(std::chrono::milliseconds(INTERVAL)); - pool->Schedule(interval, [this]() { - std::shared_ptr> ptr; - { - std::lock_guard lock(mutex_); - ptr = syncTables_; - syncTables_ = nullptr; + pool->Schedule(interval, [cloudInfo = std::weak_ptr(cloudInfo_), param = syncerParam_]() { + auto changeInfo = cloudInfo.lock(); + if (changeInfo == nullptr) { + return; } - if (ptr == nullptr) { + auto tables = changeInfo->Steal(); + if (tables.empty()) { return; } DistributedRdb::RdbService::Option option = { DistributedRdb::TIME_FIRST, 0, true, true }; - InnerSync(option, - AbsRdbPredicates(std::vector(ptr->begin(), ptr->end())).GetDistributedPredicates(), nullptr); + auto memo = AbsRdbPredicates(std::vector(tables.begin(), tables.end())).GetDistributedPredicates(); + InnerSync(param, option, memo, nullptr); }); #endif } @@ -2196,10 +2183,10 @@ int RdbStoreImpl::Restore(const std::string &backupPath, const std::vector> RdbStoreImpl::CreateWritableConn() { - auto config = config_; + auto config = config_; config.SetHaMode(HAMode::SINGLE); + config.SetCreateNecessary(false); auto [result, conn] = Connection::Create(config, true); if (result != E_OK || conn == nullptr) { LOG_ERROR("create connection failed, err:%{public}d", result); @@ -2259,7 +2246,7 @@ std::pair> RdbStoreImpl::GetStatement( return conn->CreateStatement(sql, conn); } -std::pair> RdbStoreImpl::GetStatement(const std::string& sql, bool read) const +std::pair> RdbStoreImpl::GetStatement(const std::string &sql, bool read) const { auto conn = connectionPool_->AcquireConnection(read); if (conn == nullptr) { @@ -2377,4 +2364,51 @@ std::pair> RdbStoreImpl::CreateTransaction transactions_.push_back(trans); return { errCode, trans }; } + +int32_t RdbStoreImpl::CloudTables::AddTables(const std::vector &tables) +{ + std::lock_guard lock(mutex_); + for (auto &table : tables) { + tables_.insert(table); + } + return E_OK; +} + +int32_t RdbStoreImpl::CloudTables::RmvTables(const std::vector &tables) +{ + std::lock_guard lock(mutex_); + for (auto &table : tables) { + tables_.erase(table); + } + return E_OK; +} + +bool RdbStoreImpl::CloudTables::Change(const std::string &table) +{ + bool needSync = false; + { + std::lock_guard lock(mutex_); + if (tables_.empty() || (!table.empty() && tables_.find(table) == tables_.end())) { + return needSync; + } + // from empty, then need schedule the cloud sync, others only wait the schedule execute + needSync = changes_.empty(); + if (!table.empty()) { + changes_.insert(table); + } else { + changes_.insert(tables_.begin(), tables_.end()); + } + } + return needSync; +} + +std::set RdbStoreImpl::CloudTables::Steal() +{ + std::set result; + { + std::lock_guard lock(mutex_); + result = std::move(changes_); + } + return result; +} } // namespace OHOS::NativeRdb \ No newline at end of file diff --git a/relational_store/frameworks/native/rdb/src/rdb_store_manager.cpp b/relational_store/frameworks/native/rdb/src/rdb_store_manager.cpp index b204617a..8ec1f12b 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_store_manager.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_store_manager.cpp @@ -20,11 +20,11 @@ #include "logger.h" #include "rdb_errno.h" +#include "rdb_radar_reporter.h" #include "rdb_store_impl.h" #include "rdb_trace.h" #include "sqlite_global_config.h" #include "task_executor.h" -#include "rdb_radar_reporter.h" #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) #if !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) @@ -33,9 +33,9 @@ #endif #include "security_policy.h" #endif +#include "rdb_fault_hiview_reporter.h" #include "sqlite_utils.h" #include "string_utils.h" -#include "rdb_fault_hiview_reporter.h" namespace OHOS { namespace NativeRdb { @@ -43,7 +43,6 @@ using namespace OHOS::Rdb; using Reportor = RdbFaultHiViewReporter; __attribute__((used)) const bool RdbStoreManager::regCollector_ = RdbFaultHiViewReporter::RegCollector(RdbStoreManager::Collector); -constexpr int RETRY_INTERVAL = 1; RdbStoreManager &RdbStoreManager::GetInstance() { static RdbStoreManager manager; @@ -67,18 +66,12 @@ std::shared_ptr RdbStoreManager::GetStoreFromCache(const RdbStoreC } std::shared_ptr rdbStore = it->second.lock(); if (rdbStore == nullptr) { - storeCache_.erase(path); + storeCache_.erase(it); return nullptr; } - if (!(rdbStore->GetConfig() == config)) { - storeCache_.erase(path); - auto pool = TaskExecutor::GetInstance().GetExecutor(); - if (pool != nullptr) { - pool->Schedule(std::chrono::seconds(RETRY_INTERVAL), [config, rdbStore]() { - Reportor::Report(Reportor::Create(config, E_CONFIG_INVALID_CHANGE, - "ErrorType:Config diff!" + RdbStoreConfig::Format(rdbStore->GetConfig(), config))); - }); - } + auto oldConfig = rdbStore->GetConfig(); + if (oldConfig != config) { + storeCache_.erase(it); LOG_INFO("app[%{public}s:%{public}s] path[%{public}s]" " cfg[%{public}d,%{public}d,%{public}d,%{public}d,%{public}d,%{public}d,%{public}d,%{public}s]" " %{public}s", @@ -94,44 +87,42 @@ std::shared_ptr RdbStoreManager::GetStoreFromCache(const RdbStoreC std::shared_ptr RdbStoreManager::GetRdbStore( const RdbStoreConfig &config, int &errCode, int version, RdbOpenCallback &openCallback) { - RdbStoreConfig modifyConfig = config; // TOD this lock should only work on storeCache_, add one more lock for connectionpool std::lock_guard lock(mutex_); - auto path = modifyConfig.GetRoleType() != OWNER ? modifyConfig.GetVisitorDir() : modifyConfig.GetPath(); - bundleName_ = modifyConfig.GetBundleName(); - std::shared_ptr rdbStore = GetStoreFromCache(modifyConfig, path); + auto path = config.GetRoleType() != OWNER ? config.GetVisitorDir() : config.GetPath(); + bundleName_ = config.GetBundleName(); + std::shared_ptr rdbStore = GetStoreFromCache(config, path); if (rdbStore != nullptr) { return rdbStore; } + RdbStoreConfig modifyConfig = config; if (modifyConfig.GetRoleType() == OWNER && IsConfigInvalidChanged(path, modifyConfig)) { errCode = E_CONFIG_INVALID_CHANGE; return nullptr; } - if (modifyConfig.GetRoleType() == VISITOR_WRITE) { - Param param = GetSyncParam(config); - int32_t status = GetPromiseFromService(param); - if (status != E_OK) { - LOG_ERROR("failed, storeName:%{public}s, status:%{public}d", config.GetName().c_str(), status); - return nullptr; - } + + if (modifyConfig.GetRoleType() == VISITOR_WRITE && !IsPermitted(GetSyncParam(config))) { + errCode = E_PERMISSION_DENIED; + return nullptr; } + rdbStore = std::make_shared(modifyConfig, errCode); + if (errCode != E_OK && modifyConfig != config) { + LOG_WARN("Failed to GetRdbStore using modifyConfig. path:%{public}s, rc=%{public}d", + SqliteUtils::Anonymous(path).c_str(), errCode); + rdbStore = std::make_shared(config, errCode); // retry with input config + } if (errCode != E_OK) { - LOG_ERROR("GetRdbStore fail path:%{public}s, rc=%{public}d", SqliteUtils::Anonymous(path).c_str(), errCode); + LOG_ERROR("GetRdbStore failed. path:%{public}s, rc=%{public}d", + SqliteUtils::Anonymous(path).c_str(), errCode); return nullptr; } if (modifyConfig.GetRoleType() == OWNER && !modifyConfig.IsReadOnly()) { errCode = SetSecurityLabel(modifyConfig); if (errCode != E_OK) { - LOG_ERROR("fail, storeName:%{public}s security %{public}d errCode:%{public}d", - SqliteUtils::Anonymous(modifyConfig.GetName()).c_str(), modifyConfig.GetSecurityLevel(), errCode); return nullptr; } - if (modifyConfig.IsVector()) { - storeCache_[path] = rdbStore; - return rdbStore; - } (void)rdbStore->ExchangeSlaverToMaster(); errCode = ProcessOpenCallback(*rdbStore, modifyConfig, version, openCallback); if (errCode != E_OK) { @@ -141,8 +132,7 @@ std::shared_ptr RdbStoreManager::GetRdbStore( return nullptr; } } - - storeCache_[path] = rdbStore; + storeCache_.insert_or_assign(std::move(path), rdbStore); return rdbStore; } @@ -220,25 +210,25 @@ int32_t RdbStoreManager::GetParamFromService(DistributedRdb::RdbSyncerParam &par return E_ERROR; } -int32_t RdbStoreManager::GetPromiseFromService(DistributedRdb::RdbSyncerParam ¶m) +bool RdbStoreManager::IsPermitted(const DistributedRdb::RdbSyncerParam ¶m) { #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; + return false; } if (err != E_OK || service == nullptr) { - LOG_ERROR("GetRdbService failed, err is %{public}d.", err); - return E_ERROR; + LOG_ERROR("GetRdbService failed, bundleName:%{public}s, err:%{public}d.", param.bundleName_.c_str(), err); + return false; } err = service->VerifyPromiseInfo(param); - if (err != DistributedRdb::RDB_OK) { - LOG_ERROR("failed, err is %{public}d.", err); - return E_ERROR; + if (err == DistributedRdb::RDB_OK) { + return true; } - return E_OK; + LOG_ERROR("failed, bundleName:%{public}s, store:%{public}s, err:%{public}d.", param.bundleName_.c_str(), + SqliteUtils::Anonymous(param.storeName_).c_str(), err); #endif - return E_ERROR; + return false; } void RdbStoreManager::Clear() diff --git a/relational_store/frameworks/native/rdb/src/rdb_types_util.cpp b/relational_store/frameworks/native/rdb/src/rdb_types_util.cpp index a4ab7de3..bd50fb2e 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_types_util.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_types_util.cpp @@ -18,10 +18,9 @@ namespace OHOS::ITypesUtil { template<> bool Marshalling(const SyncerParam &input, MessageParcel &data) { - return ITypesUtil::Marshal(data, input.bundleName_, input.hapName_, input.storeName_, input.area_, - input.level_, input.type_, input.isEncrypt_, input.password_, input.customDir_, input.isAutoClean_, - input.isSearchable_, input.haMode_, input.infos_, input.tokenIds_, input.uids_, input.user_, - input.permissionNames_); + return ITypesUtil::Marshal(data, input.bundleName_, input.hapName_, input.storeName_, input.area_, input.level_, + input.type_, input.isEncrypt_, input.password_, input.customDir_, input.isAutoClean_, input.isSearchable_, + input.haMode_, input.infos_, input.tokenIds_, input.uids_, input.user_, input.permissionNames_); } template<> bool Unmarshalling(SyncerParam &output, MessageParcel &data) @@ -162,14 +161,14 @@ bool Unmarshalling(Statistic &output, MessageParcel &data) template<> bool Marshalling(const PrimaryKeys &input, MessageParcel &data) { - return Marshal(data, input[Observer::CHG_TYPE_INSERT], input[Observer::CHG_TYPE_UPDATE], - input[Observer::CHG_TYPE_DELETE]); + return Marshal( + data, input[Observer::CHG_TYPE_INSERT], input[Observer::CHG_TYPE_UPDATE], input[Observer::CHG_TYPE_DELETE]); } template<> bool Unmarshalling(PrimaryKeys &output, MessageParcel &data) { - return Unmarshal(data, output[Observer::CHG_TYPE_INSERT], output[Observer::CHG_TYPE_UPDATE], - output[Observer::CHG_TYPE_DELETE]); + return Unmarshal( + data, output[Observer::CHG_TYPE_INSERT], output[Observer::CHG_TYPE_UPDATE], output[Observer::CHG_TYPE_DELETE]); } template<> @@ -217,13 +216,13 @@ bool Unmarshalling(Reference &output, MessageParcel &data) } template<> -bool Marshalling(const BigInt& input, MessageParcel& data) +bool Marshalling(const BigInt &input, MessageParcel &data) { return Marshal(data, input.Sign(), input.Value()); } template<> -bool Unmarshalling(BigInt& output, MessageParcel& data) +bool Unmarshalling(BigInt &output, MessageParcel &data) { int32_t sign = 0; std::vector value; @@ -243,4 +242,4 @@ bool Unmarshalling(DebugInfo &output, MessageParcel &data) { return Unmarshal(data, output.inode_, output.mode_, output.uid_, output.gid_); } -} \ No newline at end of file +} // namespace OHOS::ITypesUtil \ No newline at end of file diff --git a/relational_store/frameworks/native/rdb/src/security_policy.cpp b/relational_store/frameworks/native/rdb/src/security_policy.cpp index 783494e7..71cb60fb 100644 --- a/relational_store/frameworks/native/rdb/src/security_policy.cpp +++ b/relational_store/frameworks/native/rdb/src/security_policy.cpp @@ -18,6 +18,7 @@ #include "logger.h" #include "rdb_errno.h" #include "security_label.h" +#include "sqlite_utils.h" namespace OHOS { namespace NativeRdb { @@ -47,12 +48,16 @@ int SecurityPolicy::SetSecurityLabel(const RdbStoreConfig &config) { if (config.GetStorageMode() != StorageMode::MODE_MEMORY && config.GetSecurityLevel() != SecurityLevel::LAST) { auto toSetLevel = GetSecurityLevelValue(config.GetSecurityLevel()); - auto errCode = FileManagement::ModuleSecurityLabel::SecurityLabel::SetSecurityLabel(config.GetPath(), - toSetLevel) ? E_OK : E_CONFIG_INVALID_CHANGE; + auto errCode = + FileManagement::ModuleSecurityLabel::SecurityLabel::SetSecurityLabel(config.GetPath(), toSetLevel) + ? E_OK + : E_CONFIG_INVALID_CHANGE; if (errCode != E_OK) { auto currentLevel = GetFileSecurityLevel(config.GetPath()); - LOG_ERROR("Set security level from %{public}s to %{public}s, result:%{public}d, errno:%{public}d.", - currentLevel.c_str(), toSetLevel.c_str(), errCode, errno); + LOG_ERROR("storeName:%{public}s SetSecurityLabel failed. Set security level from %{public}s to %{public}s," + "result:%{public}d, errno:%{public}d.", + SqliteUtils::Anonymous(config.GetName()).c_str(), currentLevel.c_str(), toSetLevel.c_str(), errCode, + errno); } return errCode; } diff --git a/relational_store/frameworks/native/rdb/src/share_block.cpp b/relational_store/frameworks/native/rdb/src/share_block.cpp index 2d466aad..f4f4d122 100644 --- a/relational_store/frameworks/native/rdb/src/share_block.cpp +++ b/relational_store/frameworks/native/rdb/src/share_block.cpp @@ -99,10 +99,9 @@ int SharedBlockSetColumnNum(AppDataFwk::SharedBlock *sharedBlock, int columnNum) int FillSharedBlockOpt(SharedBlockInfo *info, sqlite3_stmt *stmt) { SharedBlockSerializerInfo serializer(info->sharedBlock, stmt, info->columnNum, info->startPos); - Sqlite3SharedBlockMethods sqliteBlock = { 1, &serializer, info->isCountAllRows, info->startPos, - info->requiredPos, SeriAddRow, SeriReset, SeriFinish, SeriPutString, SeriPutLong, SeriPutDouble, SeriPutBlob, - SeriPutNull, SeriPutOther - }; + Sqlite3SharedBlockMethods sqliteBlock = { 1, &serializer, info->isCountAllRows, info->startPos, info->requiredPos, + SeriAddRow, SeriReset, SeriFinish, SeriPutString, SeriPutLong, SeriPutDouble, SeriPutBlob, SeriPutNull, + SeriPutOther }; auto db = sqlite3_db_handle(stmt); int err = sqlite3_db_config(db, SQLITE_DBCONFIG_SET_SHAREDBLOCK, stmt, &sqliteBlock); if (err != SQLITE_OK) { @@ -181,8 +180,7 @@ void FillRow(SharedBlockInfo *info, sqlite3_stmt *stmt) info->sharedBlock->SetColumnNum(info->columnNum); info->startPos += info->addedRows; info->addedRows = 0; - fillOneRowResult = - FillOneRow(info->sharedBlock, stmt, info->columnNum, info->startPos, info->addedRows); + fillOneRowResult = FillOneRow(info->sharedBlock, stmt, info->columnNum, info->startPos, info->addedRows); } if (fillOneRowResult == FILL_ONE_ROW_SUCESS) { @@ -194,8 +192,8 @@ void FillRow(SharedBlockInfo *info, sqlite3_stmt *stmt) } } -FillOneRowResult FillOneRow(AppDataFwk::SharedBlock *sharedBlock, sqlite3_stmt *statement, int numColumns, - int startPos, int addedRows) +FillOneRowResult FillOneRow( + AppDataFwk::SharedBlock *sharedBlock, sqlite3_stmt *statement, int numColumns, int startPos, int addedRows) { int status = sharedBlock->AllocRow(); if (status != AppDataFwk::SharedBlock::SHARED_BLOCK_OK) { @@ -241,9 +239,8 @@ FillOneRowResult FillOneRow(AppDataFwk::SharedBlock *sharedBlock, sqlite3_stmt * return result; } - -FillOneRowResult FillOneRowOfString(AppDataFwk::SharedBlock *sharedBlock, sqlite3_stmt *statement, int startPos, - int addedRows, int pos) +FillOneRowResult FillOneRowOfString( + AppDataFwk::SharedBlock *sharedBlock, sqlite3_stmt *statement, int startPos, int addedRows, int pos) { const char *text = reinterpret_cast(sqlite3_column_text(statement, pos)); if (text == nullptr) { @@ -262,8 +259,8 @@ FillOneRowResult FillOneRowOfString(AppDataFwk::SharedBlock *sharedBlock, sqlite return FILL_ONE_ROW_SUCESS; } -FillOneRowResult FillOneRowOfLong(AppDataFwk::SharedBlock *sharedBlock, sqlite3_stmt *statement, int startPos, - int addedRows, int pos) +FillOneRowResult FillOneRowOfLong( + AppDataFwk::SharedBlock *sharedBlock, sqlite3_stmt *statement, int startPos, int addedRows, int pos) { int64_t value = sqlite3_column_int64(statement, pos); int status = sharedBlock->PutLong(addedRows, pos, value); @@ -275,8 +272,8 @@ FillOneRowResult FillOneRowOfLong(AppDataFwk::SharedBlock *sharedBlock, sqlite3_ return FILL_ONE_ROW_SUCESS; } -FillOneRowResult FillOneRowOfFloat(AppDataFwk::SharedBlock *sharedBlock, sqlite3_stmt *statement, int startPos, - int addedRows, int pos) +FillOneRowResult FillOneRowOfFloat( + AppDataFwk::SharedBlock *sharedBlock, sqlite3_stmt *statement, int startPos, int addedRows, int pos) { double value = sqlite3_column_double(statement, pos); int status = sharedBlock->PutDouble(addedRows, pos, value); @@ -288,8 +285,8 @@ FillOneRowResult FillOneRowOfFloat(AppDataFwk::SharedBlock *sharedBlock, sqlite3 return FILL_ONE_ROW_SUCESS; } -FillOneRowResult FillOneRowOfBlob(AppDataFwk::SharedBlock *sharedBlock, sqlite3_stmt *statement, int startPos, - int addedRows, int pos) +FillOneRowResult FillOneRowOfBlob( + AppDataFwk::SharedBlock *sharedBlock, sqlite3_stmt *statement, int startPos, int addedRows, int pos) { auto action = &AppDataFwk::SharedBlock::PutBlob; auto *declType = sqlite3_column_decltype(statement, pos); @@ -315,8 +312,8 @@ FillOneRowResult FillOneRowOfBlob(AppDataFwk::SharedBlock *sharedBlock, sqlite3_ return FILL_ONE_ROW_SUCESS; } -FillOneRowResult FillOneRowOfNull(AppDataFwk::SharedBlock *sharedBlock, sqlite3_stmt *statement, int startPos, - int addedRows, int pos) +FillOneRowResult FillOneRowOfNull( + AppDataFwk::SharedBlock *sharedBlock, sqlite3_stmt *statement, int startPos, int addedRows, int pos) { int status = sharedBlock->PutNull(addedRows, pos); if (status != AppDataFwk::SharedBlock::SHARED_BLOCK_OK) { diff --git a/relational_store/frameworks/native/rdb/src/shared_block_serializer_info.cpp b/relational_store/frameworks/native/rdb/src/shared_block_serializer_info.cpp index b4b64539..19af4942 100644 --- a/relational_store/frameworks/native/rdb/src/shared_block_serializer_info.cpp +++ b/relational_store/frameworks/native/rdb/src/shared_block_serializer_info.cpp @@ -22,8 +22,8 @@ namespace OHOS { namespace NativeRdb { using namespace OHOS::Rdb; -SharedBlockSerializerInfo::SharedBlockSerializerInfo(AppDataFwk::SharedBlock *sharedBlock, sqlite3_stmt *stat, - int numColumns, int startPos) +SharedBlockSerializerInfo::SharedBlockSerializerInfo( + AppDataFwk::SharedBlock *sharedBlock, sqlite3_stmt *stat, int numColumns, int startPos) : sharedBlock_(sharedBlock), statement_(stat), anumColumns(numColumns), atotalRows(0), astartPos(startPos), raddedRows(0) { diff --git a/relational_store/frameworks/native/rdb/src/sqlite_connection.cpp b/relational_store/frameworks/native/rdb/src/sqlite_connection.cpp index dbf7f28c..a5455c66 100644 --- a/relational_store/frameworks/native/rdb/src/sqlite_connection.cpp +++ b/relational_store/frameworks/native/rdb/src/sqlite_connection.cpp @@ -16,12 +16,13 @@ #define LOG_TAG "SqliteConnection" #include "sqlite_connection.h" +#include +#include + #include #include -#include #include #include -#include #include "sqlite3.h" #include "value_object.h" @@ -35,6 +36,7 @@ #include "logger.h" #include "raw_data_parser.h" #include "rdb_errno.h" +#include "rdb_fault_hiview_reporter.h" #include "rdb_security_manager.h" #include "rdb_sql_statistic.h" #include "rdb_store_config.h" @@ -42,10 +44,9 @@ #include "sqlite_errno.h" #include "sqlite_global_config.h" #include "sqlite_utils.h" -#include "rdb_fault_hiview_reporter.h" #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) -#include "relational/relational_store_sqlite_ext.h" #include "rdb_manager_impl.h" +#include "relational/relational_store_sqlite_ext.h" #endif #include "task_executor.h" @@ -55,7 +56,7 @@ using namespace OHOS::Rdb; using namespace std::chrono; using RdbKeyFile = RdbSecurityManager::KeyFileType; using Reportor = RdbFaultHiViewReporter; -constexpr const char *INTEGRITIES[] = {nullptr, "PRAGMA quick_check", "PRAGMA integrity_check"}; +constexpr const char *INTEGRITIES[] = { nullptr, "PRAGMA quick_check", "PRAGMA integrity_check" }; constexpr SqliteConnection::Suffix SqliteConnection::FILE_SUFFIXES[]; constexpr const char *SqliteConnection::MERGE_ASSETS_FUNC; constexpr const char *SqliteConnection::MERGE_ASSET_FUNC; @@ -67,6 +68,7 @@ constexpr ssize_t SqliteConnection::SLAVE_INTEGRITY_CHECK_LIMIT; constexpr uint32_t SqliteConnection::NO_ITER; constexpr uint32_t SqliteConnection::DB_INDEX; constexpr uint32_t SqliteConnection::WAL_INDEX; +constexpr uint32_t SqliteConnection::ITER_V1; __attribute__((used)) const int32_t SqliteConnection::regCreator_ = Connection::RegisterCreator(DB_SQLITE, SqliteConnection::Create); __attribute__((used)) @@ -75,6 +77,8 @@ __attribute__((used)) const int32_t SqliteConnection::regDeleter_ = Connection::RegisterDeleter(DB_SQLITE, SqliteConnection::Delete); __attribute__((used)) const int32_t SqliteConnection::regCollector_ = Connection::RegisterCollector(DB_SQLITE, SqliteConnection::Collect); +__attribute__((used)) +const int32_t SqliteConnection::regRestorer_ = Connection::RegisterRestorer(DB_SQLITE, SqliteConnection::Restore); std::pair> SqliteConnection::Create(const RdbStoreConfig &config, bool isWrite) { @@ -153,7 +157,7 @@ std::pair> SqliteConnection::CreateSl bool isSlaveLockExist = SqliteUtils::IsSlaveInterrupted(config_.GetPath()); bool hasFailure = SqliteUtils::IsSlaveInvalid(config_.GetPath()); bool walOverLimit = bugInfo.find(FILE_SUFFIXES[WAL_INDEX].debug_) != bugInfo.end() && - bugInfo[FILE_SUFFIXES[WAL_INDEX].debug_].size_ > SLAVE_WAL_SIZE_LIMIT; + bugInfo[FILE_SUFFIXES[WAL_INDEX].debug_].size_ > SLAVE_WAL_SIZE_LIMIT; LOG_INFO("slave cfg:[%{public}d,%{public}d,%{public}d,%{public}d,%{public}d,%{public}d,%{public}d]%{public}s " "%{public}s,[%{public}d,%{public}d,%{public}d,%{public}d]", config.GetDBType(), config.GetHaMode(), config.IsEncrypt(), config.GetArea(), config.GetSecurityLevel(), @@ -165,6 +169,7 @@ std::pair> SqliteConnection::CreateSl (!isSlaveExist || isSlaveLockExist || hasFailure || walOverLimit))) { if (walOverLimit) { SqliteUtils::SetSlaveInvalid(config_.GetPath()); + Reportor::Report(Reportor::Create(config, E_SQLITE_ERROR, "ErrorType: slaveWalOverLimit")); } return result; } @@ -186,8 +191,8 @@ std::pair> SqliteConnection::CreateSl return result; } } else { - LOG_WARN("open slave failed:%{public}d, %{public}s", errCode, - SqliteUtils::Anonymous(config.GetPath()).c_str()); + LOG_WARN( + "open slave failed:%{public}d, %{public}s", errCode, SqliteUtils::Anonymous(config.GetPath()).c_str()); return result; } } @@ -244,7 +249,7 @@ int SqliteConnection::InnerOpen(const RdbStoreConfig &config) #endif isReadOnly_ = !isWriter_ || config.IsReadOnly(); int openFileFlags = config.IsReadOnly() ? (SQLITE_OPEN_READONLY | SQLITE_OPEN_FULLMUTEX) - : (SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX); + : (SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX); errCode = OpenDatabase(dbPath, openFileFlags); if (errCode != E_OK) { return errCode; @@ -258,7 +263,6 @@ int SqliteConnection::InnerOpen(const RdbStoreConfig &config) } if (isWriter_) { - TryCheckPoint(true); ValueObject checkResult{"ok"}; auto index = static_cast(config.GetIntegrityCheck()); if (index < static_cast(sizeof(INTEGRITIES) / sizeof(INTEGRITIES[0]))) { @@ -269,8 +273,8 @@ int SqliteConnection::InnerOpen(const RdbStoreConfig &config) } if (errCode == E_OK && static_cast(checkResult) != "ok") { LOG_ERROR("%{public}s integrity check result is %{public}s, sql:%{public}s", - SqliteUtils::Anonymous(config.GetName()).c_str(), - static_cast(checkResult).c_str(), sql); + SqliteUtils::Anonymous(config.GetName()).c_str(), static_cast(checkResult).c_str(), + sql); Reportor::ReportFault(Reportor::Create(config, errCode, static_cast(checkResult))); } } @@ -456,7 +460,8 @@ std::pair> SqliteConnection::CreateStatement( slaveStmt->config_ = &slaveConnection_->config_; errCode = slaveStmt->Prepare(slaveConnection_->dbHandle_, sql); if (errCode != E_OK) { - LOG_WARN("prepare slave stmt failed:%{public}d, sql:%{public}s", errCode, sql.c_str()); + LOG_WARN( + "prepare slave stmt failed:%{public}d, sql:%{public}s", errCode, SqliteUtils::AnonySql(sql).c_str()); SqliteUtils::SetSlaveInvalid(config_.GetPath()); return { E_OK, statement }; } @@ -595,8 +600,8 @@ int SqliteConnection::ReSetKey(const RdbStoreConfig &config) if (!IsWriter()) { return E_OK; } - LOG_INFO("name = %{public}s, iter = %{public}d", SqliteUtils::Anonymous(config.GetName()).c_str(), - config.GetIter()); + LOG_INFO( + "name = %{public}s, iter = %{public}d", SqliteUtils::Anonymous(config.GetName()).c_str(), config.GetIter()); std::vector newKey = config.GetNewEncryptKey(); int errCode = sqlite3_rekey(dbHandle_, static_cast(newKey.data()), static_cast(newKey.size())); newKey.assign(newKey.size(), 0); @@ -846,8 +851,8 @@ int SqliteConnection::ExecuteSql(const std::string &sql, const std::vectorExecute(bindArgs); } -std::pair SqliteConnection::ExecuteForValue(const std::string &sql, - const std::vector &bindArgs) +std::pair SqliteConnection::ExecuteForValue( + const std::string &sql, const std::vector &bindArgs) { auto [errCode, statement] = CreateStatement(sql, nullptr); if (statement == nullptr || errCode != E_OK) { @@ -858,7 +863,7 @@ std::pair SqliteConnection::ExecuteForValue(const std::str std::tie(errCode, object) = statement->ExecuteForValue(bindArgs); if (errCode != E_OK) { LOG_ERROR("execute sql failed, errCode:%{public}d, sql:%{public}s, args size:%{public}zu", - SQLiteError::ErrNo(errCode), sql.c_str(), bindArgs.size()); + SQLiteError::ErrNo(errCode), SqliteUtils::AnonySql(sql).c_str(), bindArgs.size()); } return { errCode, object }; } @@ -942,8 +947,8 @@ int SqliteConnection::ConfigLocale(const std::string &localeStr) return E_ERROR; } - int err = sqlite3_create_collation_v2(dbHandle_, "LOCALES", SQLITE_UTF8, collator, Collate8Compare, - (void (*)(void *))LocalizedCollatorDestroy); + int err = sqlite3_create_collation_v2( + dbHandle_, "LOCALES", SQLITE_UTF8, collator, Collate8Compare, (void (*)(void *))LocalizedCollatorDestroy); if (err != SQLITE_OK) { LOG_ERROR("SCreate collator in sqlite3 failed."); return err; @@ -983,15 +988,17 @@ int SqliteConnection::TryCheckPoint(bool timeout) return E_ERROR; } - if (size <= GlobalExpr::DB_WAL_SIZE_LIMIT_MIN) { + if (size <= config_.GetStartCheckpointSize()) { return E_OK; } - if (!timeout && size < GlobalExpr::DB_WAL_WARNING_SIZE) { + if (!timeout && size < config_.GetCheckpointSize()) { return E_INNER_WARNING; } + (void)sqlite3_busy_timeout(dbHandle_, CHECKPOINT_TIME); int errCode = sqlite3_wal_checkpoint_v2(dbHandle_, nullptr, SQLITE_CHECKPOINT_TRUNCATE, nullptr, nullptr); + (void)sqlite3_busy_timeout(dbHandle_, DEFAULT_BUSY_TIMEOUT_MS); if (errCode != SQLITE_OK) { LOG_WARN("sqlite3_wal_checkpoint_v2 failed err:%{public}d,size:%{public}zd,wal:%{public}s.", errCode, size, SqliteUtils::Anonymous(walName).c_str()); @@ -1008,7 +1015,7 @@ int SqliteConnection::LimitWalSize() std::string walName = sqlite3_filename_wal(sqlite3_db_filename(dbHandle_, "main")); ssize_t fileSize = SqliteUtils::GetFileSize(walName); - if (fileSize < 0 || fileSize > GlobalExpr::DB_WAL_SIZE_LIMIT_MAX) { + if (fileSize < 0 || fileSize > config_.GetWalLimitSize()) { LOG_ERROR("The WAL file size exceeds the limit, %{public}s size is %{public}zd", SqliteUtils::Anonymous(walName).c_str(), fileSize); return E_WAL_SIZE_OVER_LIMIT; @@ -1076,8 +1083,8 @@ void SqliteConnection::MergeAsset(sqlite3_context *ctx, int argc, sqlite3_value sqlite3_result_blob(ctx, blob.data(), blob.size(), SQLITE_TRANSIENT); } -void SqliteConnection::CompAssets(std::map &assets, - std::map &newAssets) +void SqliteConnection::CompAssets( + std::map &assets, std::map &newAssets) { auto oldIt = assets.begin(); auto newIt = newAssets.begin(); @@ -1173,8 +1180,8 @@ int32_t SqliteConnection::Unsubscribe(const std::string &event, const std::share return UnsubscribeLocalDetailAll(event); } -int32_t SqliteConnection::UnsubscribeLocalDetail(const std::string &event, - const std::shared_ptr &observer) +int32_t SqliteConnection::UnsubscribeLocalDetail( + const std::string &event, const std::shared_ptr &observer) { std::lock_guard lock(mutex_); auto observers = observers_.find(event); @@ -1230,8 +1237,8 @@ int32_t SqliteConnection::Backup(const std::string &databasePath, const std::vec LOG_INFO("backing up, return:%{public}s", config_.GetName().c_str()); return E_OK; } - LOG_INFO("begin backup to slave:%{public}s, isAsync:%{public}d", - SqliteUtils::Anonymous(databasePath).c_str(), isAsync); + LOG_INFO( + "begin backup to slave:%{public}s, isAsync:%{public}d", SqliteUtils::Anonymous(databasePath).c_str(), isAsync); if (!isAsync) { if (slaveConnection_ == nullptr) { RdbStoreConfig rdbSlaveStoreConfig = GetSlaveRdbStoreConfig(config_); @@ -1265,8 +1272,8 @@ int32_t SqliteConnection::Backup(const std::string &databasePath, const std::vec return E_OK; } -int32_t SqliteConnection::Restore(const std::string &databasePath, const std::vector &destEncryptKey, - SlaveStatus &slaveStatus) +int32_t SqliteConnection::Restore( + const std::string &databasePath, const std::vector &destEncryptKey, SlaveStatus &slaveStatus) { return ExchangeSlaverToMaster(true, true, slaveStatus); }; @@ -1280,8 +1287,8 @@ int SqliteConnection::LoadExtension(const RdbStoreConfig &config, sqlite3 *dbHan LOG_ERROR("failed, size %{public}zu is too large", config.GetPluginLibs().size()); return E_INVALID_ARGS; } - int err = sqlite3_db_config(dbHandle, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SqliteUtils::ENABLE_LOAD_EXTENSION, - nullptr); + int err = sqlite3_db_config( + dbHandle, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SqliteUtils::ENABLE_LOAD_EXTENSION, nullptr); if (err != SQLITE_OK) { LOG_ERROR("enable failed, err=%{public}d, errno=%{public}d", err, errno); return SQLiteError::ErrNo(err); @@ -1301,8 +1308,8 @@ int SqliteConnection::LoadExtension(const RdbStoreConfig &config, sqlite3 *dbHan break; } } - int ret = sqlite3_db_config(dbHandle, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SqliteUtils::DISABLE_LOAD_EXTENSION, - nullptr); + int ret = sqlite3_db_config( + dbHandle, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SqliteUtils::DISABLE_LOAD_EXTENSION, nullptr); if (ret != SQLITE_OK) { LOG_ERROR("disable failed, err=%{public}d, errno=%{public}d", err, errno); } @@ -1389,6 +1396,7 @@ int SqliteConnection::SqliteNativeBackup(bool isRestore, SlaveStatus &curStatus) (void)SqliteConnection::Delete(slaveConfig.GetPath()); } curStatus = SlaveStatus::BACKUP_INTERRUPT; + Reportor::Report(Reportor::Create(slaveConfig, SQLiteError::ErrNo(rc), "ErrorType: slaveBackupInterrupt")); } return rc == E_CANCEL ? E_CANCEL : SQLiteError::ErrNo(rc); } @@ -1446,6 +1454,9 @@ ExchangeStrategy SqliteConnection::GenerateExchangeStrategy(const SlaveStatus &s int32_t SqliteConnection::Repair(const RdbStoreConfig &config) { + if (config.GetHaMode() == HAMode::MANUAL_TRIGGER) { + return SqliteConnection::Restore(config, SqliteUtils::GetSlavePath(config.GetPath()), config.GetPath()); + } std::shared_ptr connection = std::make_shared(config, true); if (connection == nullptr) { return E_ERROR; @@ -1469,6 +1480,7 @@ int32_t SqliteConnection::Repair(const RdbStoreConfig &config) LOG_ERROR("reopen db failed, err:%{public}d", ret); return ret; } + connection->TryCheckPoint(true); SlaveStatus curStatus; ret = connection->ExchangeSlaverToMaster(true, false, curStatus); if (ret != E_OK) { @@ -1513,8 +1525,8 @@ int SqliteConnection::ExchangeVerify(bool isRestore) return E_OK; } -std::pair> SqliteConnection::InnerCreate(const RdbStoreConfig &config, - bool isWrite) +std::pair> SqliteConnection::InnerCreate( + const RdbStoreConfig &config, bool isWrite) { std::pair> result = { E_ERROR, nullptr }; auto &[errCode, conn] = result; @@ -1570,15 +1582,15 @@ int SqliteConnection::VeritySlaveIntegrity() } } bool isSlaveDbOverLimit = bugInfo.find(FILE_SUFFIXES[DB_INDEX].debug_) != bugInfo.end() && - bugInfo[FILE_SUFFIXES[DB_INDEX].debug_].size_ > SLAVE_INTEGRITY_CHECK_LIMIT; + bugInfo[FILE_SUFFIXES[DB_INDEX].debug_].size_ > SLAVE_INTEGRITY_CHECK_LIMIT; if (isSlaveDbOverLimit && mCount == 0L) { return SqliteUtils::IsSlaveInvalid(config_.GetPath()) ? E_SQLITE_CORRUPT : E_OK; } std::tie(err, obj) = slaveConnection_->ExecuteForValue(INTEGRITIES[2]); // 2 is integrity_check if (err == E_OK && (static_cast(obj) != "ok")) { - LOG_ERROR("slave corrupt, ret:%{public}s, cRet:%{public}d, %{public}d", - static_cast(obj).c_str(), err, errno); + LOG_ERROR("slave corrupt, ret:%{public}s, cRet:%{public}d, %{public}d", static_cast(obj).c_str(), + err, errno); SqliteUtils::SetSlaveInvalid(config_.GetPath()); return E_SQLITE_CORRUPT; } @@ -1591,7 +1603,7 @@ bool SqliteConnection::IsDbVersionBelowSlave() return false; } - auto[cRet, cObj] = ExecuteForValue("SELECT COUNT(*) FROM sqlite_master WHERE type='table';"); + auto [cRet, cObj] = ExecuteForValue("SELECT COUNT(*) FROM sqlite_master WHERE type='table';"); auto cVal = std::get_if(&cObj.value); if (cRet == E_SQLITE_CORRUPT || (cVal != nullptr && (static_cast(*cVal) == 0L))) { LOG_INFO("main empty, %{public}d, %{public}s", cRet, config_.GetName().c_str()); @@ -1609,5 +1621,86 @@ bool SqliteConnection::IsDbVersionBelowSlave() } return false; } + +int SqliteConnection::CopyDb(const RdbStoreConfig &config, const std::string &srcPath, const std::string &destPath) +{ + RdbStoreConfig srcConfig(config); + srcConfig.SetPath(srcPath); + srcConfig.SetIntegrityCheck(IntegrityCheck::FULL); + srcConfig.SetHaMode(HAMode::SINGLE); + auto [ret, conn] = Connection::Create(srcConfig, true); + if (ret == E_SQLITE_CORRUPT && srcConfig.IsEncrypt() && srcConfig.GetIter() != ITER_V1) { + srcConfig.SetIter(ITER_V1); + std::tie(ret, conn) = Connection::Create(srcConfig, true); + } + if (ret != E_OK) { + LOG_ERROR("backup file is corrupted, %{public}s", SqliteUtils::Anonymous(srcPath).c_str()); + return E_SQLITE_CORRUPT; + } + conn = nullptr; + SqliteUtils::DeleteFile(srcPath + "-shm"); + SqliteUtils::DeleteFile(srcPath + "-wal"); + Connection::Delete(config); + + if (config.GetPath() != destPath) { + RdbStoreConfig dstConfig(destPath); + Connection::Delete(dstConfig); + } + + if (!SqliteUtils::CopyFile(srcPath, destPath)) { + return E_ERROR; + } + return E_OK; +} + +int32_t SqliteConnection::Restore(const RdbStoreConfig &config, const std::string &srcPath, const std::string &destPath) +{ + if (config.GetHaMode() == HAMode::SINGLE || !SqliteUtils::IsSlaveDbName(srcPath)) { + return SqliteConnection::CopyDb(config, srcPath, destPath); + } + std::shared_ptr connection = std::make_shared(config, true); + if (connection == nullptr) { + return E_ERROR; + } + RdbStoreConfig slaveConfig = connection->GetSlaveRdbStoreConfig(config); + if (access(slaveConfig.GetPath().c_str(), F_OK) != 0) { + return E_NOT_SUPPORT; + } + auto [ret, conn] = connection->CreateSlaveConnection(slaveConfig, SlaveOpenPolicy::FORCE_OPEN); + if (ret != E_OK) { + return ret; + } + connection->slaveConnection_ = conn; + + int openMainRes = connection->InnerOpen(config); + ret = connection->VeritySlaveIntegrity(); + if (ret != E_OK) { + return ret; + } + if (openMainRes == E_OK && SqliteUtils::IsSlaveInvalid(config.GetPath()) && !connection->IsDbVersionBelowSlave()) { + return E_SQLITE_CORRUPT; + } + + ret = SQLiteError::ErrNo(sqlite3_wal_checkpoint_v2(connection->slaveConnection_->dbHandle_, nullptr, + SQLITE_CHECKPOINT_TRUNCATE, nullptr, nullptr)); + if (ret != E_OK) { + LOG_ERROR("chk %{public}d %{public}d %{public}s", ret, errno, SqliteUtils::Anonymous(config.GetName()).c_str()); + return ret; + } + connection->slaveConnection_ = nullptr; + connection = nullptr; + + if (!SqliteUtils::RenameFile(slaveConfig.GetPath(), config.GetPath())) { + LOG_ERROR("rename %{public}d %{public}s", errno, SqliteUtils::Anonymous(config.GetName()).c_str()); + return E_ERROR; + } + for (auto &suffix : FILE_SUFFIXES) { + if (suffix.suffix_ != nullptr && !std::string(suffix.suffix_).empty()) { + SqliteUtils::DeleteFile(config.GetPath() + suffix.suffix_); + } + } + Connection::Delete(slaveConfig.GetPath()); + return E_OK; +} } // namespace NativeRdb } // namespace OHOS \ No newline at end of file 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 c86614cc..7f1a0b49 100644 --- a/relational_store/frameworks/native/rdb/src/sqlite_global_config.cpp +++ b/relational_store/frameworks/native/rdb/src/sqlite_global_config.cpp @@ -17,14 +17,16 @@ #include #include -#include + #include +#include #include #include + #include "logger.h" +#include "rdb_errno.h" #include "sqlite3sym.h" #include "sqlite_utils.h" -#include "rdb_errno.h" namespace OHOS { namespace NativeRdb { @@ -41,8 +43,7 @@ SqliteGlobalConfig::SqliteGlobalConfig() sqlite3_config(SQLITE_CONFIG_MULTITHREAD); - sqlite3_config(SQLITE_CONFIG_LOG, &Log, - GlobalExpr::CALLBACK_LOG_SWITCH ? reinterpret_cast(1) : NULL); + sqlite3_config(SQLITE_CONFIG_LOG, &Log, GlobalExpr::CALLBACK_LOG_SWITCH ? reinterpret_cast(1) : NULL); sqlite3_soft_heap_limit(GlobalExpr::SOFT_HEAP_LIMIT); @@ -61,16 +62,15 @@ void SqliteGlobalConfig::Log(const void *data, int err, const char *msg) if (errType == SQLITE_ERROR && strstr(msg, "\"?\": syntax error in \"PRAGMA user_ve") != nullptr) { return; } - if (errType == 0 || errType == SQLITE_CONSTRAINT || errType == SQLITE_SCHEMA || errType == SQLITE_NOTICE - || err == SQLITE_WARNING_AUTOINDEX) { + if (errType == 0 || errType == SQLITE_CONSTRAINT || errType == SQLITE_SCHEMA || errType == SQLITE_NOTICE || + err == SQLITE_WARNING_AUTOINDEX) { if (verboseLog) { LOG_INFO("Error(%{public}d) %{public}s ", err, SqliteUtils::Anonymous(msg).c_str()); } } else if (errType == SQLITE_WARNING) { LOG_WARN("WARNING(%{public}d) %{public}s ", err, SqliteUtils::Anonymous(msg).c_str()); } else { - LOG_ERROR("Error(%{public}d) errno is:%{public}d %{public}s.", err, errno, - SqliteUtils::Anonymous(msg).c_str()); + LOG_ERROR("Error(%{public}d) errno is:%{public}d %{public}s.", err, errno, SqliteUtils::Anonymous(msg).c_str()); } } 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 057bd442..51ba993b 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 @@ -17,29 +17,29 @@ #include +#include #include #include #include #include -#include #include "logger.h" -#include "rdb_sql_utils.h" #include "rdb_sql_statistic.h" +#include "rdb_sql_utils.h" #include "result_set.h" #include "share_block.h" #include "sqlite_connection.h" +#include "sqlite_errno.h" #include "sqlite_statement.h" #include "sqlite_utils.h" -#include "sqlite_errno.h" namespace OHOS { namespace NativeRdb { using namespace OHOS::Rdb; using namespace std::chrono; constexpr int64_t TIME_OUT = 1500; -SqliteSharedResultSet::SqliteSharedResultSet(Time start, Conn conn, std::string sql, const Values &args, - const std::string &path) +SqliteSharedResultSet::SqliteSharedResultSet( + Time start, Conn conn, std::string sql, const Values &args, const std::string &path) : AbsSharedResultSet(path), conn_(std::move(conn)), qrySql_(std::move(sql)), bindArgs_(args) { if (conn_ == nullptr) { @@ -141,8 +141,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()); + LOG_ERROR( + "fail, result set has been closed, ret %{public}d, sql %{public}s", E_ALREADY_CLOSED, qrySql_.c_str()); return { E_ALREADY_CLOSED, {} }; } @@ -179,15 +179,15 @@ int SqliteSharedResultSet::Close() 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()); + LOG_ERROR( + "fail, result set has been closed, ret %{public}d, sql %{public}s", E_ALREADY_CLOSED, qrySql_.c_str()); return E_ALREADY_CLOSED; } if (GetBlock() == nullptr) { return E_ERROR; } - if ((uint32_t)newPosition < GetBlock()->GetStartPos() || (uint32_t)newPosition >= GetBlock()->GetLastPos() - || oldPosition == rowCount_) { + if ((uint32_t)newPosition < GetBlock()->GetStartPos() || (uint32_t)newPosition >= GetBlock()->GetLastPos() || + oldPosition == rowCount_) { return FillBlock(newPosition); } return E_OK; @@ -215,12 +215,12 @@ int SqliteSharedResultSet::FillBlock(int requiredPos) return errCode; } blockCapacity_ = block->GetRowNum(); - if ((block->GetStartPos() == block->GetLastPos() && (uint32_t)rowCount_ != block->GetStartPos()) - || ((uint32_t)requiredPos < block->GetStartPos() || block->GetLastPos() <= (uint32_t)requiredPos) - || block->GetStartPos() > 0) { + if ((block->GetStartPos() == block->GetLastPos() && (uint32_t)rowCount_ != block->GetStartPos()) || + ((uint32_t)requiredPos < block->GetStartPos() || block->GetLastPos() <= (uint32_t)requiredPos) || + block->GetStartPos() > 0) { LOG_WARN("blockRowNum=%{public}d, requiredPos= %{public}d, startPos_= %{public}" PRIu32 - ", lastPos_= %{public}" PRIu32 ", blockPos_= %{public}" PRIu32 ".", - rowCount_, requiredPos, block->GetStartPos(), block->GetLastPos(), block->GetBlockPos()); + ", lastPos_= %{public}" PRIu32 ", blockPos_= %{public}" PRIu32 ".", + rowCount_, requiredPos, block->GetStartPos(), block->GetLastPos(), block->GetBlockPos()); } return E_OK; } 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 25da02f6..b8cb526b 100644 --- a/relational_store/frameworks/native/rdb/src/sqlite_sql_builder.cpp +++ b/relational_store/frameworks/native/rdb/src/sqlite_sql_builder.cpp @@ -298,8 +298,8 @@ std::string SqliteSqlBuilder::GetSqlArgs(size_t size) return args; } -SqliteSqlBuilder::BatchRefSqls SqliteSqlBuilder::GenerateSqls(const std::string &table, const ValuesBuckets &buckets, - int limit) +SqliteSqlBuilder::BatchRefSqls SqliteSqlBuilder::GenerateSqls( + const std::string &table, const ValuesBuckets &buckets, int limit) { auto [fields, values] = buckets.GetFieldsAndValues(); auto columnSize = fields->size(); @@ -324,8 +324,8 @@ SqliteSqlBuilder::BatchRefSqls SqliteSqlBuilder::GenerateSqls(const std::string return SqliteSqlBuilder::MakeExecuteSqls(sql, args, columnSize, limit); } -SqliteSqlBuilder::BatchRefSqls SqliteSqlBuilder::MakeExecuteSqls(const std::string &sql, - const std::vector &args, int fieldSize, int limit) +SqliteSqlBuilder::BatchRefSqls SqliteSqlBuilder::MakeExecuteSqls( + const std::string &sql, const std::vector &args, int fieldSize, int limit) { if (fieldSize == 0) { return BatchRefSqls(); diff --git a/relational_store/frameworks/native/rdb/src/sqlite_statement.cpp b/relational_store/frameworks/native/rdb/src/sqlite_statement.cpp index bb03940e..2eaa63c4 100644 --- a/relational_store/frameworks/native/rdb/src/sqlite_statement.cpp +++ b/relational_store/frameworks/native/rdb/src/sqlite_statement.cpp @@ -25,6 +25,7 @@ #include "logger.h" #include "raw_data_parser.h" #include "rdb_errno.h" +#include "rdb_fault_hiview_reporter.h" #include "rdb_sql_statistic.h" #include "relational_store_client.h" #include "remote_result_set.h" @@ -34,9 +35,8 @@ #include "sqlite3ext.h" #include "sqlite_connection.h" #include "sqlite_errno.h" -#include "sqlite_utils.h" -#include "rdb_fault_hiview_reporter.h" #include "sqlite_global_config.h" +#include "sqlite_utils.h" namespace OHOS { namespace NativeRdb { @@ -120,7 +120,7 @@ void SqliteStatement::ReadFile2Buffer() if (SqliteGlobalConfig::GetDbPath(*config_, fileName) != E_OK || access(fileName.c_str(), F_OK) != 0) { return; } - uint64_t buffer[BUFFER_LEN] = {0x0}; + uint64_t buffer[BUFFER_LEN] = { 0x0 }; FILE *file = fopen(fileName.c_str(), "r"); if (file == nullptr) { LOG_ERROR( @@ -135,8 +135,8 @@ void SqliteStatement::ReadFile2Buffer() } constexpr int bufferSize = 4; for (uint32_t i = 0; i < BUFFER_LEN; i += bufferSize) { - 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]); + 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); } @@ -145,7 +145,7 @@ int SqliteStatement::BindArgs(const std::vector &bindArgs) { std::vector> refBindArgs; for (auto &object : bindArgs) { - refBindArgs.emplace_back(std::ref(const_cast(object))); + refBindArgs.emplace_back(std::ref(const_cast(object))); } return BindArgs(refBindArgs); } @@ -206,6 +206,8 @@ int SqliteStatement::Prepare(const std::string &sql) if (errCode != E_OK) { LOG_WARN("slave prepare Error:%{public}d", errCode); SqliteUtils::SetSlaveInvalid(config_->GetPath()); + RdbStoreConfig slaveConfig(SqliteUtils::GetSlavePath(config_->GetPath())); + Reportor::ReportFault(Reportor::Create(slaveConfig, errCode, "ErrorType: slavePrepareErr")); } } return E_OK; @@ -247,6 +249,8 @@ int SqliteStatement::Bind(const std::vector &args) if (errCode != E_OK) { LOG_ERROR("slave bind error:%{public}d", errCode); SqliteUtils::SetSlaveInvalid(config_->GetPath()); + RdbStoreConfig slaveConfig(SqliteUtils::GetSlavePath(config_->GetPath())); + Reportor::Report(Reportor::Create(slaveConfig, errCode, "ErrorType: slaveBindErr")); } } return E_OK; @@ -344,7 +348,7 @@ int SqliteStatement::Execute(const std::vector &args) { std::vector> refArgs; for (auto &object : args) { - refArgs.emplace_back(std::ref(const_cast(object))); + refArgs.emplace_back(std::ref(const_cast(object))); } return Execute(refArgs); } @@ -384,9 +388,11 @@ int32_t SqliteStatement::Execute(const std::vectorExecute(args); if (errCode != E_OK) { - LOG_ERROR("slave execute error:%{public}d, sql is %{public}s, errno %{public}d", - errCode, sql_.c_str(), errno); + LOG_ERROR( + "slave execute error:%{public}d, sql is %{public}s, errno %{public}d", errCode, sql_.c_str(), errno); SqliteUtils::SetSlaveInvalid(config_->GetPath()); + RdbStoreConfig slaveConfig(SqliteUtils::GetSlavePath(config_->GetPath())); + Reportor::Report(Reportor::Create(slaveConfig, errCode, "ErrorType: slaveExecErr")); } } return E_OK; @@ -695,8 +701,8 @@ int32_t SqliteStatement::BindBigInt(sqlite3_stmt *stat, int index, const ValueOb return sqlite3_bind_blob(stat, index, static_cast(rawData.data()), rawData.size(), SQLITE_TRANSIENT); } -int SqliteStatement::ModifyLockStatus(const std::string &table, const std::vector> &hashKeys, - bool isLock) +int SqliteStatement::ModifyLockStatus( + const std::string &table, const std::vector> &hashKeys, bool isLock) { ::DistributedDB::DBStatus ret; auto db = sqlite3_db_handle(stmt_); diff --git a/relational_store/frameworks/native/rdb/src/sqlite_utils.cpp b/relational_store/frameworks/native/rdb/src/sqlite_utils.cpp index d9acdf58..87c34586 100644 --- a/relational_store/frameworks/native/rdb/src/sqlite_utils.cpp +++ b/relational_store/frameworks/native/rdb/src/sqlite_utils.cpp @@ -27,10 +27,12 @@ #include #include #include +#include #include "logger.h" #include "rdb_errno.h" #include "rdb_store_config.h" +#include "string_utils.h" namespace OHOS { namespace NativeRdb { using namespace OHOS::Rdb; @@ -42,6 +44,19 @@ constexpr int32_t FILE_PATH_MINI_SIZE = 6; constexpr int32_t AREA_MINI_SIZE = 4; constexpr int32_t AREA_OFFSET_SIZE = 5; constexpr int32_t PRE_OFFSET_SIZE = 1; +constexpr int32_t CREATE_DATABASE_SIZE = 15; +constexpr int32_t SQL_TYPE_SIZE = 3; +constexpr int32_t MIN_ANONYMIZE_LENGTH = 2; +constexpr int32_t MAX_ANONYMIZE_LENGTH = 4; +constexpr int32_t OTHER_SIZE = 6; +constexpr int32_t START_SIZE = 0; +const std::vector SELECT_ARRAY = { "AS", "GROUPBY", "GROUP", "BY", "LIMIT", "COUNT", "AVERAGE", "SELECT", + "FROM", "WHERE", "DISTRICT" }; +const std::vector INSERT_ARRAY = { "INSERT", "INTO", "VALUES" }; +const std::vector UPDATE_ARRAY = { "UPDATE", "SET", "WHERE", "AND", "OR" }; +const std::vector DELETE_ARRAY = { "DELETE", "FROM", "WHERE" }; +const std::vector DROP_ARRAY = { "DROP", "TABLE", "IF", "EXISTS", "DATABASE" }; +const std::vector PRAGMA_ARRAY = { "PRAGMA" }; constexpr SqliteUtils::SqlType SqliteUtils::SQL_TYPE_MAP[]; constexpr const char *SqliteUtils::ON_CONFLICT_CLAUSE[]; @@ -123,8 +138,8 @@ bool SqliteUtils::DeleteFile(const std::string &filePath) } auto ret = remove(filePath.c_str()); if (ret != 0) { - LOG_WARN("remove file failed errno %{public}d ret %{public}d %{public}s", errno, ret, - Anonymous(filePath).c_str()); + LOG_WARN( + "remove file failed errno %{public}d ret %{public}d %{public}s", errno, ret, Anonymous(filePath).c_str()); return false; } return true; @@ -237,6 +252,261 @@ std::string SqliteUtils::Anonymous(const std::string &srcFile) return srcFile.substr(0, pre + PRE_OFFSET_SIZE) + "***" + path + fileName; } +bool IsSpecialChar(char c) +{ + return (c == ' ' || c == '.' || c == ',' || c == '!' || c == '?' || c == ':' || c == '(' || c == ')' || c == ';'); +} + +std::vector SplitString(const std::string &input) +{ + std::vector result; + std::string word; + for (char c : input) { + if (!IsSpecialChar(c)) { + word += c; + } else { + if (!word.empty()) { + result.push_back(word); + word.clear(); + } + result.push_back(std::string(1, c)); + } + } + if (!word.empty()) { + result.push_back(word); + } + return result; +} + +std::string ReplaceMultipleSpaces(const std::string &str) +{ + std::string result = str; + if (result.empty()) { + return result; + } + + result.erase(0, result.find_first_not_of(" ")); + result.erase(result.find_last_not_of(" ") + 1); + return std::regex_replace(result, std::regex(" +"), " "); +} + +std::string AnonyWord(const std::string &word) +{ + std::string anonyWord = word; + if (word.size() == 1 && std::isdigit(word[0])) { + anonyWord[0] = '*'; + } else if (word.size() >= MIN_ANONYMIZE_LENGTH && word.size() <= MAX_ANONYMIZE_LENGTH) { + anonyWord[0] = '*'; + } else { + int length = anonyWord.length() - 3; + for (int i = 0; i < length; i++) { + anonyWord[i] = '*'; + } + } + return anonyWord; +} + +std::string AnonyString(const std::string &input) +{ + std::vector words = SplitString(input); + std::string result; + for (const std::string &word : words) { + std::string anonyWord = AnonyWord(word); + result += anonyWord; + } + return result; +} + +std::string AnonySqlString(const std::string &input, const std::vector &array) +{ + std::vector words = SplitString(input); + std::string result; + for (const std::string &word : words) { + std::string anonyWord = word; + std::string upperWord = SqliteUtils::StrToUpper(word); + if (std::find(array.begin(), array.end(), upperWord) == array.end()) { + anonyWord = AnonyWord(anonyWord); + } + result += anonyWord; + } + return result; +} + +std::string AnonyCreateTable(std::string &str) +{ + size_t lastSpacePos; + if (!str.empty() && str.back() == ' ') { + str = str.substr(0, str.length() - 1); + } + lastSpacePos = str.find_last_of(' '); + if (lastSpacePos != std::string::npos) { + str.replace(lastSpacePos + 1, str.length() - lastSpacePos, + AnonyString(str.substr(lastSpacePos + 1, str.length() - lastSpacePos))); + } + return str; +} + +std::string AnonyCreateColumn(std::string &str) +{ + std::vector tokens; + std::string delimiter = ","; + size_t pos = 0; + + while ((pos = str.find(delimiter)) != std::string::npos) { + std::string token = str.substr(0, pos); + tokens.push_back(token); + str.erase(0, pos + delimiter.length()); + } + tokens.push_back(str); + std::string result; + for (const auto &token : tokens) { + std::string repToken = ReplaceMultipleSpaces(token); + size_t spacePos = repToken.find(' '); + if (spacePos != std::string::npos) { + std::string replacedToken = AnonyString(repToken.substr(0, spacePos)) + repToken.substr(spacePos); + if (!result.empty()) { + result += ", "; + } + result += replacedToken; + } + } + return result; +} + +std::string MaskedCreateSql(const std::string &sql) +{ + auto pre = sql.find("("); + auto end = sql.rfind(")"); + auto table = sql.substr(0, pre); + auto column = sql.substr(pre, end - pre); + table = AnonyCreateTable(table); + column = AnonyCreateColumn(column); + return table + " " + column + ")"; +} + +std::string AnonyAlterDrop(const std::smatch &match, const std::string &sql) +{ + std::string columns = match[1].str(); + std::string table = match[2].str(); + std::string maskedSql = std::regex_replace(sql, + std::regex("ALTER\\s+TABLE\\s+(.*)\\s+DROP COLUMN\\s+([^\\s;]+)", std::regex_constants::icase), + "ALTER TABLE " + AnonyString(columns) + " DROP COLUMN " + AnonyString(table)); + return maskedSql; +} + +std::string AnonyAlterAdd(const std::smatch &match, const std::string &sql) +{ + std::string columns = match[1].str(); + std::string table = match[2].str(); + std::string maskedSql = std::regex_replace(sql, + std::regex("ALTER\\s+TABLE\\s+(.*)\\s+ADD COLUMN\\s+([^\\s;]+)", std::regex_constants::icase), + "ALTER TABLE " + AnonyString(columns) + " ADD COLUMN " + AnonyString(table)); + return maskedSql; +} + +std::string AnonySelectSql(const std::string &sql, const std::string &array) +{ + return AnonySqlString(sql, SELECT_ARRAY); +} + +std::string AnonyInsertSql(const std::string &sql, const std::string &array) +{ + return AnonySqlString(sql, INSERT_ARRAY); +} + +std::string AnonyUpdateSql(const std::string &sql, const std::string &array) +{ + return AnonySqlString(sql, UPDATE_ARRAY); +} + +std::string AnonyDeleteSql(const std::string &sql, const std::string &array) +{ + return AnonySqlString(sql, DELETE_ARRAY); +} + +std::string AnonyCreateSql(const std::string &replaceSql) +{ + std::regex createDatabaseRegex("CREATE\\s+DATABASE\\s+([^\\s;]+)", std::regex_constants::icase); + std::regex createTableRegex("CREATE\\s+TABLE\\s+([^\\s;]+)", std::regex_constants::icase); + std::smatch match; + if (std::regex_search(replaceSql, match, createDatabaseRegex)) { + std::string maskedSql = + replaceSql.substr(START_SIZE, CREATE_DATABASE_SIZE) + AnonyString(replaceSql.substr(CREATE_DATABASE_SIZE)); + return maskedSql; + } else if (std::regex_search(replaceSql, match, createTableRegex)) { + std::string maskedSql = MaskedCreateSql(replaceSql); + return maskedSql; + } + return replaceSql; +} + +std::string AnonyDropSql(const std::string &sql, const std::string &array) +{ + return AnonySqlString(sql, DROP_ARRAY); +} + +std::string AnonyPragmaSql(const std::string &sql, const std::string &array) +{ + return AnonySqlString(sql, PRAGMA_ARRAY); +} + +std::string AnonyAlterSql(const std::string &replaceSql) +{ + std::regex alterDropRegex("ALTER\\s+TABLE\\s+(.*)\\s+DROP COLUMN\\s+([^\\s;]+)", std::regex_constants::icase); + std::regex alterAddRegex("ALTER\\s+TABLE\\s+(.*)\\s+ADD COLUMN\\s+([^\\s;]+)", std::regex_constants::icase); + std::smatch match; + if (std::regex_search(replaceSql, match, alterDropRegex)) { + return AnonyAlterDrop(match, replaceSql); + } else if (std::regex_search(replaceSql, match, alterAddRegex)) { + return AnonyAlterAdd(match, replaceSql); + } + return replaceSql; +} + + +std::string SqliteUtils::AnonySql(const std::string &sql) +{ + std::string replaceSql = ReplaceMultipleSpaces(sql); + std::string sqlType; + if (replaceSql.size() > SQL_TYPE_SIZE) { + sqlType = StrToUpper(replaceSql.substr(START_SIZE, SQL_TYPE_SIZE)); + } else { + return replaceSql; + } + std::smatch match; + if (sqlType == "SEL") { + return AnonySqlString(replaceSql, SELECT_ARRAY); + } + if (sqlType == "INS") { + return AnonySqlString(replaceSql, INSERT_ARRAY); + } + if (sqlType == "UPD") { + return AnonySqlString(replaceSql, UPDATE_ARRAY); + } + if (sqlType == "DEL") { + return AnonySqlString(replaceSql, DELETE_ARRAY); + } + if (sqlType == "CRE") { + return AnonyCreateSql(replaceSql); + } + if (sqlType == "DRO") { + return AnonySqlString(replaceSql, DROP_ARRAY); + } + if (sqlType == "PRA") { + return AnonySqlString(replaceSql, PRAGMA_ARRAY); + } + if (sqlType == "ALT") { + return AnonyAlterSql(replaceSql); + } + + if (replaceSql.length() > OTHER_SIZE) { + std::string maskedSql = replaceSql.substr(START_SIZE, OTHER_SIZE) + AnonyString(replaceSql.substr(OTHER_SIZE)); + return maskedSql; + } + + return replaceSql; +} + ssize_t SqliteUtils::GetFileSize(const std::string &fileName) { struct stat fileStat; @@ -260,7 +530,7 @@ bool SqliteUtils::IsSlaveDbName(const std::string &fileName) return (pos != std::string::npos) && (pos == fileName.size() - slaveSuffix.size()); } -std::string SqliteUtils::GetSlavePath(const std::string& name) +std::string SqliteUtils::GetSlavePath(const std::string &name) { std::string suffix(".db"); std::string slaveSuffix("_slave.db"); @@ -315,6 +585,9 @@ const char *SqliteUtils::EncryptAlgoDescription(int32_t encryptAlgo) int SqliteUtils::SetSlaveInvalid(const std::string &dbPath) { + if (IsSlaveInvalid(dbPath)) { + return E_OK; + } std::ofstream src((dbPath + SLAVE_FAILURE).c_str(), std::ios::binary); if (src.is_open()) { src.close(); @@ -325,6 +598,9 @@ int SqliteUtils::SetSlaveInvalid(const std::string &dbPath) int SqliteUtils::SetSlaveInterrupted(const std::string &dbPath) { + if (IsSlaveInterrupted(dbPath)) { + return E_OK; + } std::ofstream src((dbPath + SLAVE_INTERRUPT).c_str(), std::ios::binary); if (src.is_open()) { src.close(); 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 228283b2..def9504b 100644 --- a/relational_store/frameworks/native/rdb/src/step_result_set.cpp +++ b/relational_store/frameworks/native/rdb/src/step_result_set.cpp @@ -17,10 +17,10 @@ #include +#include "connection_pool.h" #include "logger.h" #include "rdb_errno.h" #include "sqlite3sym.h" -#include "connection_pool.h" #include "sqlite_errno.h" #include "sqlite_statement.h" #include "sqlite_utils.h" diff --git a/relational_store/frameworks/native/rdb/src/string_utils.cpp b/relational_store/frameworks/native/rdb/src/string_utils.cpp index 07e6dd06..c5560e96 100644 --- a/relational_store/frameworks/native/rdb/src/string_utils.cpp +++ b/relational_store/frameworks/native/rdb/src/string_utils.cpp @@ -26,8 +26,8 @@ std::string StringUtils::SurroundWithQuote(const std::string &value, const std:: } // Join array members as parameters of a function call. -std::string StringUtils::SurroundWithFunction(const std::string &function, const std::string &separator, - const std::vector &array) +std::string StringUtils::SurroundWithFunction( + const std::string &function, const std::string &separator, const std::vector &array) { std::string builder(function); builder += "("; @@ -60,12 +60,12 @@ std::vector StringUtils::Split(const std::string &str, const std::s return res; } -std::string StringUtils::ExtractFilePath(const std::string& fileFullName) +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) +std::string StringUtils::ExtractFileName(const std::string &fileFullName) { return std::string(fileFullName).substr(fileFullName.rfind("/") + 1, fileFullName.size()); } diff --git a/relational_store/frameworks/native/rdb/src/trans_db.cpp b/relational_store/frameworks/native/rdb/src/trans_db.cpp index 93723025..d66c1414 100644 --- a/relational_store/frameworks/native/rdb/src/trans_db.cpp +++ b/relational_store/frameworks/native/rdb/src/trans_db.cpp @@ -104,8 +104,8 @@ std::pair TransDB::BatchInsert(const std::string &table, const Ref return { E_OK, int64_t(rows.RowSize()) }; } -std::pair TransDB::Update(const std::string &table, const Row &row, const std::string &where, - const Values &args, Resolution resolution) +std::pair TransDB::Update( + const std::string &table, const Row &row, const std::string &where, const Values &args, Resolution resolution) { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); auto clause = SqliteUtils::GetConflictClause(static_cast(resolution)); @@ -196,7 +196,7 @@ std::pair TransDB::Execute(const std::string &sql, const V ValueObject object; int sqlType = SqliteUtils::GetSqlStatementType(sql); if (!SqliteUtils::IsSupportSqlForExecute(sqlType) && !SqliteUtils::IsSpecial(sqlType)) { - LOG_ERROR("Not support the sql:%{public}s", sql.c_str()); + LOG_ERROR("Not support the sql:%{public}s", SqliteUtils::AnonySql(sql).c_str()); return { E_INVALID_ARGS, object }; } @@ -207,7 +207,7 @@ std::pair TransDB::Execute(const std::string &sql, const V errCode = statement->Execute(args); if (errCode != E_OK) { - LOG_ERROR("failed,sql:%{public}s, error:0x%{public}x.", sql.c_str(), errCode); + LOG_ERROR("failed,sql:%{public}s, error:0x%{public}x.", SqliteUtils::AnonySql(sql).c_str(), errCode); return { errCode, object }; } @@ -233,7 +233,8 @@ std::pair TransDB::Execute(const std::string &sql, const V auto [err, version] = statement->ExecuteForValue(); if (vSchema_ < static_cast(version)) { LOG_INFO("db:%{public}s exe DDL schema<%{public}" PRIi64 "->%{public}" PRIi64 "> sql:%{public}s.", - SqliteUtils::Anonymous(name_).c_str(), vSchema_, static_cast(version), sql.c_str()); + SqliteUtils::Anonymous(name_).c_str(), vSchema_, static_cast(version), + SqliteUtils::AnonySql(sql).c_str()); vSchema_ = version; } } diff --git a/relational_store/frameworks/native/rdb/src/transaction.cpp b/relational_store/frameworks/native/rdb/src/transaction.cpp index 201a6ffe..420049c3 100644 --- a/relational_store/frameworks/native/rdb/src/transaction.cpp +++ b/relational_store/frameworks/native/rdb/src/transaction.cpp @@ -29,4 +29,4 @@ int32_t Transaction::RegisterCreator(Creator creator) creator_ = std::move(creator); return E_OK; } -} +} // namespace OHOS::NativeRdb diff --git a/relational_store/frameworks/native/rdb/src/transaction_impl.cpp b/relational_store/frameworks/native/rdb/src/transaction_impl.cpp index ed818a95..3da0bf91 100644 --- a/relational_store/frameworks/native/rdb/src/transaction_impl.cpp +++ b/relational_store/frameworks/native/rdb/src/transaction_impl.cpp @@ -16,6 +16,7 @@ #define LOG_TAG "TransactionImpl" #include "transaction_impl.h" + #include "logger.h" #include "rdb_errno.h" #include "rdb_store.h" @@ -196,8 +197,8 @@ std::pair TransactionImpl::BatchInsert(const std::string &table, c return store->BatchInsert(table, rows); } -std::pair TransactionImpl::Update(const std::string &table, const Row &row, const std::string &where, - const Values &args, Resolution resolution) +std::pair TransactionImpl::Update( + const std::string &table, const Row &row, const std::string &where, const Values &args, Resolution resolution) { auto store = GetStore(); if (store == nullptr) { @@ -207,20 +208,20 @@ std::pair TransactionImpl::Update(const std::string &table, const Row return store->Update(table, row, where, args, resolution); } -std::pair TransactionImpl::Update(const Row &row, const AbsRdbPredicates &predicates, - Resolution resolution) +std::pair TransactionImpl::Update( + const Row &row, const AbsRdbPredicates &predicates, Resolution resolution) { auto store = GetStore(); if (store == nullptr) { LOG_ERROR("transaction already close"); return { E_ALREADY_CLOSED, -1 }; } - return store->Update(predicates.GetTableName(), row, predicates.GetWhereClause(), predicates.GetBindArgs(), - resolution); + return store->Update( + predicates.GetTableName(), row, predicates.GetWhereClause(), predicates.GetBindArgs(), resolution); } -std::pair TransactionImpl::Delete(const std::string &table, const std::string &whereClause, - const Values &args) +std::pair TransactionImpl::Delete( + const std::string &table, const std::string &whereClause, const Values &args) { auto store = GetStore(); if (store == nullptr) { @@ -287,4 +288,4 @@ std::pair TransactionImpl::Execute(const std::string &sql, } return store->Execute(sql, args); } -} +} // namespace OHOS::NativeRdb diff --git a/relational_store/frameworks/native/rdb/src/values_bucket.cpp b/relational_store/frameworks/native/rdb/src/values_bucket.cpp index a09e39c4..ae2f7d4b 100644 --- a/relational_store/frameworks/native/rdb/src/values_bucket.cpp +++ b/relational_store/frameworks/native/rdb/src/values_bucket.cpp @@ -86,7 +86,7 @@ void ValuesBucket::PutNull(const std::string &columnName) values_.insert(std::make_pair(columnName, ValueObject())); } -void ValuesBucket::Put(const std::string &columnName, const ValueObject &value) +void ValuesBucket::Put(const std::string &columnName, const ValueObject &value) { values_.insert_or_assign(columnName, value); } diff --git a/relational_store/frameworks/native/rdb/src/values_buckets.cpp b/relational_store/frameworks/native/rdb/src/values_buckets.cpp index 5a8d65bf..c04f5ae9 100644 --- a/relational_store/frameworks/native/rdb/src/values_buckets.cpp +++ b/relational_store/frameworks/native/rdb/src/values_buckets.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ #include "values_buckets.h" + #include "rdb_errno.h" namespace OHOS { @@ -40,7 +41,7 @@ void ValuesBuckets::Put(const ValuesBucket &bucket) auto fieldResult = fields_->insert(field); auto valueResult = values_->insert(value); row.insert(std::make_pair(std::ref(const_cast(*fieldResult.first)), - std::ref(const_cast(*valueResult.first)))); + std::ref(const_cast(*valueResult.first)))); } buckets_.push_back(std::move(row)); } @@ -61,5 +62,5 @@ std::pair ValuesBuckets::Get(size_t row, const Fi return { E_OK, it->second }; } -} -} +} // 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 3f9c5bf8..68e7fcf6 100644 --- a/relational_store/interfaces/inner_api/rdb/include/rdb_errno.h +++ b/relational_store/interfaces/inner_api/rdb/include/rdb_errno.h @@ -306,7 +306,7 @@ static constexpr int E_SQLITE_FULL = (E_BASE + 0x34); static constexpr int E_NOT_SUPPORT_THE_SQL = (E_BASE + 0x35); /** - * @brief The database is already attached. + * @brief The database alias already exists. */ static constexpr int E_ATTACHED_DATABASE_EXIST = (E_BASE + 0x36); @@ -405,6 +405,11 @@ static constexpr int E_SQLITE_SCHEMA = (E_BASE + 0x48); */ static constexpr int E_CANCEL = (E_BASE + 0x49); +/** + * @brief Permission denied + */ +static constexpr int E_PERMISSION_DENIED = (E_BASE + 0x4a); + /** * @brief Do not use except relational_store */ 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 725a9d73..bc6c26e4 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 @@ -612,7 +612,15 @@ public: this->securityLevel_ == config.securityLevel_ && this->journalSize_ == config.journalSize_ && this->pageSize_ == config.pageSize_ && this->dbType_ == config.dbType_ && this->customDir_ == config.customDir_ && this->pluginLibs_ == config.pluginLibs_ && - this->haMode_ == config.haMode_; + this->haMode_ == config.haMode_ && this->readOnly_ == config.readOnly_; + } + + /** + * @brief Overload the does not equal the number operator. + */ + bool operator!=(const RdbStoreConfig &config) const + { + return !(*this == config); } /** @@ -671,6 +679,14 @@ public: PromiseInfo GetPromiseInfo() const; void SetPromiseInfo(PromiseInfo promiseInfo); + + ssize_t GetCheckpointSize() const; + + ssize_t GetStartCheckpointSize() const; + + ssize_t GetWalLimitSize() const; + + void SetWalLimitSize(ssize_t size); int32_t GetHaMode() const; @@ -720,6 +736,9 @@ private: std::string syncMode_; std::string databaseFileType; PromiseInfo promiseInfo_; + ssize_t walLimitSize_; + ssize_t checkpointSize_; + ssize_t startCheckpointSize_; // distributed rdb std::string bundleName_; std::string moduleName_; diff --git a/relational_store/interfaces/inner_api/rdb/include/shared_result_set.h b/relational_store/interfaces/inner_api/rdb/include/shared_result_set.h index 14f6a4da..e4a5b374 100644 --- a/relational_store/interfaces/inner_api/rdb/include/shared_result_set.h +++ b/relational_store/interfaces/inner_api/rdb/include/shared_result_set.h @@ -38,7 +38,7 @@ public: /** * @brief Destructor. */ - ~SharedResultSet() {} + virtual ~SharedResultSet() {} /** * @brief Obtains a block from the {@link SharedResultSet}. 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 d65faef6..54f6b79c 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 @@ -255,6 +255,10 @@ public: int32_t GetHaMode() const; PromiseInfo GetPromiseInfo() const; void SetPromiseInfo(PromiseInfo promiseInfo); + ssize_t GetCheckpointSize() const; + ssize_t GetStartCheckpointSize() const; + ssize_t GetWalLimitSize() const; + void SetWalLimitSize(ssize_t size); void SetHaMode(int32_t haMode); void SetScalarFunctions(const std::map functions); void SetCryptoParam(CryptoParam cryptoParam); @@ -295,6 +299,9 @@ private: std::string syncMode_; std::string databaseFileType; PromiseInfo promiseInfo_; + ssize_t walLimitSize_; + ssize_t checkpointSize_; + ssize_t startCheckpointSize_; // distributed rdb std::string bundleName_; std::string moduleName_; diff --git a/relational_store/interfaces/ndk/include/relational_store.h b/relational_store/interfaces/ndk/include/relational_store.h index 72d9f834..f1a6f524 100644 --- a/relational_store/interfaces/ndk/include/relational_store.h +++ b/relational_store/interfaces/ndk/include/relational_store.h @@ -159,14 +159,14 @@ typedef struct { /** * @brief Define OH_Rdb_ConfigV2 type. * - * @since 13 + * @since 14 */ typedef struct OH_Rdb_ConfigV2 OH_Rdb_ConfigV2; /** * @brief Define Rdb_DBType type. * - * @since 13 + * @since 14 */ typedef enum Rdb_DBType { /** @@ -190,7 +190,7 @@ typedef enum Rdb_DBType { * The possible cause is that the address space of the application is full, As a result, the space * cannot be allocated. * @see OH_Rdb_ConfigV2 - * @since 13 + * @since 14 */ OH_Rdb_ConfigV2 *OH_Rdb_CreateConfig(); @@ -202,7 +202,7 @@ OH_Rdb_ConfigV2 *OH_Rdb_CreateConfig(); * @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. - * @since 13 + * @since 14 */ int OH_Rdb_DestroyConfig(OH_Rdb_ConfigV2 *config); @@ -215,7 +215,7 @@ int OH_Rdb_DestroyConfig(OH_Rdb_ConfigV2 *config); * @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. - * @since 13 + * @since 14 */ int OH_Rdb_SetDatabaseDir(OH_Rdb_ConfigV2 *config, const char *databaseDir); @@ -228,7 +228,7 @@ int OH_Rdb_SetDatabaseDir(OH_Rdb_ConfigV2 *config, const char *databaseDir); * @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. - * @since 13 + * @since 14 */ int OH_Rdb_SetStoreName(OH_Rdb_ConfigV2 *config, const char *storeName); @@ -241,7 +241,7 @@ int OH_Rdb_SetStoreName(OH_Rdb_ConfigV2 *config, const char *storeName); * @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. - * @since 13 + * @since 14 */ int OH_Rdb_SetBundleName(OH_Rdb_ConfigV2 *config, const char *bundleName); @@ -254,7 +254,7 @@ int OH_Rdb_SetBundleName(OH_Rdb_ConfigV2 *config, const char *bundleName); * @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. - * @since 13 + * @since 14 */ int OH_Rdb_SetModuleName(OH_Rdb_ConfigV2 *config, const char *moduleName); @@ -263,11 +263,11 @@ int OH_Rdb_SetModuleName(OH_Rdb_ConfigV2 *config, const char *moduleName); * * @param config Represents a pointer to {@link OH_Rdb_ConfigV2} instance. * Indicates the configuration of the database related to this RDB store. - * @param isEncrypt Indicates whether the database is encrypted. + * @param isEncrypted Indicates whether the database is encrypted. * @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. - * @since 13 + * @since 14 */ int OH_Rdb_SetEncrypted(OH_Rdb_ConfigV2 *config, bool isEncrypted); @@ -280,7 +280,7 @@ int OH_Rdb_SetEncrypted(OH_Rdb_ConfigV2 *config, bool isEncrypted); * @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. - * @since 13 + * @since 14 */ int OH_Rdb_SetSecurityLevel(OH_Rdb_ConfigV2 *config, int securityLevel); @@ -289,10 +289,11 @@ int OH_Rdb_SetSecurityLevel(OH_Rdb_ConfigV2 *config, int securityLevel); * * @param config Represents a pointer to {@link OH_Rdb_ConfigV2} instance. * Indicates the configuration of the database related to this RDB store + * @param area Represents the security area of the database. * @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. - * @since 13 + * @since 14 */ int OH_Rdb_SetArea(OH_Rdb_ConfigV2 *config, int area); @@ -304,15 +305,15 @@ int OH_Rdb_SetArea(OH_Rdb_ConfigV2 *config, int area); * {@link RDB_OK} - success. * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * {@link RDB_E_NOT_SUPPORTED} - The error code for not support db types. - * @since 13 + * @since 14 */ int OH_Rdb_SetDbType(OH_Rdb_ConfigV2 *config, int dbType); /** * @brief Get support db type list - * @param numType The output parameter, which is used to recieve the length of the support db type array. + * @param typeCount The output parameter, which is used to recieve the length of the support db type array. * @return Return Rdb_DBType array contains supported db type, array length is number of support type - * @since 13 + * @since 14 */ const int *OH_Rdb_GetSupportedDbType(int *typeCount); @@ -379,7 +380,7 @@ OH_Rdb_Store *OH_Rdb_GetOrOpen(const OH_Rdb_Config *config, int *errCode); * 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_ConfigV2, OH_Rdb_Store. - * @since 13 + * @since 14 */ OH_Rdb_Store *OH_Rdb_CreateOrOpen(const OH_Rdb_ConfigV2 *config, int *errCode); @@ -420,7 +421,7 @@ int OH_Rdb_DeleteStore(const OH_Rdb_Config *config); * {@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 13 + * @since 14 */ int OH_Rdb_DeleteStoreV2(const OH_Rdb_ConfigV2 *config); @@ -502,14 +503,14 @@ int OH_Rdb_Execute(OH_Rdb_Store *store, const char *sql); * @brief Write operations are performed using the specified transaction represented by the transaction ID * * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. - * @param sql Indicates the SQL statement to execute. * @param trxId The transaction ID of the specified transaction, must be greater than 0 + * @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. * {@link RDB_E_NOT_SUPPORTED} - The error code for not supprt. * @see OH_Rdb_Store. - * @since 13 + * @since 14 */ int OH_Rdb_ExecuteByTrxId(OH_Rdb_Store *store, int64_t trxId, const char *sql); @@ -571,7 +572,7 @@ int OH_Rdb_Commit(OH_Rdb_Store *store); * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * {@link RDB_E_NOT_SUPPORTED} - The error code for not supprt. * @see OH_Rdb_Store. - * @since 13 + * @since 14 */ int OH_Rdb_BeginTransWithTrxId(OH_Rdb_Store *store, int64_t *trxId); @@ -585,7 +586,7 @@ int OH_Rdb_BeginTransWithTrxId(OH_Rdb_Store *store, int64_t *trxId); * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * {@link RDB_E_NOT_SUPPORTED} - The error code for not supprt. * @see OH_Rdb_Store. - * @since 13 + * @since 14 */ int OH_Rdb_RollBackByTrxId(OH_Rdb_Store *store, int64_t trxId); @@ -599,7 +600,7 @@ int OH_Rdb_RollBackByTrxId(OH_Rdb_Store *store, int64_t trxId); * {@link RDB_E_INVALID_ARGS} - The error code for common invalid args. * {@link RDB_E_NOT_SUPPORTED} - The error code for not supprt. * @see OH_Rdb_Store. - * @since 13 + * @since 14 */ int OH_Rdb_CommitByTrxId(OH_Rdb_Store *store, int64_t trxId); 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 18244142..1a26e3c1 100644 --- a/relational_store/test/js/rdb/unittest/src/RdbstoreInsertJsunit.test.js +++ b/relational_store/test/js/rdb/unittest/src/RdbstoreInsertJsunit.test.js @@ -406,5 +406,37 @@ describe('rdbStoreInsertTest', function () { console.log(TAG + "************* testRdbStorebatchInsert002 end *************"); }) + + /** + * @tc.name: rdb batchInsert test + * @tc.number: SUB_DDM_AppDataFWK_JSRDB_batchInsert_0003 + * @tc.desc: rdb batchInsert not exist column test + * @tc.require: issueIB3DGQ + */ + it('testRdbStorebatchInsert003', 0, async function () { + console.log(TAG + "************* testRdbStorebatchInsert003 start *************"); + + await rdbStore.executeSql("delete from test"); + + let valueBucketArray = new Array(); + + var u8 = new Uint8Array([1, 2, 3]) + const valueBucket = { + "name": "zhangsan", + "age": 18, + "salary": 11.5, + "blobType": u8, + "notexistcolumn": 1, + } + valueBucketArray.push(valueBucket); + + let errCode = await rdbStore.batchInsert("test", valueBucketArray); + expect(-1).assertEqual(errCode); + let resultSet = await rdbStore.querySql("SELECT * FROM test"); + let count = resultSet.rowCount; + expect(0).assertEqual(count); + resultSet.close() + console.log(TAG + "************* testRdbStorebatchInsert003 end *************"); + }) console.log(TAG + "*************Unit Test End*************"); }) \ No newline at end of file diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbstoreEncryptionJsunit.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbstoreEncryptionJsunit.test.js index da780895..d88fbb02 100644 --- a/relational_store/test/js/relationalstore/unittest/src/RdbstoreEncryptionJsunit.test.js +++ b/relational_store/test/js/relationalstore/unittest/src/RdbstoreEncryptionJsunit.test.js @@ -15,8 +15,10 @@ import {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from 'deccjsunit/index' import data_relationalStore from '@ohos.data.relationalStore' import ability_featureAbility from '@ohos.ability.featureAbility' +import factory from '@ohos.data.distributedKVStore' const TAG = "[RELATIONAL_STORE_JSKITS_TEST]" +const TEST_BUNDLE_NAME = "com.example.myapplication" const CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test (" + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + "name TEXT NOT NULL, " + "age INTEGER, " + "salary REAL, " + "blobType BLOB)" @@ -732,5 +734,62 @@ describe('rdbEncryptTest', function () { console.log(TAG + "************* RdbDecryptTest_0090 end *************") }) + /** + * @tc.number testEncryptRdbAndKv0002 + * @tc.name Normal test case of using encrypt kv, then using rdb attach interface + * @tc.desc 1.Get encrypt kv db + * 2.Get encrypt rdb1 + * 3.rdb1.backup(rdb2) + * 4.rdb1.restore(rdb2) + */ + it('testEncryptRdbAndKv0002', 0, async () => { + console.log(TAG + "************* testEncryptRdbAndKv0002 start *************"); + let kvConfig = { + bundleName: TEST_BUNDLE_NAME, + context: context + } + let options = { + createIfMissing: true, + encrypt: true, + backup: false, + autoSync: false, + kvStoreType: factory.KVStoreType.SINGLE_VERSION, + securityLevel: factory.SecurityLevel.S2, + } + let rdbConfig = { + name: "RdbTest.db", + securityLevel: data_relationalStore.SecurityLevel.S1, + encrypt: true, + } + let kvManager = factory.createKVManager(kvConfig); + try { + let kvDb = await kvManager.getKVStore('kvDb', options) + rdbConfig.name = "RdbTest1.db" + let rdbStore1 = await data_relationalStore.getRdbStore(context, rdbConfig); + await rdbStore1?.executeSql(CREATE_TABLE_TEST); + console.log(TAG + "testEncryptRdbAndKv0002 create table test success"); + await rdbStore1.backup("RdbTest2.db"); + console.log(TAG + "testEncryptRdbAndKv0002 backup success"); + await rdbStore1?.executeSql("drop table test"); + console.log(TAG + "testEncryptRdbAndKv0002 drop table test success"); + await rdbStore1.restore("RdbTest2.db"); + console.log(TAG + "testEncryptRdbAndKv0002 restore success"); + let valueBucket = { + "name": "zhangsan", + "age": 18, + "salary": 100.5, + }; + await rdbStore1.insert("test", valueBucket) + expect(true).assertTrue(); + } catch (err) { + console.log(TAG + err); + expect(null).assertFail(); + console.log(TAG + "testEncryptRdbAndKv0002 failed"); + } + await kvManager.closeKVStore(TEST_BUNDLE_NAME, 'kvDb'); + await data_relationalStore.deleteRdbStore(context, "RdbTest1.db"); + await data_relationalStore.deleteRdbStore(context, "RdbTest2.db"); + console.log(TAG + "************* testEncryptRdbAndKv0002 end *************"); + }) console.log(TAG + "*************Unit Test End*************") }) diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbstoreRdbstoreJsunit.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbstoreRdbstoreJsunit.test.js index 0f7d06af..be2545dc 100644 --- a/relational_store/test/js/relationalstore/unittest/src/RdbstoreRdbstoreJsunit.test.js +++ b/relational_store/test/js/relationalstore/unittest/src/RdbstoreRdbstoreJsunit.test.js @@ -337,15 +337,17 @@ describe('rdbStoreTest', function () { blobType: new Uint8Array(Array(1024 * 1024).fill(1)), }) const middleTime = new Date().getTime(); + console.log(TAG + "testRdbStore0012, startTime:" + startTime + " middleTime:" + middleTime); - expect((middleTime - startTime) > 2000).assertTrue(); + expect((middleTime - startTime) > 1000).assertTrue(); rdbStore.insertSync('test', { blobType: new Uint8Array(Array(1024 * 1024).fill(1)), }) const endTime = new Date().getTime(); + console.log(TAG + "testRdbStore0012, endTime:" + endTime + " middleTime:" + middleTime); - expect((endTime - middleTime) < 2000).assertTrue(); + expect((endTime - middleTime) < 1000).assertTrue(); console.log(TAG + "************* testRdbStore0012 end *************"); done(); } catch (e) { diff --git a/relational_store/test/native/clouddata/unittest/cloud_data_test.cpp b/relational_store/test/native/clouddata/unittest/cloud_data_test.cpp index fce7a1b3..a58f2d78 100644 --- a/relational_store/test/native/clouddata/unittest/cloud_data_test.cpp +++ b/relational_store/test/native/clouddata/unittest/cloud_data_test.cpp @@ -18,6 +18,8 @@ #include "accesstoken_kit.h" #include "cloud_manager.h" +#include "cloud_types.h" +#include "cloud_types_util.h" #include "logger.h" #include "token_setproc.h" @@ -213,6 +215,116 @@ HWTEST_F(CloudDataTest, CloudDataTest_003, TestSize.Level0) } } +/* * + * @tc.name: EnableCloud001 + * @tc.desc: Test the EnableCloud API + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(CloudDataTest, EnableCloud001, TestSize.Level0) +{ + AllocSystemHapToken(g_systemPolicy); + auto [state, proxy] = CloudManager::GetInstance().GetCloudService(); + ASSERT_EQ(state, CloudService::SUCCESS); + std::map switches; + switches.emplace(TEST_BUNDLE_NAME, 0); + auto status = proxy->EnableCloud(TEST_ACCOUNT_ID, switches); + EXPECT_NE(status, CloudService::SUCCESS); +} + +/* * + * @tc.name: DisableCloud001 + * @tc.desc: Test the DisableCloud API + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(CloudDataTest, DisableCloud001, TestSize.Level0) +{ + AllocSystemHapToken(g_systemPolicy); + auto [state, proxy] = CloudManager::GetInstance().GetCloudService(); + ASSERT_EQ(state, CloudService::SUCCESS); + auto status = proxy->DisableCloud(TEST_ACCOUNT_ID); + EXPECT_NE(status, CloudService::SUCCESS); +} + +/* * + * @tc.name: ChangeAppSwitch001 + * @tc.desc: Test the ChangeAppSwitch API + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(CloudDataTest, ChangeAppSwitch001, TestSize.Level0) +{ + AllocSystemHapToken(g_systemPolicy); + auto [state, proxy] = CloudManager::GetInstance().GetCloudService(); + ASSERT_EQ(state, CloudService::SUCCESS); + auto status = proxy->ChangeAppSwitch(TEST_ACCOUNT_ID, TEST_BUNDLE_NAME, 0); + EXPECT_NE(status, CloudService::SUCCESS); +} + +/* * + * @tc.name: Clean001 + * @tc.desc: Test the Clean API + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(CloudDataTest, Clean001, TestSize.Level0) +{ + AllocSystemHapToken(g_systemPolicy); + auto [state, proxy] = CloudManager::GetInstance().GetCloudService(); + ASSERT_EQ(state, CloudService::SUCCESS); + std::map actions; + actions.emplace(TEST_BUNDLE_NAME, 0); + auto status = proxy->Clean(TEST_ACCOUNT_ID, actions); + EXPECT_EQ(status, CloudService::ERROR); +} + +/* * + * @tc.name: NotifyDataChange001 + * @tc.desc: Test the NotifyDataChange API + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(CloudDataTest, NotifyDataChange001, TestSize.Level0) +{ + AllocSystemHapToken(g_systemPolicy); + auto [state, proxy] = CloudManager::GetInstance().GetCloudService(); + ASSERT_EQ(state, CloudService::SUCCESS); + auto status = proxy->NotifyDataChange("id", "data", 100); + EXPECT_EQ(status, CloudService::INVALID_ARGUMENT); +} + +/* * + * @tc.name: NotifyDataChange002 + * @tc.desc: Test the NotifyDataChange API + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(CloudDataTest, NotifyDataChange002, TestSize.Level0) +{ + AllocSystemHapToken(g_systemPolicy); + auto [state, proxy] = CloudManager::GetInstance().GetCloudService(); + ASSERT_EQ(state, CloudService::SUCCESS); + auto status = proxy->NotifyDataChange(TEST_ACCOUNT_ID, TEST_BUNDLE_NAME); + EXPECT_EQ(status, CloudService::INVALID_ARGUMENT); +} + +/* * + * @tc.name: SetGlobalCloudStrategy001 + * @tc.desc: Test the SetGlobalCloudStrategy API + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(CloudDataTest, SetGlobalCloudStrategy001, TestSize.Level0) +{ + AllocSystemHapToken(g_systemPolicy); + auto [state, proxy] = CloudManager::GetInstance().GetCloudService(); + ASSERT_EQ(state, CloudService::SUCCESS); + std::vector values = { 0 }; + auto status = proxy->SetGlobalCloudStrategy(Strategy::STRATEGY_NETWORK, values); + EXPECT_EQ(status, CloudService::SUCCESS); +} + /* * * @tc.name: QueryLastSyncInfo001 * @tc.desc: Test the system application permissions of the QueryLastSyncInfo API diff --git a/relational_store/test/native/rdb/unittest/rdb_double_write_test.cpp b/relational_store/test/native/rdb/unittest/rdb_double_write_test.cpp index 3e02914e..9fb8cfb1 100644 --- a/relational_store/test/native/rdb/unittest/rdb_double_write_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_double_write_test.cpp @@ -950,14 +950,16 @@ HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_027, TestSize.Level1) config.SetAllowRebuild(true); DoubleWriteTestOpenCallback helper; + store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + EXPECT_EQ(errCode, E_OK); + ASSERT_NE(store, nullptr); + RdbStoreConfig slaveConfig(RdbDoubleWriteTest::SLAVE_DATABASE_NAME); DoubleWriteTestOpenCallback slaveHelper; RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode); EXPECT_NE(RdbDoubleWriteTest::slaveStore, nullptr); - store = RdbHelper::GetRdbStore(config, 1, helper, errCode); - EXPECT_EQ(errCode, E_OK); - ASSERT_NE(store, nullptr); + EXPECT_EQ(store->Backup(std::string(""), {}), E_OK); int64_t id = 10; int count = 100; @@ -1117,4 +1119,46 @@ HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_033, TestSize.Level1) EXPECT_EQ(rebuiltType, RebuiltType::REPAIRED); RdbDoubleWriteTest::CheckNumber(store, count); +} + +/** + * @tc.name: RdbStore_DoubleWrite_034 + * @tc.desc: open MANUAL_TRIGGER db, write, backup, insert, check count, restore, check count + * @tc.type: FUNC + */ +HWTEST_F(RdbDoubleWriteTest, RdbStore_DoubleWrite_034, TestSize.Level1) +{ + int errCode = E_OK; + RdbStoreConfig config(RdbDoubleWriteTest::DATABASE_NAME); + config.SetHaMode(HAMode::MANUAL_TRIGGER); + config.SetAllowRebuild(true); + DoubleWriteTestOpenCallback helper; + + store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + EXPECT_EQ(errCode, E_OK); + ASSERT_NE(store, nullptr); + + int64_t id = 10; + int count = 100; + Insert(id, count); + + RdbStoreConfig slaveConfig(RdbDoubleWriteTest::SLAVE_DATABASE_NAME); + DoubleWriteTestOpenCallback slaveHelper; + RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode); + EXPECT_NE(RdbDoubleWriteTest::slaveStore, nullptr); + EXPECT_EQ(store->Backup(std::string(""), {}), E_OK); + RdbDoubleWriteTest::CheckNumber(slaveStore, count); + + id = 1000; + Insert(id, count, true); + RdbDoubleWriteTest::CheckNumber(store, count); + RdbDoubleWriteTest::CheckNumber(slaveStore, count + count); + slaveStore = nullptr; + + EXPECT_EQ(store->Restore(std::string(""), {}), E_OK); + RdbDoubleWriteTest::CheckNumber(store, count + count); + + RdbDoubleWriteTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode); + EXPECT_NE(RdbDoubleWriteTest::slaveStore, nullptr); + RdbDoubleWriteTest::CheckNumber(slaveStore, 0L); } \ 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 index e16d009a..21f6b822 100644 --- a/relational_store/test/native/rdb/unittest/rdb_read_only_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_read_only_test.cpp @@ -33,6 +33,7 @@ public: void TearDown(); static const std::string READONLY_DATABASE_NAME; + static const std::string READONLY_DATABASE_NAME_18; // for testcase 18 static const std::string READONLY_DATABASE_BAK_NAME; static const std::string DATABASE_NAME; static std::shared_ptr readOnlyStore; @@ -40,6 +41,7 @@ public: 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_NAME_18 = RDB_TEST_PATH + "readOnly1.db"; const std::string RdbReadOnlyTest::READONLY_DATABASE_BAK_NAME = RDB_TEST_PATH + "readOnlyBak.db"; std::shared_ptr RdbReadOnlyTest::readOnlyStore = nullptr; @@ -406,14 +408,14 @@ HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0018, TestSize.Level1) return; } int errCode = E_ERROR; - RdbStoreConfig config(RdbReadOnlyTest::READONLY_DATABASE_NAME); + RdbStoreConfig config(RdbReadOnlyTest::READONLY_DATABASE_NAME_18); 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); + ASSERT_NE(nullptr, store); auto [ret, id] = store->BeginTrans(); EXPECT_EQ(E_NOT_SUPPORT, ret); diff --git a/relational_store/test/native/rdb/unittest/rdb_security_manager_test.cpp b/relational_store/test/native/rdb/unittest/rdb_security_manager_test.cpp index c1930c4a..9d66ac6b 100644 --- a/relational_store/test/native/rdb/unittest/rdb_security_manager_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_security_manager_test.cpp @@ -122,26 +122,35 @@ HWTEST_F(RdbSecurityManagerTest, LockUnlock, TestSize.Level1) HWTEST_F(RdbSecurityManagerTest, LoadSecretKeyFromDiskTest, TestSize.Level1) { int errCode = E_OK; - std::string name = "secret_key_load_test"; - RdbStoreConfig config(RDB_TEST_PATH + name); + std::string dbPath = RDB_TEST_PATH + "secret_key_load_test.db"; + RdbStoreConfig config(dbPath); config.SetEncryptStatus(true); + config.SetBundleName(BUNDLE_NAME); RdbStoreSecurityManagerTestOpenCallback helper; auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode); EXPECT_EQ(errCode, E_OK); EXPECT_NE(store, nullptr); - - RdbSecurityManager::KeyFiles keyFile(RDB_TEST_PATH); + store = nullptr; + RdbSecurityManager::KeyFiles keyFile(dbPath); const std::string file = keyFile.GetKeyFile(RdbSecurityManager::KeyFileType::PUB_KEY_FILE); + std::vector keyfile1; + ASSERT_TRUE(OHOS::LoadBufferFromFile(file, keyfile1)); + std::vector content = { 'a' }; bool ret = OHOS::SaveBufferToFile(file, content); ASSERT_TRUE(ret); - RdbPassword pwd = - RdbSecurityManager::GetInstance().GetRdbPassword(RDB_TEST_PATH, RdbSecurityManager::KeyFileType::PUB_KEY_FILE); - ASSERT_EQ(pwd.GetSize(), 0); - - auto store1 = RdbHelper::GetRdbStore(config, 1, helper, errCode); + + std::vector keyfile2; + ASSERT_TRUE(OHOS::LoadBufferFromFile(file, keyfile2)); + ASSERT_NE(keyfile1.size(), keyfile2.size()); + + RdbStoreConfig config1(dbPath); + config1.SetEncryptStatus(true); + config1.SetBundleName(BUNDLE_NAME); + RdbStoreSecurityManagerTestOpenCallback helper1; + auto store1 = RdbHelper::GetRdbStore(config1, 1, helper1, errCode); EXPECT_EQ(errCode, E_OK); EXPECT_NE(store1, nullptr); diff --git a/relational_store/test/native/rdb/unittest/rdb_store_backup_restore_test.cpp b/relational_store/test/native/rdb/unittest/rdb_store_backup_restore_test.cpp index 0207f442..f427e026 100644 --- a/relational_store/test/native/rdb/unittest/rdb_store_backup_restore_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_store_backup_restore_test.cpp @@ -12,34 +12,39 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "rdb_store_impl.h" - #include +#include #include #include -#include #include "common.h" #include "rdb_errno.h" #include "rdb_helper.h" #include "rdb_open_callback.h" +#include "rdb_store_impl.h" using namespace testing::ext; using namespace OHOS::NativeRdb; class RdbStoreBackupRestoreTest : public testing::Test { public: - static void SetUpTestCase() {} - static void TearDownTestCase() {} - void SetUp() {} - void TearDown() {} + static void SetUpTestCase() + { + } + static void TearDownTestCase() + { + } + void SetUp(); + void TearDown(); + void CorruptDoubleWriteStore(); void CheckResultSet(std::shared_ptr &store); void CheckAge(std::shared_ptr &resultSet); void CheckSalary(std::shared_ptr &resultSet); void CheckBlob(std::shared_ptr &resultSet); static constexpr char DATABASE_NAME[] = "/data/test/backup_restore_test.db"; + static constexpr char slaveDataBaseName[] = "/data/test/backup_restore_test_slave.db"; static constexpr char BACKUP_DATABASE_NAME[] = "/data/test/backup_restore_test_backup.db"; }; @@ -64,113 +69,34 @@ int RdbStoreBackupRestoreTestOpenCallback::OnUpgrade(RdbStore &store, int oldVer { return E_OK; } - -void RdbStoreBackupRestoreTest::CheckResultSet(std::shared_ptr &store) -{ - std::shared_ptr resultSet = - store->QuerySql("SELECT * FROM test WHERE name = ?", std::vector{ "zhangsan" }); - EXPECT_NE(resultSet, nullptr); - - int columnIndex; - int intVal; - std::string strVal; - ColumnType columnType; - int position; - int ret = resultSet->GetRowIndex(position); - EXPECT_EQ(ret, E_OK); - EXPECT_EQ(position, -1); - - ret = resultSet->GetColumnType(0, columnType); - EXPECT_EQ(ret, E_ROW_OUT_RANGE); - - ret = resultSet->GoToFirstRow(); - EXPECT_EQ(ret, E_OK); - - ret = resultSet->GetColumnIndex("id", columnIndex); - EXPECT_EQ(ret, E_OK); - EXPECT_EQ(columnIndex, 0); - ret = resultSet->GetColumnType(columnIndex, columnType); - EXPECT_EQ(ret, E_OK); - EXPECT_EQ(columnType, ColumnType::TYPE_INTEGER); - ret = resultSet->GetInt(columnIndex, intVal); - EXPECT_EQ(ret, E_OK); - EXPECT_EQ(1, intVal); - - ret = resultSet->GetColumnIndex("name", columnIndex); - EXPECT_EQ(ret, E_OK); - ret = resultSet->GetColumnType(columnIndex, columnType); - EXPECT_EQ(ret, E_OK); - EXPECT_EQ(columnType, ColumnType::TYPE_STRING); - ret = resultSet->GetString(columnIndex, strVal); - EXPECT_EQ(ret, E_OK); - EXPECT_EQ("zhangsan", strVal); - - CheckAge(resultSet); - CheckSalary(resultSet); - CheckBlob(resultSet); - - ret = resultSet->GoToNextRow(); - EXPECT_EQ(ret, E_ROW_OUT_RANGE); - - ret = resultSet->GetColumnType(columnIndex, columnType); - EXPECT_EQ(ret, E_ROW_OUT_RANGE); - - ret = resultSet->Close(); - EXPECT_EQ(ret, E_OK); -} - -void RdbStoreBackupRestoreTest::CheckAge(std::shared_ptr &resultSet) +void RdbStoreBackupRestoreTest::SetUp(void) { - int columnIndex; - int intVal; - ColumnType columnType; - int ret = resultSet->GetColumnIndex("age", columnIndex); - EXPECT_EQ(ret, E_OK); - ret = resultSet->GetColumnType(columnIndex, columnType); - EXPECT_EQ(ret, E_OK); - EXPECT_EQ(columnType, ColumnType::TYPE_INTEGER); - ret = resultSet->GetInt(columnIndex, intVal); - EXPECT_EQ(ret, E_OK); - // 18: age is 18 - EXPECT_EQ(18, intVal); + RdbHelper::ClearCache(); + int errocode = RdbHelper::DeleteRdbStore(DATABASE_NAME); + EXPECT_EQ(E_OK, errocode); + errocode = RdbHelper::DeleteRdbStore(BACKUP_DATABASE_NAME); + EXPECT_EQ(E_OK, errocode); } - -void RdbStoreBackupRestoreTest::CheckSalary(std::shared_ptr &resultSet) +void RdbStoreBackupRestoreTest::TearDown(void) { - int columnIndex; - double dVal; - ColumnType columnType; - int ret = resultSet->GetColumnIndex("salary", columnIndex); - EXPECT_EQ(ret, E_OK); - ret = resultSet->GetColumnType(columnIndex, columnType); - EXPECT_EQ(ret, E_OK); - EXPECT_EQ(columnType, ColumnType::TYPE_FLOAT); - ret = resultSet->GetDouble(columnIndex, dVal); - EXPECT_EQ(ret, E_OK); - // 100.5: salary is 100.5 - EXPECT_EQ(100.5, dVal); + RdbHelper::ClearCache(); + int errocode = RdbHelper::DeleteRdbStore(DATABASE_NAME); + EXPECT_EQ(E_OK, errocode); + errocode = RdbHelper::DeleteRdbStore(BACKUP_DATABASE_NAME); + EXPECT_EQ(E_OK, errocode); } - -void RdbStoreBackupRestoreTest::CheckBlob(std::shared_ptr &resultSet) +void RdbStoreBackupRestoreTest::CorruptDoubleWriteStore(void) { - int columnIndex; - std::vector blob; - ColumnType columnType; - int ret = resultSet->GetColumnIndex("blobType", columnIndex); - EXPECT_EQ(ret, E_OK); - ret = resultSet->GetColumnType(columnIndex, columnType); - EXPECT_EQ(ret, E_OK); - EXPECT_EQ(columnType, ColumnType::TYPE_BLOB); - ret = resultSet->GetBlob(columnIndex, blob); - EXPECT_EQ(ret, E_OK); - // 3: blob size - EXPECT_EQ(3, static_cast(blob.size())); - // 1: blob[0] is 1 - EXPECT_EQ(1, blob[0]); - // 2: blob[1] is 2 - EXPECT_EQ(2, blob[1]); - // 3: blob[2] is 3 - EXPECT_EQ(3, blob[2]); + std::fstream file(DATABASE_NAME, std::ios::in | std::ios::out | std::ios::binary); + ASSERT_TRUE(file.is_open() == true); + const int seekPosition = 30; + file.seekp(seekPosition, std::ios::beg); + ASSERT_TRUE(file.good() == true); + const int bytesToWrite = 2; + char bytes[bytesToWrite] = { 0x6, 0x6 }; + file.write(bytes, bytesToWrite); + ASSERT_TRUE(file.good() == true); + file.close(); } /* * @@ -211,10 +137,12 @@ HWTEST_F(RdbStoreBackupRestoreTest, Rdb_BackupRestoreTest_001, TestSize.Level2) ret = store->Restore(BACKUP_DATABASE_NAME); EXPECT_EQ(ret, E_OK); - CheckResultSet(store); - - RdbHelper::DeleteRdbStore(RdbStoreBackupRestoreTest::DATABASE_NAME); - RdbHelper::DeleteRdbStore(RdbStoreBackupRestoreTest::BACKUP_DATABASE_NAME); + std::shared_ptr resultSet = + store->QuerySql("SELECT * FROM test WHERE name = ?", std::vector{ "zhangsan" }); + ret = resultSet->GoToFirstRow(); + EXPECT_EQ(ret, E_OK); + ret = resultSet->Close(); + EXPECT_EQ(ret, E_OK); } /* * @@ -269,9 +197,6 @@ HWTEST_F(RdbStoreBackupRestoreTest, Rdb_BackupRestoreTest_002, TestSize.Level2) ret = store->ExecuteSql(RdbStoreBackupRestoreTestOpenCallback::CREATE_TABLE_TEST); EXPECT_EQ(ret, E_OK); - - RdbHelper::DeleteRdbStore(DATABASE_NAME); - RdbHelper::DeleteRdbStore(BACKUP_DATABASE_NAME); } /* * @@ -314,8 +239,284 @@ HWTEST_F(RdbStoreBackupRestoreTest, Rdb_BackupRestoreTest_003, TestSize.Level2) ret = store->Restore(BACKUP_DATABASE_NAME); EXPECT_EQ(ret, E_OK); - CheckResultSet(store); + std::shared_ptr resultSet = + store->QuerySql("SELECT * FROM test WHERE name = ?", std::vector{ "zhangsan" }); + ret = resultSet->GoToFirstRow(); + EXPECT_EQ(ret, E_OK); + ret = resultSet->Close(); + EXPECT_EQ(ret, E_OK); +} - RdbHelper::DeleteRdbStore(RdbStoreBackupRestoreTest::DATABASE_NAME); - RdbHelper::DeleteRdbStore(RdbStoreBackupRestoreTest::BACKUP_DATABASE_NAME); +/* * + * @tc.name: Rdb_BackupRestoreTest_004 + * @tc.desc: hamode is replica, backup and deletestore and restore, after restore can insert + * @tc.type: FUNC + */ +HWTEST_F(RdbStoreBackupRestoreTest, Rdb_BackupRestoreTest_004, TestSize.Level2) +{ + int errCode = E_OK; + RdbStoreConfig config(RdbStoreBackupRestoreTest::DATABASE_NAME); + config.SetEncryptStatus(true); + config.SetHaMode(HAMode::MAIN_REPLICA); + RdbStoreBackupRestoreTestOpenCallback helper; + auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + EXPECT_EQ(errCode, E_OK); + EXPECT_NE(store, nullptr); + + int64_t id; + ValuesBucket values; + + values.Put("id", 1); + values.Put("name", std::string("zhangsan")); + values.Put("age", 18); + values.Put("salary", 100.5); + values.Put("blobType", std::vector{ 1, 2, 3 }); + int ret = store->Insert(id, "test", values); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(1, id); + + ret = store->Backup(BACKUP_DATABASE_NAME); + EXPECT_EQ(ret, E_OK); + + ret = RdbHelper::DeleteRdbStore(RdbStoreBackupRestoreTest::DATABASE_NAME); + EXPECT_EQ(ret, E_OK); + + ret = store->Restore(BACKUP_DATABASE_NAME); + EXPECT_EQ(ret, E_OK); + + std::shared_ptr resultSet = + store->QuerySql("SELECT * FROM test WHERE name = ?", std::vector{ "zhangsan" }); + ret = resultSet->GoToFirstRow(); + EXPECT_EQ(ret, E_OK); + ret = resultSet->GoToNextRow(); + EXPECT_EQ(ret, E_ROW_OUT_RANGE); + ret = resultSet->Close(); + EXPECT_EQ(ret, E_OK); + + values.Clear(); + values.Put("id", 2); + values.Put("name", std::string("lisa")); + values.Put("age", 19); + values.Put("salary", 101); + values.Put("blobType", std::vector{ 4, 5, 6 }); + ret = store->Insert(id, "test", values); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(2, id); + + resultSet = store->QuerySql("SELECT * FROM test WHERE name = ?", std::vector{ "lisa" }); + ret = resultSet->GoToFirstRow(); + EXPECT_EQ(ret, E_OK); + ret = resultSet->GoToNextRow(); + EXPECT_EQ(ret, E_ROW_OUT_RANGE); + ret = resultSet->Close(); + EXPECT_EQ(ret, E_OK); } + +/* * + * @tc.name: Rdb_BackupRestoreTest_005 + * @tc.desc: hamode is replica , backup and restore for broken original db, and after restore can insert + * @tc.type: FUNC + */ +HWTEST_F(RdbStoreBackupRestoreTest, Rdb_BackupRestoreTest_005, TestSize.Level2) +{ + int errCode = E_OK; + RdbStoreConfig config(RdbStoreBackupRestoreTest::DATABASE_NAME); + config.SetEncryptStatus(true); + config.SetHaMode(HAMode::MAIN_REPLICA); + RdbStoreBackupRestoreTestOpenCallback helper; + auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + EXPECT_EQ(errCode, E_OK); + EXPECT_NE(store, nullptr); + + int64_t id; + ValuesBucket values; + + values.Put("id", 1); + values.Put("name", std::string("zhangsan")); + values.Put("age", 18); + values.Put("salary", 100.5); + values.Put("blobType", std::vector{ 1, 2, 3 }); + int ret = store->Insert(id, "test", values); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(1, id); + + ret = store->Backup(BACKUP_DATABASE_NAME); + EXPECT_EQ(ret, E_OK); + + store = nullptr; + CorruptDoubleWriteStore(); + store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + EXPECT_EQ(errCode, E_OK); + + int deletedRows = 0; + ret = store->Delete(deletedRows, "test", "id = 1"); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(1, deletedRows); + + ret = store->Restore(BACKUP_DATABASE_NAME); + EXPECT_EQ(ret, E_OK); + + std::shared_ptr resultSet = + store->QuerySql("SELECT * FROM test WHERE name = ?", std::vector{ "zhangsan" }); + ret = resultSet->GoToFirstRow(); + EXPECT_EQ(ret, E_OK); + ret = resultSet->GoToNextRow(); + EXPECT_EQ(ret, E_ROW_OUT_RANGE); + ret = resultSet->Close(); + EXPECT_EQ(ret, E_OK); +} + +/* * + * @tc.name: Rdb_BackupRestoreTest_006 + * @tc.desc: hamode is replica , backup and restore, aftre restore ,store can insert data and delete data and query + * @tc.type: FUNC + */ +HWTEST_F(RdbStoreBackupRestoreTest, Rdb_BackupRestoreTest_006, TestSize.Level2) +{ + int errCode = E_OK; + RdbStoreConfig config(RdbStoreBackupRestoreTest::DATABASE_NAME); + config.SetEncryptStatus(true); + config.SetHaMode(HAMode::MAIN_REPLICA); + RdbStoreBackupRestoreTestOpenCallback helper; + auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + EXPECT_EQ(errCode, E_OK); + EXPECT_NE(store, nullptr); + + int64_t id; + ValuesBucket values; + + values.Put("id", 1); + values.Put("name", std::string("zhangsan")); + values.Put("age", 18); + values.Put("salary", 100.5); + values.Put("blobType", std::vector{ 1, 2, 3 }); + int ret = store->Insert(id, "test", values); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(1, id); + + ret = store->Backup(BACKUP_DATABASE_NAME); + EXPECT_EQ(ret, E_OK); + + int deletedRows = 0; + ret = store->Delete(deletedRows, "test", "id = 1"); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(1, deletedRows); + + ret = store->Restore(BACKUP_DATABASE_NAME); + EXPECT_EQ(ret, E_OK); + std::shared_ptr resultSet = + store->QuerySql("SELECT * FROM test WHERE name = ?", std::vector{ "zhangsan" }); + ret = resultSet->GoToFirstRow(); + EXPECT_EQ(ret, E_OK); + ret = resultSet->Close(); + EXPECT_EQ(ret, E_OK); + + deletedRows = 0; + ret = store->Delete(deletedRows, "test", "id = 1"); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(1, deletedRows); + resultSet = store->QuerySql("SELECT * FROM test WHERE name = ?", std::vector{ "zhangsan" }); + ret = resultSet->GoToFirstRow(); + EXPECT_EQ(ret, E_ROW_OUT_RANGE); + ret = resultSet->Close(); + EXPECT_EQ(ret, E_OK); +} + +/* * + * @tc.name: Rdb_BackupRestoreTest_007 + * @tc.desc: hamode is replica , deletestore , cannot backup and restore + * @tc.type: FUNC + */ +HWTEST_F(RdbStoreBackupRestoreTest, Rdb_BackupRestoreTest_007, TestSize.Level2) +{ + int errCode = E_OK; + RdbStoreConfig config(RdbStoreBackupRestoreTest::DATABASE_NAME); + config.SetEncryptStatus(true); + config.SetHaMode(HAMode::MAIN_REPLICA); + RdbStoreBackupRestoreTestOpenCallback helper; + auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + EXPECT_EQ(errCode, E_OK); + EXPECT_NE(store, nullptr); + + int64_t id; + ValuesBucket values; + + values.Put("id", 1); + values.Put("name", std::string("zhangsan")); + values.Put("age", 18); + values.Put("salary", 100.5); + values.Put("blobType", std::vector{ 1, 2, 3 }); + int ret = store->Insert(id, "test", values); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(1, id); + + ret = RdbHelper::DeleteRdbStore(DATABASE_NAME); + EXPECT_EQ(ret, E_OK); + + ret = store->Backup(BACKUP_DATABASE_NAME); + EXPECT_EQ(ret, E_DB_NOT_EXIST); + EXPECT_NE(0, access(BACKUP_DATABASE_NAME, F_OK)); + EXPECT_NE(0, access(slaveDataBaseName, F_OK)); + + ret = store->Restore(BACKUP_DATABASE_NAME); + EXPECT_EQ(ret, E_INVALID_FILE_PATH); + + std::shared_ptr resultSet = + store->QuerySql("SELECT * FROM test WHERE name = ?", std::vector{ "zhangsan" }); + ret = resultSet->GoToFirstRow(); + EXPECT_EQ(ret, E_SQLITE_IOERR); + ret = resultSet->Close(); + EXPECT_EQ(ret, E_OK); +} + +/* * + * @tc.name: Rdb_BackupRestoreTest_008 + * @tc.desc: hamode is replica , backup and restore, check slavestore and backupstore + * @tc.type: FUNC + */ +HWTEST_F(RdbStoreBackupRestoreTest, Rdb_BackupRestoreTest_008, TestSize.Level2) +{ + int errCode = E_OK; + RdbStoreConfig config(RdbStoreBackupRestoreTest::DATABASE_NAME); + config.SetEncryptStatus(true); + config.SetHaMode(HAMode::MAIN_REPLICA); + RdbStoreBackupRestoreTestOpenCallback helper; + auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + EXPECT_EQ(errCode, E_OK); + EXPECT_NE(store, nullptr); + + int64_t id; + ValuesBucket values; + + values.Put("id", 1); + values.Put("name", std::string("zhangsan")); + values.Put("age", 18); + values.Put("salary", 100.5); + values.Put("blobType", std::vector{ 1, 2, 3 }); + int ret = store->Insert(id, "test", values); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(1, id); + + ret = store->Backup(BACKUP_DATABASE_NAME); + EXPECT_EQ(ret, E_OK); + + int deletedRows = 0; + ret = store->Delete(deletedRows, "test", "id = 1"); + EXPECT_EQ(ret, E_OK); + EXPECT_EQ(1, deletedRows); + + ret = store->Restore(BACKUP_DATABASE_NAME); + EXPECT_EQ(ret, E_OK); + + std::shared_ptr resultSet = + store->QuerySql("SELECT * FROM test WHERE name = ?", std::vector{ "zhangsan" }); + ret = resultSet->GoToFirstRow(); + EXPECT_EQ(ret, E_OK); + ret = resultSet->GoToNextRow(); + EXPECT_EQ(ret, E_ROW_OUT_RANGE); + ret = resultSet->Close(); + EXPECT_EQ(ret, E_OK); + + EXPECT_EQ(0, access(BACKUP_DATABASE_NAME, F_OK)); + EXPECT_EQ(0, access(slaveDataBaseName, F_OK)); +} \ No newline at end of file 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 ef58eb0b..279e7a86 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 @@ -259,6 +259,28 @@ HWTEST_F(RdbStoreImplTest, Rdb_BatchInsertTest_001, TestSize.Level2) EXPECT_EQ(E_OK, ret); } +/* * + * @tc.name: Rdb_BatchInsertTest_002 + * @tc.desc: Abnormal testCase for BatchInsert, if column is not exist. + * @tc.type: FUNC + */ +HWTEST_F(RdbStoreImplTest, Rdb_BatchInsertTest_002, TestSize.Level2) +{ + store_->ExecuteSql("CREATE TABLE batchInsertTest " + "(id INTEGER PRIMARY KEY AUTOINCREMENT, data INTEGER, data1 INTEGER, " + "data2 INTEGER);"); + ValuesBucket valuesBucket; + valuesBucket.PutInt("data", ValueObject(0)); + valuesBucket.PutInt("data1", ValueObject(1)); + valuesBucket.PutInt("data2", ValueObject(2)); + valuesBucket.PutInt("NonexistentColumn", ValueObject(3)); + std::vector valuesBuckets = { valuesBucket }; + int64_t insertNum = 1; + int ret = store_->BatchInsert(insertNum, "batchInsertTest", valuesBuckets); + EXPECT_EQ(-1, insertNum); + EXPECT_EQ(E_OK, ret); +} + /* * * @tc.name: Rdb_QueryTest_001 * @tc.desc: Abnormal testCase for Query, if table name is empty diff --git a/relational_store/test/native/rdb/unittest/sqlite_utils_test.cpp b/relational_store/test/native/rdb/unittest/sqlite_utils_test.cpp index d528681c..cb89c4dd 100644 --- a/relational_store/test/native/rdb/unittest/sqlite_utils_test.cpp +++ b/relational_store/test/native/rdb/unittest/sqlite_utils_test.cpp @@ -160,4 +160,150 @@ HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0023, TestSize.Level1) { EXPECT_EQ(SqliteUtils::Anonymous("file /data/stage/el2/database/rdb/ddddddd/linker_reborn.db-wal"), "file /***/el2/***/linker_reborn.db-wal"); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0024, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::AnonySql("select value1, value2 from table1 WHERE case = 1."), + "select ***ue1, ***ue2 from ***le1 WHERE *ase = *."); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0025, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::AnonySql("select district value1, value2 from table1 " + "WHERE case = 1 groupby value1 limit 1."), + "select district ***ue1, ***ue2 from ***le1 " + "WHERE *ase = * groupby ***ue1 limit *."); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0026, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::AnonySql("select value1, value2 from table1."), "select ***ue1, ***ue2 from ***le1."); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0027, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::AnonySql("select table1.value1, table2.value2 from table1, table2."), + "select ***le1.***ue1, ***le2.***ue2 from ***le1, ***le2."); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0028, TestSize.Level1) +{ + EXPECT_EQ( + SqliteUtils::AnonySql("select ***le1.***ue1 as *d, ***le2.***ue2 as **lue from ***le1 as A, ***le2 as B."), + "select ***le1.***ue1 as *d, ***le2.***ue2 as **lue from ***le1 as A, ***le2 as B."); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0029, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::AnonySql("SELECT * FROM test."), "SELECT * FROM *est."); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0030, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::AnonySql("SELECT count(*) FROM test."), "SELECT count(*) FROM *est."); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0031, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::AnonySql("SELECT average(*) FROM test."), "SELECT average(*) FROM *est."); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0032, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::AnonySql("INSERT INTO test (data1, data2, data3, data4) VALUES (?, ?, ?, ?);"), + "INSERT INTO *est (**ta1, **ta2, **ta3, **ta4) VALUES (?, ?, ?, ?);"); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0033, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::AnonySql( + "INSERT INTO test (data1, data2, data3, data4) VALUES (?, ?, ?, ?),(?,?,?,?),(?,?,?,?),(?,?,?,?);"), + "INSERT INTO *est (**ta1, **ta2, **ta3, **ta4) VALUES (?, ?, ?, ?),(?,?,?,?),(?,?,?,?),(?,?,?,?);"); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0034, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::AnonySql("UPDATE test SET age = 8 WHERE id = 1."), "UPDATE *est SET *ge = * WHERE *d = *."); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0035, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::AnonySql("UPDATE test SET age = 8 WHERE id = 1 and id = 1 or id = 1."), + "UPDATE *est SET *ge = * WHERE *d = * and *d = * or *d = *."); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0036, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::AnonySql("DELETE FROM test;"), "DELETE FROM *est;"); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0037, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::AnonySql("DELETE FROM test WHERE time = 3;"), "DELETE FROM *est WHERE *ime = *;"); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0038, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::AnonySql("CREATE DATABASE DBtest.db;"), "CREATE DATABASE ***est.*b;"); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0039, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::AnonySql("CREATE TABLE IF NOT EXISTS TEST (id INT PRIMARY KEY, name TEXT, extend BLOB, " + "code REAL, years UNLIMIT INT, ment ASSET, ments ASSETS)."), + "CREATE TABLE IF NOT EXISTS *EST (*d INT PRIMARY KEY, *ame TEXT, " + "***end BLOB, *ode REAL, **ars UNLIMIT INT, *ent ASSET, **nts ASSETS)"); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0040, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::AnonySql("CREATE TABLE TEST (id INT PRIMARY KEY, name TEXT, " + "extend BLOB, code REAL, years UNLIMITED INT, ment ASSET, ments ASSETS)."), + "CREATE TABLE *EST (*d INT PRIMARY KEY, *ame TEXT, " + "***end BLOB, *ode REAL, **ars UNLIMITED INT, *ent ASSET, **nts ASSETS)"); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0041, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::AnonySql("DROP TABLE IF EXISTS table1;"), "DROP TABLE IF EXISTS ***le1;"); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0042, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::AnonySql("DROP TABLE table1;"), "DROP TABLE ***le1;"); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0043, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::AnonySql("DROP DATABASE IF EXISTS name1;"), "DROP DATABASE IF EXISTS **me1;"); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0044, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::AnonySql("DROP DATABASE name2;"), "DROP DATABASE **me2;"); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0045, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::AnonySql("PRAGMA version = 3"), "PRAGMA ****ion = *"); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0046, TestSize.Level1) +{ + EXPECT_EQ( + SqliteUtils::AnonySql("ALTER TABLE test ADD COLUMN name TEXT;"), "ALTER TABLE *est ADD COLUMN *ame TEXT;"); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0047, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::AnonySql("CREATE TABLE TEST (id INT PRIMARY KEY, name TEXT," + " extend BLOB, code REAL, years UNLIMITED INT, ment ASSET, ments ASSETS)."), + "CREATE TABLE *EST (*d INT PRIMARY KEY, *ame TEXT, " + "***end BLOB, *ode REAL, **ars UNLIMITED INT, *ent ASSET, **nts ASSETS)"); +} + +HWTEST_F(SqliteUtilsTest, SqliteUtils_Test_0048, TestSize.Level1) +{ + EXPECT_EQ(SqliteUtils::AnonySql("ALTER TABLE table DROP COLUMN column;"), "ALTER TABLE **ble DROP COLUMN ***umn;"); } \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index c219bebd..7abcf717 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -145,6 +145,8 @@ target_link_libraries(DataObjectTest ${links} gtest_main gcov data_object distri target_include_directories(DataObjectTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../data_object/frameworks/innerkitsimpl/include/adaptor) target_include_directories(DataObjectTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../data_object/frameworks/innerkitsimpl/include/common) target_include_directories(DataObjectTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../data_object/frameworks/innerkitsimpl/include/communicator) +target_include_directories(DataObjectTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../data_object/frameworks/jskitsimpl/include/adaptor) +target_include_directories(DataObjectTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../data_object/frameworks/jskitsimpl/include/common) target_include_directories(DataObjectTest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../data_object/frameworks/innerkitsimpl/test/unittest/mock/include) #************************************************DataObjectTest end************************************************# diff --git a/udmf/framework/innerkitsimpl/common/unified_meta.cpp b/udmf/framework/innerkitsimpl/common/unified_meta.cpp index 51f5641c..8aa87690 100644 --- a/udmf/framework/innerkitsimpl/common/unified_meta.cpp +++ b/udmf/framework/innerkitsimpl/common/unified_meta.cpp @@ -500,7 +500,9 @@ static constexpr UtdType UTD_TYPES[] = { { ART_IMAGE, "ART_IMAGE", "com.aol.art-image" }, { CONTENT_FORM, "CONTENT_FORM", "general.content-form" }, { M4P_AUDIO, "M4P_AUDIO", "com.apple.m4p-audio" }, - { AC3_AUDIO, "AC3_AUDIO", "general.ac3-audio" } + { AC3_AUDIO, "AC3_AUDIO", "general.ac3-audio" }, + { OPENHARMONY_HSP, "OPENHARMONY_HSP", "openharmony.hsp" }, + { OPENHARMONY_HAR, "OPENHARMONY_HAR", "openharmony.har" } }; namespace UtdUtils { diff --git a/udmf/framework/innerkitsimpl/data/preset_type_descriptors.cpp b/udmf/framework/innerkitsimpl/data/preset_type_descriptors.cpp index d948cba1..e9e47245 100644 --- a/udmf/framework/innerkitsimpl/data/preset_type_descriptors.cpp +++ b/udmf/framework/innerkitsimpl/data/preset_type_descriptors.cpp @@ -3287,6 +3287,20 @@ void PresetTypeDescriptors::InitDescriptors() {"audio/ac3"}, "Audio Codec 3 File Format", REFERENCE_URL, + ""}, + {"openharmony.hsp", + {"openharmony.package"}, + {".hsp"}, + {}, + "Harmony Shared Package", + REFERENCE_URL, + ""}, + {"openharmony.har", + {"openharmony.package"}, + {".har"}, + {}, + "Harmony Archive", + REFERENCE_URL, ""} }; }; diff --git a/udmf/framework/jskitsimpl/common/napi_data_utils.cpp b/udmf/framework/jskitsimpl/common/napi_data_utils.cpp index fdf87e13..8f0306fd 100644 --- a/udmf/framework/jskitsimpl/common/napi_data_utils.cpp +++ b/udmf/framework/jskitsimpl/common/napi_data_utils.cpp @@ -556,6 +556,16 @@ bool NapiDataUtils::IsNull(napi_env env, napi_value value) return false; } +bool NapiDataUtils::IsUndefinedOrNull(napi_env env, napi_value value) +{ + napi_valuetype type = napi_undefined; + napi_status status = napi_typeof(env, value, &type); + if (status == napi_ok && (type == napi_undefined || type == napi_null)) { + return true; + } + return false; +} + napi_value NapiDataUtils::DefineClass(napi_env env, const std::string &name, const napi_property_descriptor *properties, size_t count, napi_callback newcb) { diff --git a/udmf/framework/jskitsimpl/data/file_napi.cpp b/udmf/framework/jskitsimpl/data/file_napi.cpp index 84b762a0..bcc65eab 100644 --- a/udmf/framework/jskitsimpl/data/file_napi.cpp +++ b/udmf/framework/jskitsimpl/data/file_napi.cpp @@ -95,9 +95,11 @@ napi_value FileNapi::SetDetails(napi_env env, napi_callback_info info) auto input = [env, ctxt, &details](size_t argc, napi_value *argv) { ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::E_INVALID_PARAMETERS, "Parameter error: Mandatory parameters are left unspecified"); - ctxt->status = NapiDataUtils::GetValue(env, argv[0], details); - ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, - Status::E_INVALID_PARAMETERS, "Parameter error: parameter details type must be Record"); + if (!NapiDataUtils::IsUndefinedOrNull(env, argv[0])) { + ctxt->status = NapiDataUtils::GetValue(env, argv[0], details); + ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, + Status::E_INVALID_PARAMETERS, "Parameter error: parameter details type must be Record"); + } }; ctxt->GetCbInfoSync(env, info, input); ASSERT_ERR(ctxt->env, ctxt->status == napi_ok, Status::E_ERROR, ctxt->error); diff --git a/udmf/framework/jskitsimpl/data/html_napi.cpp b/udmf/framework/jskitsimpl/data/html_napi.cpp index 57730939..49e43b8c 100644 --- a/udmf/framework/jskitsimpl/data/html_napi.cpp +++ b/udmf/framework/jskitsimpl/data/html_napi.cpp @@ -98,9 +98,11 @@ napi_value HtmlNapi::SetPlainContent(napi_env env, napi_callback_info info) auto input = [env, ctxt, &plainContent](size_t argc, napi_value *argv) { ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::E_INVALID_PARAMETERS, "Parameter error: Mandatory parameters are left unspecified"); - ctxt->status = NapiDataUtils::GetValue(env, argv[0], plainContent); - ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, - Status::E_INVALID_PARAMETERS, "Parameter error: parameter plainContent type must be string"); + if (!NapiDataUtils::IsUndefinedOrNull(env, argv[0])) { + ctxt->status = NapiDataUtils::GetValue(env, argv[0], plainContent); + ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, + Status::E_INVALID_PARAMETERS, "Parameter error: parameter plainContent type must be string"); + } }; ctxt->GetCbInfoSync(env, info, input); ASSERT_ERR(ctxt->env, ctxt->status == napi_ok, Status::E_ERROR, ctxt->error); diff --git a/udmf/framework/jskitsimpl/data/link_napi.cpp b/udmf/framework/jskitsimpl/data/link_napi.cpp index e27ff133..641defef 100644 --- a/udmf/framework/jskitsimpl/data/link_napi.cpp +++ b/udmf/framework/jskitsimpl/data/link_napi.cpp @@ -132,9 +132,11 @@ napi_value LinkNapi::SetDescription(napi_env env, napi_callback_info info) auto input = [env, ctxt, &description](size_t argc, napi_value *argv) { ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::E_INVALID_PARAMETERS, "Parameter error: Mandatory parameters are left unspecified"); - ctxt->status = NapiDataUtils::GetValue(env, argv[0], description); - ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, - Status::E_INVALID_PARAMETERS, "Parameter error: parameter description type must be string"); + if (!NapiDataUtils::IsUndefinedOrNull(env, argv[0])) { + ctxt->status = NapiDataUtils::GetValue(env, argv[0], description); + ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, + Status::E_INVALID_PARAMETERS, "Parameter error: parameter description type must be string"); + } }; ctxt->GetCbInfoSync(env, info, input); ASSERT_ERR(ctxt->env, ctxt->status == napi_ok, Status::E_ERROR, ctxt->error); diff --git a/udmf/framework/jskitsimpl/data/plain_text_napi.cpp b/udmf/framework/jskitsimpl/data/plain_text_napi.cpp index 73ba739e..9ba459fd 100644 --- a/udmf/framework/jskitsimpl/data/plain_text_napi.cpp +++ b/udmf/framework/jskitsimpl/data/plain_text_napi.cpp @@ -131,9 +131,11 @@ napi_value PlainTextNapi::SetAbstract(napi_env env, napi_callback_info info) auto input = [env, ctxt, &abstract](size_t argc, napi_value *argv) { ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::E_INVALID_PARAMETERS, "Parameter error: Mandatory parameters are left unspecified"); - ctxt->status = NapiDataUtils::GetValue(env, argv[0], abstract); - ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, - Status::E_INVALID_PARAMETERS, "Parameter error: parameter abstract type must be string"); + if (!NapiDataUtils::IsUndefinedOrNull(env, argv[0])) { + ctxt->status = NapiDataUtils::GetValue(env, argv[0], abstract); + ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, + Status::E_INVALID_PARAMETERS, "Parameter error: parameter abstract type must be string"); + } }; ctxt->GetCbInfoSync(env, info, input); ASSERT_ERR(ctxt->env, ctxt->status == napi_ok, Status::E_ERROR, ctxt->error); diff --git a/udmf/framework/jskitsimpl/data/text_napi.cpp b/udmf/framework/jskitsimpl/data/text_napi.cpp index 38efd69e..fe97fea2 100644 --- a/udmf/framework/jskitsimpl/data/text_napi.cpp +++ b/udmf/framework/jskitsimpl/data/text_napi.cpp @@ -94,9 +94,11 @@ napi_value TextNapi::SetDetails(napi_env env, napi_callback_info info) auto input = [env, ctxt, &details](size_t argc, napi_value *argv) { ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::E_INVALID_PARAMETERS, "Parameter error: Mandatory parameters are left unspecified"); - ctxt->status = NapiDataUtils::GetValue(env, argv[0], details); - ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, - Status::E_INVALID_PARAMETERS, "Parameter error: parameter details type must be Record"); + if (!NapiDataUtils::IsUndefinedOrNull(env, argv[0])) { + ctxt->status = NapiDataUtils::GetValue(env, argv[0], details); + ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, + Status::E_INVALID_PARAMETERS, "Parameter error: parameter details type must be Record"); + } }; ctxt->GetCbInfoSync(env, info, input); ASSERT_ERR(ctxt->env, ctxt->status == napi_ok, Status::E_ERROR, ctxt->error); diff --git a/udmf/framework/jskitsimpl/data/unified_data_channel_napi.cpp b/udmf/framework/jskitsimpl/data/unified_data_channel_napi.cpp index 65c21490..b942b8b9 100644 --- a/udmf/framework/jskitsimpl/data/unified_data_channel_napi.cpp +++ b/udmf/framework/jskitsimpl/data/unified_data_channel_napi.cpp @@ -227,7 +227,6 @@ napi_value UnifiedDataChannelNapi::DeleteData(napi_env env, napi_callback_info i }; auto output = [env, ctxt](napi_value &result) { - ASSERT_WITH_ERRCODE(ctxt, !ctxt->unifiedDataSet.empty(), E_ERROR, "unifiedDataSet is empty!"); ctxt->status = napi_create_array_with_length(env, ctxt->unifiedDataSet.size(), &ctxt->output); ASSERT_WITH_ERRCODE(ctxt, ctxt->status == napi_ok, E_ERROR, "napi_create_array_with_length failed!"); int index = 0; diff --git a/udmf/framework/jskitsimpl/data/unified_data_napi.cpp b/udmf/framework/jskitsimpl/data/unified_data_napi.cpp index 4c9b7b4f..9c9fb521 100644 --- a/udmf/framework/jskitsimpl/data/unified_data_napi.cpp +++ b/udmf/framework/jskitsimpl/data/unified_data_napi.cpp @@ -76,6 +76,10 @@ napi_value UnifiedDataNapi::New(napi_env env, napi_callback_info info) UnifiedDataPropertiesNapi* propertiesNapi = nullptr; uData->propertyRef_ = NewWithRef(env, argc, argv, reinterpret_cast(&propertiesNapi), UnifiedDataPropertiesNapi::Constructor(env)); + if (propertiesNapi == nullptr) { + LOG_ERROR(UDMF_KITS_NAPI, "new UnifiedDataPropertiesNapi failed!"); + return nullptr; + } uData->value_ = std::make_shared(propertiesNapi->value_); if (uRecord) { uData->value_->AddRecord(uRecord->value_); diff --git a/udmf/framework/jskitsimpl/data/unified_data_properties_napi.cpp b/udmf/framework/jskitsimpl/data/unified_data_properties_napi.cpp index 4927fed5..9e88b570 100644 --- a/udmf/framework/jskitsimpl/data/unified_data_properties_napi.cpp +++ b/udmf/framework/jskitsimpl/data/unified_data_properties_napi.cpp @@ -137,7 +137,8 @@ napi_value UnifiedDataPropertiesNapi::GetShareOptions(napi_env env, napi_callbac auto properties = GetPropertiesNapi(env, info, ctxt); ASSERT_ERR(ctxt->env, (properties != nullptr && properties->value_ != nullptr), Status::E_ERROR, "invalid object!"); - ctxt->status = NapiDataUtils::SetValue(env, properties->value_->shareOptions, ctxt->output); + ctxt->status = NapiDataUtils::SetValue(env, + properties->value_->shareOptions == CROSS_DEVICE ? CROSS_APP : properties->value_->shareOptions, ctxt->output); ASSERT_ERR(ctxt->env, ctxt->status == napi_ok, Status::E_ERROR, "set ShareOptions failed"); return ctxt->output; } diff --git a/udmf/framework/jskitsimpl/unittest/UdmfPromiseJsTest.js b/udmf/framework/jskitsimpl/unittest/UdmfPromiseJsTest.js index 833e5875..3826e7b6 100644 --- a/udmf/framework/jskitsimpl/unittest/UdmfPromiseJsTest.js +++ b/udmf/framework/jskitsimpl/unittest/UdmfPromiseJsTest.js @@ -31,6 +31,7 @@ describe('UdmfPromiseJSTest', function () { const optionsValid = { intention: 'DataHub', }; const optionsInValidIntention = { intention: 'Drag', }; const optionsInValidKey = { key: 'udmf://drag/com.test.demo/123456789', }; + const optionsValidKey = { key: 'udmf://DataHub/com.test.demo/123456789', }; const optionsInValidAll = { intention: 'DataHub', key: 'udmf://drag/com.test.demo/123456789' }; const unifiedData01 = new UDC.UnifiedData(gPlainText1); const unifiedData02 = new UDC.UnifiedData(gPlainText2); @@ -409,4 +410,31 @@ describe('UdmfPromiseJSTest', function () { } console.info(TAG, 'end'); }); + + /** + * @tc.name UdmfDeleteDataPromiseEmptyDataTest + * @tc.desc Test Js Api deleteData with empty data + * @tc.type: FUNC + * @tc.require: issueNumber + */ + it('UdmfDeleteDataPromiseEmptyDataTest', 0, async function (done) { + const TAG = 'UdmfDeleteDataPromiseEmptyDataTest:'; + console.info(TAG, 'start'); + try { + UDC.deleteData(optionsValidKey).then((data) => { + console.error(TAG, 'delete data success!'); + expect(data.length).assertEqual(0); + done(); + }).catch(() => { + console.error(TAG, 'Unreachable code!'); + expect(null).assertFail(); + done(); + }); + } catch (e) { + console.error(TAG, 'Unreachable code!'); + expect(null).assertFail(); + done(); + } + console.info(TAG, 'end'); + }); }); \ No newline at end of file diff --git a/udmf/framework/ndkimpl/data/udmf.cpp b/udmf/framework/ndkimpl/data/udmf.cpp index b3ccc75d..cfbd688e 100644 --- a/udmf/framework/ndkimpl/data/udmf.cpp +++ b/udmf/framework/ndkimpl/data/udmf.cpp @@ -761,6 +761,7 @@ Udmf_ShareOption OH_UdmfProperty_GetShareOption(OH_UdmfProperty* properties) case ShareOptions::IN_APP: return Udmf_ShareOption::SHARE_OPTIONS_IN_APP; case ShareOptions::CROSS_APP: + case ShareOptions::CROSS_DEVICE: return Udmf_ShareOption::SHARE_OPTIONS_CROSS_APP; default: return Udmf_ShareOption::SHARE_OPTIONS_INVALID; diff --git a/udmf/interfaces/innerkits/common/unified_meta.h b/udmf/interfaces/innerkits/common/unified_meta.h index c376a0d9..2926b499 100644 --- a/udmf/interfaces/innerkits/common/unified_meta.h +++ b/udmf/interfaces/innerkits/common/unified_meta.h @@ -527,6 +527,8 @@ enum UDType : int32_t { CONTENT_FORM, M4P_AUDIO, AC3_AUDIO, + OPENHARMONY_HSP, + OPENHARMONY_HAR, UD_BUTT }; @@ -575,6 +577,7 @@ static const std::unordered_map JS_UD_INTENTION_NAME_MAP { enum ShareOptions : int32_t { IN_APP, CROSS_APP, + CROSS_DEVICE, SHARE_OPTIONS_BUTT, }; diff --git a/udmf/interfaces/innerkits/data/unified_data_properties.h b/udmf/interfaces/innerkits/data/unified_data_properties.h index 93e7dc5c..0def095c 100644 --- a/udmf/interfaces/innerkits/data/unified_data_properties.h +++ b/udmf/interfaces/innerkits/data/unified_data_properties.h @@ -24,7 +24,7 @@ class API_EXPORT UnifiedDataProperties { public: std::string tag; AAFwk::WantParams extras; - ShareOptions shareOptions = CROSS_APP; + ShareOptions shareOptions = CROSS_DEVICE; std::int64_t timestamp; bool isRemote; }; diff --git a/udmf/interfaces/jskits/common/napi_data_utils.h b/udmf/interfaces/jskits/common/napi_data_utils.h index aa9f7018..091336d1 100644 --- a/udmf/interfaces/jskits/common/napi_data_utils.h +++ b/udmf/interfaces/jskits/common/napi_data_utils.h @@ -112,6 +112,9 @@ public: static bool IsTypeForNapiValue(napi_env env, napi_value param, napi_valuetype expectType); static bool IsNull(napi_env env, napi_value value); + + static bool IsUndefinedOrNull(napi_env env, napi_value value); + /* 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); -- Gitee