diff --git a/BUILD.gn b/BUILD.gn index dd401f98b069757fe4ad5efe524c432583bd8ec8..5f01c0b986cd1c1cb6523f5024c217e940cc959a 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -25,7 +25,6 @@ group("build_native_test") { deps = [ "frameworks/innerkitsimpl/distributeddatafwk/test:unittest", "frameworks/libs/distributeddb/test:unittest", - "frameworks/libs/distributeddb/test/moduletest:moduletest", ] if (!defined(global_parts_info.distributeddatamgr_arkdata_database_core)) { deps += @@ -52,9 +51,54 @@ group("fuzztest") { deps = [] deps += [ "test/fuzztest/blob_fuzzer:fuzztest", - "test/fuzztest/devicekvstore_fuzzer:fuzztest", + "test/fuzztest/devicekvstorecapenabled_fuzzer:fuzztest", + "test/fuzztest/devicekvstorecaprange_fuzzer:fuzztest", + "test/fuzztest/devicekvstoreget_fuzzer:fuzztest", + "test/fuzztest/devicekvstoregetcount_fuzzer:fuzztest", + "test/fuzztest/devicekvstoregetcountquery_fuzzer:fuzztest", + "test/fuzztest/devicekvstoregetentriesprefix_fuzzer:fuzztest", + "test/fuzztest/devicekvstoregetentriesquery_fuzzer:fuzztest", + "test/fuzztest/devicekvstoregetresultset_fuzzer:fuzztest", + "test/fuzztest/devicekvstoregetresultsetprefix_fuzzer:fuzztest", + "test/fuzztest/devicekvstoregetresultsetquery_fuzzer:fuzztest", + "test/fuzztest/devicekvstoreput_fuzzer:fuzztest", + "test/fuzztest/devicekvstoreputbatch_fuzzer:fuzztest", + "test/fuzztest/devicekvstoreremovedevicedata_fuzzer:fuzztest", + "test/fuzztest/devicekvstoresecuritylevel_fuzzer:fuzztest", + "test/fuzztest/devicekvstoresubscribe_fuzzer:fuzztest", + "test/fuzztest/devicekvstoresubscribequery_fuzzer:fuzztest", + "test/fuzztest/devicekvstoresynccallback_fuzzer:fuzztest", + "test/fuzztest/devicekvstoresyncdelay_fuzzer:fuzztest", + "test/fuzztest/devicekvstoresyncparam_fuzzer:fuzztest", + "test/fuzztest/devicekvstoresyncquery_fuzzer:fuzztest", + "test/fuzztest/devicekvstoreunsubscribequery_fuzzer:fuzztest", "test/fuzztest/distributedkvdatamanager_fuzzer:fuzztest", - "test/fuzztest/singlekvstore_fuzzer:fuzztest", + "test/fuzztest/kvutil_fuzzer:fuzztest", + "test/fuzztest/singlekvstoreasyncget_fuzzer:fuzztest", + "test/fuzztest/singlekvstoreasyncgetentries_fuzzer:fuzztest", + "test/fuzztest/singlekvstorecapabilityenabled_fuzzer:fuzztest", + "test/fuzztest/singlekvstorecapabilityrange_fuzzer:fuzztest", + "test/fuzztest/singlekvstoreentriesprefix_fuzzer:fuzztest", + "test/fuzztest/singlekvstoreentriesquery_fuzzer:fuzztest", + "test/fuzztest/singlekvstoreget_fuzzer:fuzztest", + "test/fuzztest/singlekvstoregetcount_fuzzer:fuzztest", + "test/fuzztest/singlekvstoregetcountquery_fuzzer:fuzztest", + "test/fuzztest/singlekvstoreput_fuzzer:fuzztest", + "test/fuzztest/singlekvstoreremovedata_fuzzer:fuzztest", + "test/fuzztest/singlekvstoreresultset_fuzzer:fuzztest", + "test/fuzztest/singlekvstoreresultsetprefix_fuzzer:fuzztest", + "test/fuzztest/singlekvstoreresultsetquery_fuzzer:fuzztest", + "test/fuzztest/singlekvstoresecurity_fuzzer:fuzztest", + "test/fuzztest/singlekvstoresubscribe_fuzzer:fuzztest", + "test/fuzztest/singlekvstoresubscribequery_fuzzer:fuzztest", + "test/fuzztest/singlekvstoresynccallback_fuzzer:fuzztest", + "test/fuzztest/singlekvstoresynccallbackquery_fuzzer:fuzztest", + "test/fuzztest/singlekvstoresyncdelay_fuzzer:fuzztest", + "test/fuzztest/singlekvstoresyncparam_fuzzer:fuzztest", + "test/fuzztest/singlekvstoresyncpull_fuzzer:fuzztest", + "test/fuzztest/singlekvstoresyncpush_fuzzer:fuzztest", + "test/fuzztest/singlekvstoresyncquery_fuzzer:fuzztest", + "test/fuzztest/singlekvstoreunsubscribequery_fuzzer:fuzztest", "test/fuzztest/taskscheduler_fuzzer:fuzztest", "test/fuzztest/typesutil_fuzzer:fuzztest", ] diff --git a/bundle.json b/bundle.json index 70df515d57dc84763e2a143708c519e3923df4bf..fd1360f12b76883970617c3c7231d4aa1d662d0c 100644 --- a/bundle.json +++ b/bundle.json @@ -67,6 +67,7 @@ "c_utils", "device_manager", "dmsfwk", + "eventhandler", "hilog", "hisysevent", "hitrace", @@ -75,13 +76,15 @@ "json", "jsoncpp", "napi", + "runtime_core", "safwk", "samgr", "file_api", "zlib", "data_share", "openssl", - "sqlite" + "sqlite", + "bounds_checking_function" ] }, "build": { @@ -94,7 +97,9 @@ "//foundation/distributeddatamgr/kv_store/interfaces/jskits/distributedkvstore:build_module", "//foundation/distributeddatamgr/kv_store/kvstoremock/interfaces/jskits/distributedkvstore:build_module", "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata:distributeddata_client_sync", - "//foundation/distributeddatamgr/kv_store/databaseutils:database_utils" + "//foundation/distributeddatamgr/kv_store/databaseutils:database_utils", + "//foundation/distributeddatamgr/kv_store/kvstoremock/interfaces/mock:build_module", + "//foundation/distributeddatamgr/kv_store/frameworks/ets/taihe/kv_store:distributedkvstore_ani_pack" ], "inner_kits": [ { @@ -320,6 +325,9 @@ ], "header_base": "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb/include" } + }, + { + "name": "//foundation/distributeddatamgr/kv_store/frameworks/ets/taihe/kv_store:distributedkvstore_ani_pack" } ], "test": [ diff --git a/frameworks/cj/include/distributed_kv_store_ffi.h b/frameworks/cj/include/distributed_kv_store_ffi.h new file mode 100644 index 0000000000000000000000000000000000000000..248b7131be9171cfa1d904708ab831f1039d2b2d --- /dev/null +++ b/frameworks/cj/include/distributed_kv_store_ffi.h @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DISTRIBUTED_KV_STORE_FFI_H +#define DISTRIBUTED_KV_STORE_FFI_H + +#include +#include "napi_base_context.h" +#include "ffi_remote_data.h" +#include "cj_common_ffi.h" +#include "data_query.h" + +#include "distributed_kv_store_log.h" +#include "distributed_kv_store_impl.h" + +namespace OHOS { +namespace DistributedKVStore { + +extern "C" { + FFI_EXPORT int64_t FfiOHOSDistributedKVStoreCreateKVManager(const char* boudleName, + OHOS::AbilityRuntime::Context* context); + + FFI_EXPORT int64_t FfiOHOSDistributedKVStoreGetKVStore(int64_t id, const char* storeId, + CJOptions options, int32_t* errCode); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreCloseKVStore(int64_t id, const char* appId, const char* storeId); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreDeleteKVStore(int64_t id, const char* appId, const char* storeId); + + FFI_EXPORT CArrStr FfiOHOSDistributedKVStoreGetAllKVStoreId(int64_t id, const char* appId, int32_t* errCode); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreOnDistributedDataServiceDie(int64_t id, void (*callbackId)()); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreOffDistributedDataServiceDie(int64_t id, void (*callbackId)()); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreOffAllDistributedDataServiceDie(int64_t id); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStorePut(int64_t id, const char* key, ValueType value); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStorePutBatch(int64_t id, const CArrEntry cArrEntry); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStoreDelete(int64_t id, const char* key); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStoreDeleteBatch(int64_t id, const CArrStr cArrStr); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStoreRemoveDeviceData(int64_t id, const char* deviceId); + + FFI_EXPORT ValueType FfiOHOSDistributedKVStoreSingleKVStoreGet(int64_t id, const char* key, int32_t* errCode); + + FFI_EXPORT CArrEntry FfiOHOSDistributedKVStoreSingleKVStoreGetEntriesByQuery(int64_t id, + int64_t queryId, int32_t* errCode); + + FFI_EXPORT CArrEntry FfiOHOSDistributedKVStoreSingleKVStoreGetEntriesByString(int64_t id, + const char* prefix, int32_t* errCode); + + FFI_EXPORT int64_t FfiOHOSDistributedKVStoreSingleKVStoreGetResultSetByString(int64_t id, + const char* keyPrefix, int32_t* errCode); + + FFI_EXPORT int64_t FfiOHOSDistributedKVStoreSingleKVStoreGetResultSetByQuery(int64_t id, + int64_t queryId, int32_t* errCode); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStoreCloseResultSet(int64_t id, int64_t resultSetId); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStoreGetResultSize(int64_t id, + int64_t queryId, int32_t* errCode); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStoreBackup(int64_t id, const char* file); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStoreRestore(int64_t id, const char* file); + + FFI_EXPORT CStringNum FfiOHOSDistributedKVStoreSingleKVStoreDeleteBackup(int64_t id, + const CArrStr cArrStr, int32_t* errCode); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStoreStartTransaction(int64_t id); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStoreCommit(int64_t id); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStoreRollback(int64_t id); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStoreEnableSync(int64_t id, bool enabled); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStoreSetSyncRange(int64_t id, const CArrStr localLabels, + const CArrStr remoteSupportLabels); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStoreSetSyncParam(int64_t id, uint32_t defaultAllowedDelayMs); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStoreSync(int64_t id, const CArrStr deviceIds, uint8_t mode, + uint32_t delayMs); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStoreSyncByQuery(int64_t id, const CArrStr deviceIds, + int64_t queryId, uint8_t mode, uint32_t delayMs); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStoreOnDataChange(int64_t id, uint8_t type, + void (*callbackId)(const CChangeNotification valueRef)); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStoreOffDataChange(int64_t id, + void (*callbackId)(const CChangeNotification valueRef)); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStoreOffAllDataChange(int64_t id); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStoreOnSyncComplete(int64_t id, + void (*callbackId)(const CStringNum valueRef)); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStoreOffAllSyncComplete(int64_t id); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreSingleKVStoreGetSecurityLevel(int64_t id, int32_t* errCode); + + FFI_EXPORT int64_t FfiOHOSDistributedKVStoreQueryConstructor(); + + FFI_EXPORT void FfiOHOSDistributedKVStoreQueryReset(int64_t id); + + FFI_EXPORT void FfiOHOSDistributedKVStoreQueryEqualTo(int64_t id, const char* field, ValueType value); + + FFI_EXPORT void FfiOHOSDistributedKVStoreQueryNotEqualTo(int64_t id, const char* field, ValueType value); + + FFI_EXPORT void FfiOHOSDistributedKVStoreQueryGreaterThan(int64_t id, const char* field, ValueType value); + + FFI_EXPORT void FfiOHOSDistributedKVStoreQueryLessThan(int64_t id, const char* field, ValueType value); + + FFI_EXPORT void FfiOHOSDistributedKVStoreQueryGreaterThanOrEqualTo(int64_t id, const char* field, ValueType value); + + FFI_EXPORT void FfiOHOSDistributedKVStoreQueryLessThanOrEqualTo(int64_t id, const char* field, ValueType value); + + FFI_EXPORT void FfiOHOSDistributedKVStoreQueryIsNull(int64_t id, const char* field); + + FFI_EXPORT void FfiOHOSDistributedKVStoreQueryInNumber(int64_t id, const char* field, const CArrNumber valueList); + + FFI_EXPORT void FfiOHOSDistributedKVStoreQueryInString(int64_t id, const char* field, const CArrStr valueList); + + FFI_EXPORT void FfiOHOSDistributedKVStoreQueryNotInNumber(int64_t id, const char* field, + const CArrNumber valueList); + + FFI_EXPORT void FfiOHOSDistributedKVStoreQueryNotInString(int64_t id, const char* field, const CArrStr valueList); + + FFI_EXPORT void FfiOHOSDistributedKVStoreQueryLike(int64_t id, const char* field, const char* value); + + FFI_EXPORT void FfiOHOSDistributedKVStoreQueryUnlike(int64_t id, const char* field, const char* value); + + FFI_EXPORT void FfiOHOSDistributedKVStoreQueryAnd(int64_t id); + + FFI_EXPORT void FfiOHOSDistributedKVStoreQueryOr(int64_t id); + + FFI_EXPORT void FfiOHOSDistributedKVStoreQueryOrderByAsc(int64_t id, const char* field); + + FFI_EXPORT void FfiOHOSDistributedKVStoreQueryOrderByDesc(int64_t id, const char* field); + + FFI_EXPORT void FfiOHOSDistributedKVStoreQueryLimit(int64_t id, int32_t total, int32_t offset); + + FFI_EXPORT void FfiOHOSDistributedKVStoreQueryIsNotNull(int64_t id, const char* field); + + FFI_EXPORT void FfiOHOSDistributedKVStoreQueryBeginGroup(int64_t id); + + FFI_EXPORT void FfiOHOSDistributedKVStoreQueryEndGroup(int64_t id); + + FFI_EXPORT void FfiOHOSDistributedKVStoreQueryPrefixKey(int64_t id, const char* prefix); + + FFI_EXPORT void FfiOHOSDistributedKVStoreQuerySetSuggestIndex(int64_t id, const char* index); + + FFI_EXPORT void FfiOHOSDistributedKVStoreQueryDeviceId(int64_t id, const char* deviceId); + + FFI_EXPORT const char* FfiOHOSDistributedKVStoreQueryGetSqlLike(int64_t id); + + FFI_EXPORT ValueType FfiOHOSDistributedKVStoreDeviceKVStoreGet(int64_t id, const char* deviceId, const char* key, + int32_t* errCode); + + FFI_EXPORT CArrEntry FfiOHOSDistributedKVStoreDeviceKVStoreGetEntries(int64_t id, const char* deviceId, + const char* keyPrefix, int32_t* errCode); + + FFI_EXPORT CArrEntry FfiOHOSDistributedKVStoreDeviceKVStoreGetEntriesQuery(int64_t id, const char* deviceId, + int64_t queryId, int32_t* errCode); + + FFI_EXPORT int64_t FfiOHOSDistributedKVStoreDeviceKVStoreGetResultSet(int64_t id, const char* deviceId, + const char* keyPrefix, int32_t* errCode); + + FFI_EXPORT int64_t FfiOHOSDistributedKVStoreDeviceKVStoreGetResultSetQuery(int64_t id, const char* deviceId, + int64_t queryId, int32_t* errCode); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreDeviceKVStoreGetResultSize(int64_t id, const char* deviceId, + int64_t queryId, int32_t* errCode); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreKVStoreResultSetGetCount(int64_t id); + + FFI_EXPORT int32_t FfiOHOSDistributedKVStoreKVStoreResultSetGetPosition(int64_t id); + + FFI_EXPORT bool FfiOHOSDistributedKVStoreKVStoreResultSetMoveToFirst(int64_t id); + + FFI_EXPORT bool FfiOHOSDistributedKVStoreKVStoreResultSetMoveToLast(int64_t id); + + FFI_EXPORT bool FfiOHOSDistributedKVStoreKVStoreResultSetMoveToNext(int64_t id); + + FFI_EXPORT bool FfiOHOSDistributedKVStoreKVStoreResultSetMoveToPrevious(int64_t id); + + FFI_EXPORT bool FfiOHOSDistributedKVStoreKVStoreResultSetMove(int64_t id, int32_t offset); + + FFI_EXPORT bool FfiOHOSDistributedKVStoreKVStoreResultSetMoveToPosition(int64_t id, int32_t position); + + FFI_EXPORT bool FfiOHOSDistributedKVStoreKVStoreResultSetIsFirst(int64_t id); + + FFI_EXPORT bool FfiOHOSDistributedKVStoreKVStoreResultSetIsLast(int64_t id); + + FFI_EXPORT bool FfiOHOSDistributedKVStoreKVStoreResultSetIsBeforeFirst(int64_t id); + + FFI_EXPORT bool FfiOHOSDistributedKVStoreKVStoreResultSetIsAfterLast(int64_t id); + + FFI_EXPORT CEntry FfiOHOSDistributedKVStoreKVStoreResultSetGetEntry(int64_t id); + + FFI_EXPORT void FfiOHOSFreeCString(char* str); +} +} +} + +#endif \ No newline at end of file diff --git a/frameworks/cj/include/distributed_kv_store_impl.h b/frameworks/cj/include/distributed_kv_store_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..f9f0fb186dc454382594d600ea975e9b7b791605 --- /dev/null +++ b/frameworks/cj/include/distributed_kv_store_impl.h @@ -0,0 +1,394 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DISTRIBUTED_KV_STORE_IMPL_H +#define DISTRIBUTED_KV_STORE_IMPL_H + +#include +#include +#include "distributed_kv_data_manager.h" +#include "kvstore_death_recipient.h" +#include "distributed_kv_store_log.h" +#include "ability_context_impl.h" +#include "kvstore_result_set.h" + +namespace OHOS { +namespace DistributedKVStore { +using namespace OHOS::DistributedKv; +enum { + /* exported cj SubscribeType is (DistributedKv::SubscribeType-1) */ + SUBSCRIBE_LOCAL = 0, /* i.e. SubscribeType::SUBSCRIBE_TYPE_LOCAL-1 */ + SUBSCRIBE_REMOTE = 1, /* i.e. SubscribeType::SUBSCRIBE_TYPE_REMOTE-1 */ + SUBSCRIBE_LOCAL_REMOTE = 2, /* i.e. SubscribeType::SUBSCRIBE_TYPE_ALL-1 */ + SUBSCRIBE_COUNT = 3 +}; + +struct ContextParam { + std::string baseDir = ""; + std::string hapName = ""; + int32_t area = DistributedKv::Area::EL1; +}; + +struct CJFieldNode { + bool nullable; + char* defaultString; + int32_t type; +}; + +struct CJSchema { + CJFieldNode root; + char** indexes; + int32_t indexesSize; + int32_t mode; + int32_t skip; +}; + +struct CJOptions { + bool createIfMissing; + bool encrypt; + bool backup; + bool autoSync; + int32_t kvStoreType; + int32_t securityLevel; + CJSchema schema; +}; + +struct CArrByte { + u_int8_t* head; + int64_t size; +}; + +struct CArrStr { + char** head; + int64_t size; +}; + +struct CArrNumber { + int32_t* intList; + float* floatList; + double* doubleList; + int64_t size; + uint8_t tag; +}; + +struct ValueType { + char* string; + int32_t integer; + float flo; + CArrByte byteArray; + bool boolean; + double dou; + uint8_t tag; +}; + +struct CStringNum { + char** headChar; + int32_t* headNum; + int64_t size; +}; + +struct CEntry { + char *key; + ValueType value; +}; + +struct CArrEntry { + CEntry* head; + int64_t size; +}; + +struct CChangeNotification { + CArrEntry insertEntries; + CArrEntry updateEntries; + CArrEntry deleteEntries; + char* deviceId; +}; + +class CKvStoreResultSet : public OHOS::FFI::FFIData { +public: + OHOS::FFI::RuntimeType* GetRuntimeType() override + { + return GetClassType(); + } + + explicit CKvStoreResultSet(std::shared_ptr kvResultSet); + + std::shared_ptr GetKvStoreResultSet(); + + int32_t GetCount(); + + int32_t GetPosition(); + + bool MoveToFirst(); + + bool MoveToLast(); + + bool MoveToNext(); + + bool MoveToPrevious(); + + bool Move(int32_t offset); + + bool MoveToPosition(int32_t position); + + bool IsFirst(); + + bool IsLast(); + + bool IsBeforeFirst(); + + bool IsAfterLast(); + + CEntry GetEntry(); + +private: + std::shared_ptr kvResultSet; + friend class OHOS::FFI::RuntimeType; + friend class OHOS::FFI::TypeBase; + static OHOS::FFI::RuntimeType* GetClassType() + { + static OHOS::FFI::RuntimeType runtimeType = + OHOS::FFI::RuntimeType::Create("CKvStoreResultSet"); + return &runtimeType; + } +}; + +class CJKVManager : public OHOS::FFI::FFIData { +public: + OHOS::FFI::RuntimeType* GetRuntimeType() override + { + return GetClassType(); + } + + CJKVManager(); + CJKVManager(const char* boudleName, OHOS::AbilityRuntime::Context* context); + + uint64_t GetKVStore(const char* cStoreId, const CJOptions cjOptions, int32_t& errCode); + int32_t CloseKVStore(const char* appId, const char* storeId); + int32_t DeleteKVStore(const char* appId, const char* storeId); + CArrStr GetAllKVStoreId(const char* appId, int32_t& errCode); + int32_t OnDistributedDataServiceDie(void (*callbackId)()); + int32_t OffDistributedDataServiceDie(void (*callbackId)()); + int32_t OffAllDistributedDataServiceDie(); + +private: + class DeathRecipient : public DistributedKv::KvStoreDeathRecipient { + public: + DeathRecipient(void (*callbackId)(), const std::function& callbackRef); + virtual ~DeathRecipient() = default; + void OnRemoteDied() override; + void (*m_callbackId)(); + std::function m_callbackRef; + }; + DistributedKv::DistributedKvDataManager kvDataManager_ {}; + std::mutex deathMutex_ {}; + std::list> deathRecipient_; + std::string bundleName_ {}; + std::shared_ptr param_; + friend class OHOS::FFI::RuntimeType; + friend class OHOS::FFI::TypeBase; + static OHOS::FFI::RuntimeType* GetClassType() + { + static OHOS::FFI::RuntimeType runtimeType = OHOS::FFI::RuntimeType::Create("CJKVManager"); + return &runtimeType; + } +}; +class CQuery : public OHOS::FFI::FFIData { +public: + OHOS::FFI::RuntimeType* GetRuntimeType() override + { + return GetClassType(); + } + + CQuery() {}; + + const DistributedKv::DataQuery& GetDataQuery() const; + + void Reset(); + + void EqualTo(const std::string &field, ValueType &value); + + void NotEqualTo(const std::string &field, ValueType &value); + + void GreaterThan(const std::string &field, ValueType &value); + + void LessThan(const std::string &field, ValueType &value); + + void GreaterThanOrEqualTo(const std::string &field, ValueType &value); + + void LessThanOrEqualTo(const std::string &field, ValueType &value); + + void IsNull(const std::string &field); + + void InNumber(const std::string &field, const CArrNumber &valueList); + + void InString(const std::string &field, const CArrStr &valueList); + + void NotInNumber(const std::string &field, const CArrNumber &valueList); + + void NotInString(const std::string &field, const CArrStr &valueList); + + void Like(const std::string &field, const std::string &value); + + void Unlike(const std::string &field, const std::string &value); + + void And(); + + void Or(); + + void OrderByAsc(const std::string &field); + + void OrderByDesc(const std::string &field); + + void Limit(int32_t total, int32_t offset); + + void IsNotNull(const std::string &field); + + void BeginGroup(); + + void EndGroup(); + + void PrefixKey(const std::string &prefix); + + void SetSuggestIndex(const std::string &index); + + void DeviceId(const std::string &deviceId); + + const std::string GetSqlLike(); + +private: + DistributedKv::DataQuery query_; + friend class OHOS::FFI::RuntimeType; + friend class OHOS::FFI::TypeBase; + static OHOS::FFI::RuntimeType* GetClassType() + { + static OHOS::FFI::RuntimeType runtimeType = OHOS::FFI::RuntimeType::Create("CQuery"); + return &runtimeType; + } +}; + +class CJSingleKVStore : public OHOS::FFI::FFIData { +public: + OHOS::FFI::RuntimeType* GetRuntimeType() override + { + return GetClassType(); + } + + explicit CJSingleKVStore(const std::string& storeId); + + std::shared_ptr GetKvStorePtr(); + void SetKvStorePtr(std::shared_ptr kvStore); + void SetContextParam(std::shared_ptr param); + int32_t Put(const std::string &key, const ValueType &value); + int32_t PutBatch(const CArrEntry &cArrEntry); + int32_t Delete(const std::string &key); + int32_t DeleteBatch(const CArrStr &cArrStr); + int32_t RemoveDeviceData(const std::string &deviceId); + ValueType Get(const std::string &key, int32_t& errCode); + CArrEntry GetEntries(OHOS::sptr query, int32_t& errCode); + CArrEntry GetEntries(const std::string &keyPrefix, int32_t& errCode); + int64_t GetResultSetByString(const std::string &keyPrefix, int32_t& errCode); + int64_t GetResultSetByQuery(OHOS::sptr query, int32_t& errCode); + int32_t CloseResultSet(OHOS::sptr resultSet); + int32_t GetResultSize(OHOS::sptr query, int32_t& errCode); + int32_t Backup(const std::string &file); + int32_t Restore(const std::string &file); + CStringNum DeleteBackup(const CArrStr &cArrStr, int32_t& errCode); + int32_t StartTransaction(); + int32_t Commit(); + int32_t Rollback(); + int32_t EnableSync(bool enabled); + int32_t SetSyncRange(const CArrStr &localLabels, const CArrStr &remoteSupportLabels); + int32_t SetSyncParam(uint32_t defaultAllowedDelayMs); + int32_t Sync(const CArrStr deviceIds, uint8_t mode, uint32_t delayMs); + int32_t SyncByQuery(const CArrStr deviceIds, OHOS::sptr query, uint8_t mode, uint32_t delayMs); + int32_t OnDataChange(uint8_t type, void (*callbackId)(const CChangeNotification valueRef)); + int32_t OffDataChange(void (*callbackId)(const CChangeNotification valueRef)); + int32_t OffAllDataChange(); + int32_t OnSyncComplete(void (*callbackId)(const CStringNum valueRef)); + int32_t OffAllSyncComplete(); + int32_t GetSecurityLevel(int32_t& errCode); + +private: + class DataObserver : public DistributedKv::KvStoreObserver { + public: + DataObserver(void (*callbackId)(const CChangeNotification), + const std::function& callbackRef); + virtual ~DataObserver() = default; + void OnChange(const DistributedKv::ChangeNotification& notification) override; + void (*m_callbackId)(const CChangeNotification); + std::function m_callbackRef; + }; + class SyncObserver : public DistributedKv::KvStoreSyncCallback { + public: + SyncObserver(void (*callbackId)(const CStringNum), + const std::function)>& callbackRef); + virtual ~SyncObserver() = default; + void SyncCompleted(const std::map& results) override; + void (*m_callbackId)(const CStringNum); + std::function)> m_callbackRef; + }; + std::shared_ptr kvStore_ = nullptr; + std::string storeId_; + std::shared_ptr param_ = nullptr; + friend class OHOS::FFI::RuntimeType; + friend class OHOS::FFI::TypeBase; + static OHOS::FFI::RuntimeType* GetClassType() + { + static OHOS::FFI::RuntimeType runtimeType = + OHOS::FFI::RuntimeType::Create("CJSingleKVStore"); + return &runtimeType; + } + std::mutex listMutex_ {}; + std::list> dataObserver_[SUBSCRIBE_COUNT]; + std::list> syncObservers_; +}; +class CJDeviceKVStore : public CJSingleKVStore { +public: + OHOS::FFI::RuntimeType* GetRuntimeType() override + { + return GetClassType(); + } + + explicit CJDeviceKVStore(const std::string& storeId); + + ValueType Get(const std::string &deviceId, const std::string &key, int32_t& errCode); + + CArrEntry GetEntriesByDataQuery(DistributedKVStore::DataQuery dataQuery, int32_t& errCode); + + CArrEntry GetEntries(const std::string &deviceId, const std::string &keyPrefix, int32_t& errCode); + + CArrEntry GetEntries(const std::string &deviceId, OHOS::sptr query, int32_t& errCode); + + int64_t GetResultSet(const std::string &deviceId, const std::string &keyPrefix, int32_t& errCode); + + int64_t GetResultSetQuery(const std::string &deviceId, OHOS::sptr query, int32_t& errCode); + + int32_t GetResultSize(const std::string &deviceId, OHOS::sptr query, int32_t& errCode); + +private: + friend class OHOS::FFI::RuntimeType; + friend class OHOS::FFI::TypeBase; + static OHOS::FFI::RuntimeType* GetClassType() + { + static OHOS::FFI::RuntimeType runtimeType = + OHOS::FFI::RuntimeType::Create("CJDeviceKVStore"); + return &runtimeType; + } +}; +} +} // namespace OHOS::DistributedKVStore + +#endif \ No newline at end of file diff --git a/frameworks/cj/include/distributed_kv_store_log.h b/frameworks/cj/include/distributed_kv_store_log.h new file mode 100644 index 0000000000000000000000000000000000000000..e7e96a412d6b942ed207db01b197c709325e334c --- /dev/null +++ b/frameworks/cj/include/distributed_kv_store_log.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DISTRIBUTED_KV_STORE_LOG_H +#define DISTRIBUTED_KV_STORE_LOG_H + +#include "hilog/log.h" + +#undef LOG_DOMAIN +#undef LOG_TAG +#define LOG_DOMAIN 0xD002B25 +#define LOG_TAG "DistributedKVStoreCffi" + +#define LOGI(...) \ +if (HiLogIsLoggable(LOG_DOMAIN, LOG_TAG, LOG_INFO)) { \ + HILOG_INFO(LOG_CORE, ##__VA_ARGS__); \ +} + +#define LOGE(...) \ +if (HiLogIsLoggable(LOG_DOMAIN, LOG_TAG, LOG_ERROR)) { \ + HILOG_ERROR(LOG_CORE, __VA_ARGS__); \ +} + +#endif diff --git a/frameworks/cj/include/distributed_kv_store_utils.h b/frameworks/cj/include/distributed_kv_store_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..5156d016759c4c75d0da6b1f28d3f0fe2b4f165a --- /dev/null +++ b/frameworks/cj/include/distributed_kv_store_utils.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef DISTRIBUTED_KV_STORE_UTILS_H +#define DISTRIBUTED_KV_STORE_UTILS_H + +#include +#include +#include + +namespace OHOS { +namespace DistributedKVStore { + char* MallocCString(const std::string& origin); + void FreeCString(char* str); + enum CJErrorCode { + CJ_ERROR_PERMISSION_DENIED = 202, + + CJ_ERROR_INVALID_ARGUMENT = 401, + + CJ_ERROR_OVER_MAX_LIMITS = 15100001, + + CJ_ERROR_STORE_META_CHANGED = 15100002, + + CJ_ERROR_CRYPT_ERROR = 15100003, + + CJ_ERROR_NOT_FOUND = 15100004, + + CJ_ERROR_ALREADY_CLOSED = 15100005, + }; + + enum TypeSymbol { + /* Blob's first byte is the blob's data ValueType */ + STRING = 0, + INTEGER = 1, + FLOAT = 2, + BYTE_ARRAY = 3, + BOOLEAN = 4, + DOUBLE = 5, + INVALID = 255 + }; +} +} +#endif \ No newline at end of file diff --git a/frameworks/cj/src/distributed_kv_store_ffi.cpp b/frameworks/cj/src/distributed_kv_store_ffi.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e2c209aac3a28d292e0e526f4383394845ad3656 --- /dev/null +++ b/frameworks/cj/src/distributed_kv_store_ffi.cpp @@ -0,0 +1,987 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "distributed_kv_store_ffi.h" +#include "distributed_kv_store_impl.h" +#include "distributed_kv_store_utils.h" + +using namespace OHOS::FFI; +using namespace OHOS::DistributedKVStore; + +namespace OHOS { +namespace DistributedKVStore { +extern "C" { +int64_t FfiOHOSDistributedKVStoreCreateKVManager(const char* boudleName, OHOS::AbilityRuntime::Context* context) +{ + if (context == nullptr || boudleName == nullptr) { + return -1; + } + auto nativeCJKVManager = FFIData::Create(boudleName, context); + if (nativeCJKVManager == nullptr) { + return -1; + } + return nativeCJKVManager->GetID(); +} + +int64_t FfiOHOSDistributedKVStoreGetKVStore(int64_t id, const char* storeId, CJOptions options, int32_t* errCode) +{ + if (errCode == nullptr) { + return -1; + } + if (storeId == nullptr) { + *errCode = -1; + return -1; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + *errCode = -1; + return -1; + } + return instance->GetKVStore(storeId, options, *errCode); +} + +int32_t FfiOHOSDistributedKVStoreCloseKVStore(int64_t id, const char* appId, const char* storeId) +{ + if (appId == nullptr || storeId == nullptr) { + return -1; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->CloseKVStore(appId, storeId); +} + +int32_t FfiOHOSDistributedKVStoreDeleteKVStore(int64_t id, const char* appId, const char* storeId) +{ + if (appId == nullptr || storeId == nullptr) { + return -1; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->DeleteKVStore(appId, storeId); +} + +CArrStr FfiOHOSDistributedKVStoreGetAllKVStoreId(int64_t id, const char* appId, int32_t* errCode) +{ + if (errCode == nullptr) { + return CArrStr{}; + } + if (appId == nullptr) { + *errCode = -1; + return CArrStr{}; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + *errCode = -1; + return CArrStr{}; + } + return instance->GetAllKVStoreId(appId, *errCode); +} + +int32_t FfiOHOSDistributedKVStoreOnDistributedDataServiceDie(int64_t id, void (*callbackId)()) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->OnDistributedDataServiceDie(callbackId); +} + +int32_t FfiOHOSDistributedKVStoreOffDistributedDataServiceDie(int64_t id, void (*callbackId)()) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->OffDistributedDataServiceDie(callbackId); +} + +int32_t FfiOHOSDistributedKVStoreOffAllDistributedDataServiceDie(int64_t id) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->OffAllDistributedDataServiceDie(); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStorePut(int64_t id, const char* key, ValueType value) +{ + if (key == nullptr) { + return -1; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->Put(key, value); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStorePutBatch(int64_t id, const CArrEntry cArrEntry) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->PutBatch(cArrEntry); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStoreDelete(int64_t id, const char* key) +{ + if (key == nullptr) { + return -1; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->Delete(key); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStoreDeleteBatch(int64_t id, const CArrStr cArrStr) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->DeleteBatch(cArrStr); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStoreRemoveDeviceData(int64_t id, const char* deviceId) +{ + if (deviceId == nullptr) { + return -1; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->RemoveDeviceData(deviceId); +} + +ValueType FfiOHOSDistributedKVStoreSingleKVStoreGet(int64_t id, const char* key, int32_t* errCode) +{ + if (errCode == nullptr) { + return ValueType{}; + } + if (key == nullptr) { + *errCode = -1; + return ValueType{}; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + *errCode = -1; + return ValueType{}; + } + return instance->Get(key, *errCode); +} + +CArrEntry FfiOHOSDistributedKVStoreSingleKVStoreGetEntriesByQuery(int64_t id, int64_t queryId, int32_t* errCode) +{ + if (errCode == nullptr) { + return CArrEntry{}; + } + auto instance = FFIData::GetData(id); + auto query = FFIData::GetData(queryId); + if (instance == nullptr || query == nullptr) { + *errCode = -1; + return CArrEntry{}; + } + return instance->GetEntries(query, *errCode); +} + +CArrEntry FfiOHOSDistributedKVStoreSingleKVStoreGetEntriesByString(int64_t id, const char* prefix, int32_t* errCode) +{ + if (errCode == nullptr) { + return CArrEntry{}; + } + if (prefix == nullptr) { + *errCode = -1; + return CArrEntry{}; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + *errCode = -1; + return CArrEntry{}; + } + return instance->GetEntries(prefix, *errCode); +} + +int64_t FfiOHOSDistributedKVStoreSingleKVStoreGetResultSetByString(int64_t id, const char* keyPrefix, int32_t* errCode) +{ + if (errCode == nullptr) { + return 0; + } + if (keyPrefix == nullptr) { + *errCode = -1; + return 0; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + *errCode = -1; + return 0; + } + return instance->GetResultSetByString(keyPrefix, *errCode); +} + +int64_t FfiOHOSDistributedKVStoreSingleKVStoreGetResultSetByQuery(int64_t id, int64_t queryId, int32_t* errCode) +{ + if (errCode == nullptr) { + return 0; + } + auto instance = FFIData::GetData(id); + auto query = FFIData::GetData(queryId); + if (instance == nullptr || query == nullptr) { + *errCode = -1; + return 0; + } + return instance->GetResultSetByQuery(query, *errCode); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStoreCloseResultSet(int64_t id, int64_t resultSetId) +{ + auto instance = FFIData::GetData(id); + auto resultSet = FFIData::GetData(resultSetId); + if (instance == nullptr || resultSet == nullptr) { + return -1; + } + return instance->CloseResultSet(resultSet); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStoreGetResultSize(int64_t id, int64_t queryId, int32_t* errCode) +{ + if (errCode == nullptr) { + return 0; + } + auto instance = FFIData::GetData(id); + auto query = FFIData::GetData(queryId); + if (instance == nullptr || query == nullptr) { + *errCode = -1; + return 0; + } + return instance->GetResultSize(query, *errCode); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStoreBackup(int64_t id, const char* file) +{ + if (file == nullptr) { + return -1; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->Backup(file); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStoreRestore(int64_t id, const char* file) +{ + if (file == nullptr) { + return -1; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->Restore(file); +} + +CStringNum FfiOHOSDistributedKVStoreSingleKVStoreDeleteBackup(int64_t id, + const CArrStr cArrStr, int32_t* errCode) +{ + if (errCode == nullptr) { + return CStringNum{}; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + *errCode = -1; + return CStringNum{}; + } + return instance->DeleteBackup(cArrStr, *errCode); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStoreStartTransaction(int64_t id) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->StartTransaction(); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStoreCommit(int64_t id) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->Commit(); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStoreRollback(int64_t id) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->Rollback(); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStoreEnableSync(int64_t id, bool enabled) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->EnableSync(enabled); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStoreSetSyncRange(int64_t id, const CArrStr localLabels, + const CArrStr remoteSupportLabels) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->SetSyncRange(localLabels, remoteSupportLabels); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStoreSetSyncParam(int64_t id, uint32_t defaultAllowedDelayMs) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->SetSyncParam(defaultAllowedDelayMs); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStoreSync(int64_t id, const CArrStr deviceIds, uint8_t mode, uint32_t delayMs) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->Sync(deviceIds, mode, delayMs); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStoreSyncByQuery(int64_t id, const CArrStr deviceIds, int64_t queryId, + uint8_t mode, uint32_t delayMs) +{ + auto instance = FFIData::GetData(id); + auto query = FFIData::GetData(queryId); + if (instance == nullptr || query == nullptr) { + return -1; + } + return instance->SyncByQuery(deviceIds, query, mode, delayMs); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStoreOnDataChange(int64_t id, uint8_t type, + void (*callbackId)(const CChangeNotification valueRef)) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->OnDataChange(type, callbackId); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStoreOffDataChange(int64_t id, + void (*callbackId)(const CChangeNotification valueRef)) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->OffDataChange(callbackId); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStoreOffAllDataChange(int64_t id) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->OffAllDataChange(); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStoreOnSyncComplete(int64_t id, void (*callbackId)(const CStringNum valueRef)) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->OnSyncComplete(callbackId); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStoreOffAllSyncComplete(int64_t id) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->OffAllSyncComplete(); +} + +int32_t FfiOHOSDistributedKVStoreSingleKVStoreGetSecurityLevel(int64_t id, int32_t* errCode) +{ + if (errCode == nullptr) { + return 0; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + *errCode = -1; + return 0; + } + return instance->GetSecurityLevel(*errCode); +} + +int64_t FfiOHOSDistributedKVStoreQueryConstructor() +{ + auto nativeCJQuery = FFIData::Create(); + if (nativeCJQuery == nullptr) { + return -1; + } + return nativeCJQuery->GetID(); +} + +void FfiOHOSDistributedKVStoreQueryReset(int64_t id) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return; + } + return instance->Reset(); +} + +void FfiOHOSDistributedKVStoreQueryEqualTo(int64_t id, const char* field, ValueType value) +{ + if (field == nullptr) { + return; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return; + } + return instance->EqualTo(field, value); +} + +void FfiOHOSDistributedKVStoreQueryNotEqualTo(int64_t id, const char* field, ValueType value) +{ + if (field == nullptr) { + return; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return; + } + return instance->NotEqualTo(field, value); +} + +void FfiOHOSDistributedKVStoreQueryGreaterThan(int64_t id, const char* field, ValueType value) +{ + if (field == nullptr) { + return; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return; + } + return instance->GreaterThan(field, value); +} + +void FfiOHOSDistributedKVStoreQueryLessThan(int64_t id, const char* field, ValueType value) +{ + if (field == nullptr) { + return; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return; + } + return instance->LessThan(field, value); +} + +void FfiOHOSDistributedKVStoreQueryGreaterThanOrEqualTo(int64_t id, const char* field, ValueType value) +{ + if (field == nullptr) { + return; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return; + } + return instance->GreaterThanOrEqualTo(field, value); +} + +void FfiOHOSDistributedKVStoreQueryLessThanOrEqualTo(int64_t id, const char* field, ValueType value) +{ + if (field == nullptr) { + return; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return; + } + return instance->LessThanOrEqualTo(field, value); +} + +void FfiOHOSDistributedKVStoreQueryIsNull(int64_t id, const char* field) +{ + if (field == nullptr) { + return; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return; + } + return instance->IsNull(field); +} + +void FfiOHOSDistributedKVStoreQueryInNumber(int64_t id, const char* field, const CArrNumber valueList) +{ + if (field == nullptr) { + return; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return; + } + return instance->InNumber(field, valueList); +} + +void FfiOHOSDistributedKVStoreQueryInString(int64_t id, const char* field, const CArrStr valueList) +{ + if (field == nullptr) { + return; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return; + } + return instance->InString(field, valueList); +} + +void FfiOHOSDistributedKVStoreQueryNotInNumber(int64_t id, const char* field, const CArrNumber valueList) +{ + if (field == nullptr) { + return; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return; + } + return instance->NotInNumber(field, valueList); +} + +void FfiOHOSDistributedKVStoreQueryNotInString(int64_t id, const char* field, const CArrStr valueList) +{ + if (field == nullptr) { + return; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return; + } + return instance->NotInString(field, valueList); +} + +void FfiOHOSDistributedKVStoreQueryLike(int64_t id, const char* field, const char* value) +{ + if (field == nullptr || value == nullptr) { + return; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return; + } + return instance->Like(field, value); +} + +void FfiOHOSDistributedKVStoreQueryUnlike(int64_t id, const char* field, const char* value) +{ + if (field == nullptr || value == nullptr) { + return; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return; + } + return instance->Unlike(field, value); +} + +void FfiOHOSDistributedKVStoreQueryAnd(int64_t id) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return; + } + return instance->And(); +} + +void FfiOHOSDistributedKVStoreQueryOr(int64_t id) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return; + } + return instance->Or(); +} + +void FfiOHOSDistributedKVStoreQueryOrderByAsc(int64_t id, const char* field) +{ + if (field == nullptr) { + return; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return; + } + return instance->OrderByAsc(field); +} + +void FfiOHOSDistributedKVStoreQueryOrderByDesc(int64_t id, const char* field) +{ + if (field == nullptr) { + return; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return; + } + return instance->OrderByDesc(field); +} + +void FfiOHOSDistributedKVStoreQueryLimit(int64_t id, int32_t total, int32_t offset) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return; + } + return instance->Limit(total, offset); +} + +void FfiOHOSDistributedKVStoreQueryIsNotNull(int64_t id, const char* field) +{ + if (field == nullptr) { + return; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return; + } + return instance->IsNotNull(field); +} + +void FfiOHOSDistributedKVStoreQueryBeginGroup(int64_t id) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return; + } + return instance->BeginGroup(); +} + +void FfiOHOSDistributedKVStoreQueryEndGroup(int64_t id) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return; + } + return instance->EndGroup(); +} + +void FfiOHOSDistributedKVStoreQueryPrefixKey(int64_t id, const char* prefix) +{ + if (prefix == nullptr) { + return; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return; + } + return instance->PrefixKey(prefix); +} + +void FfiOHOSDistributedKVStoreQuerySetSuggestIndex(int64_t id, const char* index) +{ + if (index == nullptr) { + return; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return; + } + return instance->SetSuggestIndex(index); +} + +void FfiOHOSDistributedKVStoreQueryDeviceId(int64_t id, const char* deviceId) +{ + if (deviceId == nullptr) { + return; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return; + } + return instance->DeviceId(deviceId); +} + +const char* FfiOHOSDistributedKVStoreQueryGetSqlLike(int64_t id) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return nullptr; + } + return MallocCString(instance->GetSqlLike()); +} + +ValueType FfiOHOSDistributedKVStoreDeviceKVStoreGet(int64_t id, const char* deviceId, + const char* key, int32_t* errCode) +{ + if (errCode == nullptr) { + return ValueType{}; + } + if (deviceId == nullptr || key == nullptr) { + *errCode = -1; + return ValueType{}; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + *errCode = -1; + return ValueType{}; + } + return instance->Get(deviceId, key, *errCode); +} + +CArrEntry FfiOHOSDistributedKVStoreDeviceKVStoreGetEntries(int64_t id, const char* deviceId, const char* keyPrefix, + int32_t* errCode) +{ + if (errCode == nullptr) { + return CArrEntry{}; + } + if (deviceId == nullptr || keyPrefix == nullptr) { + *errCode = -1; + return CArrEntry{}; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + *errCode = -1; + return CArrEntry{}; + } + return instance->GetEntries(deviceId, keyPrefix, *errCode); +} + +CArrEntry FfiOHOSDistributedKVStoreDeviceKVStoreGetEntriesQuery(int64_t id, const char* deviceId, int64_t queryId, + int32_t* errCode) +{ + if (errCode == nullptr) { + return CArrEntry{}; + } + if (deviceId == nullptr) { + *errCode = -1; + return CArrEntry{}; + } + auto instance = FFIData::GetData(id); + auto query = FFIData::GetData(queryId); + if (instance == nullptr || query == nullptr) { + *errCode = -1; + return CArrEntry{}; + } + return instance->GetEntries(deviceId, query, *errCode); +} + +int64_t FfiOHOSDistributedKVStoreDeviceKVStoreGetResultSet(int64_t id, const char* deviceId, const char* keyPrefix, + int32_t* errCode) +{ + if (errCode == nullptr) { + return -1; + } + if (deviceId == nullptr || keyPrefix == nullptr) { + *errCode = -1; + return -1; + } + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + *errCode = -1; + return -1; + } + return instance->GetResultSet(deviceId, keyPrefix, *errCode); +} + +int64_t FfiOHOSDistributedKVStoreDeviceKVStoreGetResultSetQuery(int64_t id, const char* deviceId, int64_t queryId, + int32_t* errCode) +{ + if (errCode == nullptr) { + return -1; + } + if (deviceId == nullptr) { + *errCode = -1; + return -1; + } + auto instance = FFIData::GetData(id); + auto query = FFIData::GetData(queryId); + if (instance == nullptr || query == nullptr) { + *errCode = -1; + return -1; + } + return instance->GetResultSetQuery(deviceId, query, *errCode); +} + +int32_t FfiOHOSDistributedKVStoreDeviceKVStoreGetResultSize(int64_t id, const char* deviceId, int64_t queryId, + int32_t* errCode) +{ + if (errCode == nullptr) { + return -1; + } + if (deviceId == nullptr) { + *errCode = -1; + return -1; + } + auto instance = FFIData::GetData(id); + auto query = FFIData::GetData(queryId); + if (instance == nullptr || query == nullptr) { + *errCode = -1; + return -1; + } + return instance->GetResultSize(deviceId, query, *errCode); +} + +int32_t FfiOHOSDistributedKVStoreKVStoreResultSetGetCount(int64_t id) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->GetCount(); +} + +int32_t FfiOHOSDistributedKVStoreKVStoreResultSetGetPosition(int64_t id) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return -1; + } + return instance->GetPosition(); +} + +bool FfiOHOSDistributedKVStoreKVStoreResultSetMoveToFirst(int64_t id) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return false; + } + return instance->MoveToFirst(); +} + +bool FfiOHOSDistributedKVStoreKVStoreResultSetMoveToLast(int64_t id) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return false; + } + return instance->MoveToLast(); +} + +bool FfiOHOSDistributedKVStoreKVStoreResultSetMoveToNext(int64_t id) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return false; + } + return instance->MoveToNext(); +} + +bool FfiOHOSDistributedKVStoreKVStoreResultSetMoveToPrevious(int64_t id) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return false; + } + return instance->MoveToPrevious(); +} + +bool FfiOHOSDistributedKVStoreKVStoreResultSetMove(int64_t id, int32_t offset) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return false; + } + return instance->Move(offset); +} + +bool FfiOHOSDistributedKVStoreKVStoreResultSetMoveToPosition(int64_t id, int32_t position) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return false; + } + return instance->MoveToPosition(position); +} + +bool FfiOHOSDistributedKVStoreKVStoreResultSetIsFirst(int64_t id) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return false; + } + return instance->IsFirst(); +} + +bool FfiOHOSDistributedKVStoreKVStoreResultSetIsLast(int64_t id) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return false; + } + return instance->IsLast(); +} + +bool FfiOHOSDistributedKVStoreKVStoreResultSetIsBeforeFirst(int64_t id) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return false; + } + return instance->IsBeforeFirst(); +} + +bool FfiOHOSDistributedKVStoreKVStoreResultSetIsAfterLast(int64_t id) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return false; + } + return instance->IsAfterLast(); +} + +CEntry FfiOHOSDistributedKVStoreKVStoreResultSetGetEntry(int64_t id) +{ + auto instance = FFIData::GetData(id); + if (instance == nullptr) { + return CEntry{}; + } + return instance->GetEntry(); +} + +void FfiOHOSFreeCString(char* str) +{ + FreeCString(str); +} +} +} +} diff --git a/frameworks/cj/src/distributed_kv_store_impl.cpp b/frameworks/cj/src/distributed_kv_store_impl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2b311299d35eb4132550e0fe27c61fd4419b7a58 --- /dev/null +++ b/frameworks/cj/src/distributed_kv_store_impl.cpp @@ -0,0 +1,1298 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include "securec.h" +#include "ffi_remote_data.h" +#include "cj_lambda.h" + +#include "distributed_kv_store_impl.h" +#include "distributed_kv_store_utils.h" + +using namespace OHOS::FFI; + +namespace OHOS::DistributedKVStore { + +static int32_t ConvertCJErrCode(Status status) +{ + switch (status) { + case PERMISSION_DENIED: + // 202 + return CJ_ERROR_PERMISSION_DENIED; + case INVALID_ARGUMENT: + case NOT_SUPPORT: + // 401 + return CJ_ERROR_INVALID_ARGUMENT; + case OVER_MAX_LIMITS: + // 15100001 + return CJ_ERROR_OVER_MAX_LIMITS; + case STORE_META_CHANGED: + case SECURITY_LEVEL_ERROR: + // 15100002 + return CJ_ERROR_STORE_META_CHANGED; + case CRYPT_ERROR: + case DATA_CORRUPTED: + // 15100003 + return CJ_ERROR_CRYPT_ERROR; + case NOT_FOUND: + case DB_ERROR: + // 15100004 + return CJ_ERROR_NOT_FOUND; + case ALREADY_CLOSED: + // 15100005 + return CJ_ERROR_ALREADY_CLOSED; + default: + return static_cast(status); + } +} + +static CArrByte VectorToByteArray(std::vector bytes) +{ + uint8_t* head = static_cast(malloc(bytes.size() * sizeof(uint8_t))); + if (head == nullptr) { + return CArrByte{}; + } + for (unsigned long i = 0; i < bytes.size(); i++) { + head[i] = bytes[i]; + } + CArrByte byteArray = { head, bytes.size() }; + return byteArray; +} + +static ValueType KVValueToValueType(const DistributedKv::Blob& blob) +{ + auto& data = blob.Data(); + ValueType v = { 0 }; + // number 2 means: valid Blob must have more than 2 bytes. + if (data.size() < 1) { + LOGI("Blob have no data!"); + return {0}; + } + // number 1 means: skip the first byte, byte[0] is real data type. + std::vector real(data.begin() + 1, data.end()); + if (data[0] == STRING) { + v.string = MallocCString(std::string(real.begin(), real.end())); + v.tag = STRING; + } else if (data[0] == INTEGER) { + uint32_t tmp4int = be32toh(*reinterpret_cast(&(real[0]))); + v.integer = *reinterpret_cast(&tmp4int); + v.tag = INTEGER; + } else if (data[0] == FLOAT) { + uint32_t tmp4flt = be32toh(*reinterpret_cast(&(real[0]))); + v.flo = *reinterpret_cast((void*)(&tmp4flt)); + v.tag = FLOAT; + } else if (data[0] == BYTE_ARRAY) { + v.byteArray = VectorToByteArray(std::vector(real.begin(), real.end())); + v.tag = BYTE_ARRAY; + } else if (data[0] == BOOLEAN) { + v.boolean = static_cast(real[0]); + v.tag = BOOLEAN; + } else if (data[0] == DOUBLE) { + uint64_t tmp4dbl = be64toh(*reinterpret_cast(&(real[0]))); + v.dou = *reinterpret_cast((void*)(&tmp4dbl)); + v.tag = DOUBLE; + } else { + // for schema-db, if (data[0] == STRING), no beginning byte! + v.string = MallocCString(std::string(data.begin(), data.end())); + v.tag = STRING; + } + return v; +} + +static void PushData(const ValueType &value, std::vector &data, uint8_t tag) +{ + switch (tag) { + case INTEGER: { + int32_t tmp = value.integer; // copy value, and make it available in stack space. + uint32_t tmp32 = htobe32(*reinterpret_cast(&tmp)); + uint8_t *res = reinterpret_cast(&tmp32); + data.push_back(INTEGER); + data.insert(data.end(), res, res + sizeof(int32_t) / sizeof(uint8_t)); + break; + } + case FLOAT: { + float tmp = value.flo; // copy value, and make it available in stack space. + uint32_t tmp32 = htobe32(*reinterpret_cast(&tmp)); + uint8_t *res = reinterpret_cast(&tmp32); + data.push_back(FLOAT); + data.insert(data.end(), res, res + sizeof(float) / sizeof(uint8_t)); + break; + } + case DOUBLE: { + double tmp = value.dou; // copy value, and make it available in stack space. + uint64_t tmp64 = htobe64(*reinterpret_cast(&tmp)); + uint8_t *res = reinterpret_cast(&tmp64); + data.push_back(DOUBLE); + data.insert(data.end(), res, res + sizeof(double) / sizeof(uint8_t)); + break; + } + default: + break; + } +} + +static DistributedKv::Value ValueTypeToKVValue(const ValueType &value) +{ + std::vector data; + switch (value.tag) { + case STRING: { + std::string str = value.string; + data.push_back(STRING); + data.insert(data.end(), str.begin(), str.end()); + break; + } + case INTEGER: { + PushData(value, data, value.tag); + break; + } + case FLOAT: { + PushData(value, data, value.tag); + break; + } + case BYTE_ARRAY: { + std::vector bytes = std::vector(); + for (int64_t i = 0; i < value.byteArray.size; i++) { + bytes.push_back(value.byteArray.head[i]); + } + data.push_back(BYTE_ARRAY); + data.insert(data.end(), bytes.begin(), bytes.end()); + break; + } + case BOOLEAN: { + data.push_back(BOOLEAN); + data.push_back(static_cast(value.boolean)); + break; + } + case DOUBLE: { + PushData(value, data, value.tag); + break; + } + default: + break; + } + return DistributedKv::Blob(data); +} + +CJKVManager::CJKVManager() {}; +CJKVManager::CJKVManager(const char* boudleName, OHOS::AbilityRuntime::Context* context) +{ + ContextParam param; + param.area = context->GetArea(); + param.baseDir = context->GetDatabaseDir(); + auto hapInfo = context->GetHapModuleInfo(); + if (hapInfo != nullptr) { + param.hapName = hapInfo->moduleName; + } + param_ = std::make_shared(std::move(param)); + bundleName_ = boudleName; +} + +uint64_t CJKVManager::GetKVStore(const char* cStoreId, const CJOptions cjOptions, int32_t& errCode) +{ + Options options; + options.createIfMissing = cjOptions.createIfMissing; + options.encrypt = cjOptions.encrypt; + options.backup = cjOptions.backup; + options.autoSync = cjOptions.autoSync; + options.kvStoreType = static_cast(cjOptions.kvStoreType); + options.securityLevel = cjOptions.securityLevel; + AppId appId = { bundleName_ }; + std::string sStoreId = cStoreId; + StoreId storeId = { sStoreId }; + options.baseDir = param_->baseDir; + options.area = param_->area + 1; + options.hapName = param_->hapName; + std::shared_ptr kvStore; + Status status = kvDataManager_.GetSingleKvStore(options, appId, storeId, kvStore); + if (status == DATA_CORRUPTED) { + options.rebuild = true; + status = kvDataManager_.GetSingleKvStore(options, appId, storeId, kvStore); + LOGE("Data has corrupted, rebuild db"); + } + errCode = ConvertCJErrCode(status); + if (errCode != 0) { + return 0; + } + if (cjOptions.kvStoreType == 1) { + auto nativeKVStore = FFIData::Create(sStoreId); + if (nativeKVStore == nullptr) { + errCode = -1; + return -1; + } + nativeKVStore->SetKvStorePtr(kvStore); + nativeKVStore->SetContextParam(param_); + return nativeKVStore->GetID(); + } + auto nativeKVStore = FFIData::Create(sStoreId); + if (nativeKVStore == nullptr) { + errCode = -1; + return -1; + } + nativeKVStore->SetKvStorePtr(kvStore); + nativeKVStore->SetContextParam(param_); + return nativeKVStore->GetID(); +} + +int32_t CJKVManager::CloseKVStore(const char* appId, const char* storeId) +{ + std::string sAppId = appId; + std::string sStoreId = storeId; + AppId appIdBox = { sAppId }; + StoreId storeIdBox { sStoreId }; + Status status = kvDataManager_.CloseKvStore(appIdBox, storeIdBox); + if ((status == Status::SUCCESS) || (status == Status::STORE_NOT_FOUND) || (status == Status::STORE_NOT_OPEN)) { + status = Status::SUCCESS; + } + return ConvertCJErrCode(status); +} + +int32_t CJKVManager::DeleteKVStore(const char* appId, const char* storeId) +{ + std::string sAppId = appId; + std::string sStoreId = storeId; + AppId appIdBox = { sAppId }; + StoreId storeIdBox { sStoreId }; + std::string databaseDir = param_->baseDir; + Status status = kvDataManager_.DeleteKvStore(appIdBox, storeIdBox, databaseDir); + return ConvertCJErrCode(status); +} + +static CArrStr VectorAppIdToCArr(const std::vector& storeIdList) +{ + CArrStr strArray; + strArray.size = static_cast(storeIdList.size()); + strArray.head = static_cast(malloc(strArray.size * sizeof(char*))); + if (strArray.head == nullptr) { + return CArrStr{0}; + } + for (int64_t i = 0; i < strArray.size; i++) { + strArray.head[i] = MallocCString(storeIdList[i].storeId); + } + return strArray; +} + +CArrStr CJKVManager::GetAllKVStoreId(const char* appId, int32_t& errCode) +{ + std::string sAppId = appId; + AppId appIdBox = { sAppId }; + std::vector storeIdList; + Status status = kvDataManager_.GetAllKvStoreId(appIdBox, storeIdList); + errCode = ConvertCJErrCode(status); + if (errCode != 0) { + return CArrStr{0}; + } + return VectorAppIdToCArr(storeIdList); +} + +int32_t CJKVManager::OnDistributedDataServiceDie(void (*callbackId)()) +{ + std::lock_guard lck(deathMutex_); + auto onChange = [lambda = CJLambda::Create(callbackId)]() -> void { lambda(); }; + auto deathRecipient = std::make_shared(callbackId, onChange); + kvDataManager_.RegisterKvStoreServiceDeathRecipient(deathRecipient); + deathRecipient_.push_back(deathRecipient); + return 0; +} + +int32_t CJKVManager::OffDistributedDataServiceDie(void (*callbackId)()) +{ + std::lock_guard lck(deathMutex_); + auto it = deathRecipient_.begin(); + while (it != deathRecipient_.end()) { + if ((*it)->m_callbackId == callbackId) { + kvDataManager_.UnRegisterKvStoreServiceDeathRecipient(*it); + it = deathRecipient_.erase(it); + break; // specified observer is current iterator + } + ++it; + } + return 0; +} + +int32_t CJKVManager::OffAllDistributedDataServiceDie() +{ + std::lock_guard lck(deathMutex_); + for (auto& observer : deathRecipient_) { + kvDataManager_.UnRegisterKvStoreServiceDeathRecipient(observer); + } + deathRecipient_.clear(); + return 0; +} + +CJSingleKVStore::CJSingleKVStore(const std::string& storeId) +{ + storeId_ = storeId; +} + +std::shared_ptr CJSingleKVStore::GetKvStorePtr() +{ + return kvStore_; +} + +void CJSingleKVStore::SetKvStorePtr(std::shared_ptr kvStore) +{ + kvStore_ = kvStore; +} + +void CJSingleKVStore::SetContextParam(std::shared_ptr param) +{ + param_ = param; +} + +int32_t CJSingleKVStore::Put(const std::string &key, const ValueType &value) +{ + auto tempKey = DistributedKv::Key(key); + Status status = kvStore_->Put(tempKey, ValueTypeToKVValue(value)); + return ConvertCJErrCode(status); +} + +static Entry CEntryToEntry(const CEntry &cEntry) +{ + std::string key = cEntry.key; + Entry entry = {DistributedKv::Key(key), ValueTypeToKVValue(cEntry.value)}; + return entry; +} + +static std::vector CArrayEntryToEntries(const CArrEntry &cArrEntry) +{ + std::vector entrys; + int64_t arrSize = cArrEntry.size; + + for (int64_t i = 0; i < arrSize; i++) { + Entry entry = CEntryToEntry(cArrEntry.head[i]); + entrys.push_back(entry); + } + return entrys; +} + +static CArrEntry EntriesToCArrEntry(const std::vector &entries) +{ + CEntry *cEntries = static_cast(malloc(entries.size() * sizeof(CEntry))); + if (cEntries == nullptr) { + return CArrEntry{}; + } + for (size_t i = 0; i < entries.size(); i++) { + cEntries[i].key = MallocCString(entries[i].key.ToString()); + cEntries[i].value = KVValueToValueType(entries[i].value); + } + return CArrEntry{.head = cEntries, .size = int64_t(entries.size())}; +} + +static CChangeNotification ChangeNotificationToCChangeNotification(const ChangeNotification &c) +{ + std::vector insertEntries = c.GetInsertEntries(); + std::vector updateEntries = c.GetUpdateEntries(); + std::vector deleteEntries = c.GetDeleteEntries(); + std::string deviceId = c.GetDeviceId(); + return CChangeNotification{.insertEntries = EntriesToCArrEntry(insertEntries), + .updateEntries = EntriesToCArrEntry(updateEntries), + .deleteEntries = EntriesToCArrEntry(deleteEntries), + .deviceId = MallocCString(deviceId)}; +} + +int32_t CJSingleKVStore::PutBatch(const CArrEntry &cArrEntry) +{ + Status status = kvStore_->PutBatch(CArrayEntryToEntries(cArrEntry)); + return ConvertCJErrCode(status); +} + +int32_t CJSingleKVStore::Delete(const std::string &key) +{ + auto tempKey = DistributedKv::Key(key); + Status status = kvStore_->Delete(tempKey); + return ConvertCJErrCode(status); +} + +static std::vector CArrStrToVectorKey(const CArrStr &cArrStr) +{ + std::vector keys; + int64_t size = cArrStr.size; + for (int64_t i = 0; i < size; i++) { + std::string str = cArrStr.head[i]; + keys.push_back(DistributedKv::Key(str)); + } + return keys; +} + +int32_t CJSingleKVStore::DeleteBatch(const CArrStr &cArrStr) +{ + Status status = kvStore_->DeleteBatch(CArrStrToVectorKey(cArrStr)); + return ConvertCJErrCode(status); +} + +int32_t CJSingleKVStore::RemoveDeviceData(const std::string &deviceId) +{ + Status status = kvStore_->RemoveDeviceData(deviceId); + return ConvertCJErrCode(status); +} + +ValueType CJSingleKVStore::Get(const std::string &key, int32_t& errCode) +{ + auto s_key = DistributedKv::Key(key); + OHOS::DistributedKv::Value value; + Status status = kvStore_->Get(key, value); + errCode = ConvertCJErrCode(status); + if (errCode != 0) { + return ValueType{0}; + } + return KVValueToValueType(value); +} + +CArrEntry CJSingleKVStore::GetEntries(OHOS::sptr query, int32_t& errCode) +{ + std::vector entries; + DistributedKVStore::DataQuery dataQuery = query->GetDataQuery(); + Status status = kvStore_->GetEntries(dataQuery, entries); + errCode = ConvertCJErrCode(status); + return EntriesToCArrEntry(entries); +} + +CArrEntry CJSingleKVStore::GetEntries(const std::string &keyPrefix, int32_t& errCode) +{ + std::vector entries; + DistributedKVStore::DataQuery dataQuery; + dataQuery.KeyPrefix(keyPrefix); + Status status = kvStore_->GetEntries(dataQuery, entries); + errCode = ConvertCJErrCode(status); + return EntriesToCArrEntry(entries); +} + +int64_t CJSingleKVStore::GetResultSetByString(const std::string &keyPrefix, int32_t& errCode) +{ + DistributedKVStore::DataQuery dataQuery; + dataQuery.KeyPrefix(keyPrefix); + std::shared_ptr kvResultSet; + Status status = GetKvStorePtr()->GetResultSet(dataQuery, kvResultSet); + errCode = ConvertCJErrCode(status); + auto nativeCKVStoreResultSet = FFIData::Create(kvResultSet); + if (nativeCKVStoreResultSet == nullptr) { + return -1; + } + return nativeCKVStoreResultSet->GetID(); +} + +int64_t CJSingleKVStore::GetResultSetByQuery(OHOS::sptr query, int32_t& errCode) +{ + DistributedKVStore::DataQuery dataQuery = query->GetDataQuery(); + std::shared_ptr kvResultSet; + Status status = GetKvStorePtr()->GetResultSet(dataQuery, kvResultSet); + errCode = ConvertCJErrCode(status); + auto nativeCKVStoreResultSet = FFIData::Create(kvResultSet); + if (nativeCKVStoreResultSet == nullptr) { + return -1; + } + return nativeCKVStoreResultSet->GetID(); +} + +int32_t CJSingleKVStore::CloseResultSet(OHOS::sptr resultSet) +{ + std::shared_ptr ptrKvResultSet = resultSet->GetKvStoreResultSet(); + Status status = kvStore_->CloseResultSet(ptrKvResultSet); + return ConvertCJErrCode(status); +} + +int32_t CJSingleKVStore::GetResultSize(OHOS::sptr query, int32_t& errCode) +{ + DistributedKVStore::DataQuery dataQuery = query->GetDataQuery(); + int resultSize = 0; + Status status = kvStore_->GetCount(dataQuery, resultSize); + errCode = ConvertCJErrCode(status); + return resultSize; +} + +int32_t CJSingleKVStore::Backup(const std::string &file) +{ + Status status = kvStore_->Backup(file, param_->baseDir); + return ConvertCJErrCode(status); +} + +int32_t CJSingleKVStore::Restore(const std::string &file) +{ + Status status = kvStore_->Restore(file, param_->baseDir); + return ConvertCJErrCode(status); +} + +static std::vector CArrStrToVectorString(const CArrStr &cArrStr) +{ + std::vector strings; + int64_t size = cArrStr.size; + for (int64_t i = 0; i < size; i++) { + std::string str = cArrStr.head[i]; + strings.push_back(str); + } + return strings; +} + +static CStringNum MapToCStringNum(const std::map& results) +{ + CStringNum cStringNum; + cStringNum.headChar = (char**)malloc(sizeof(char*) * results.size()); + if (cStringNum.headChar == nullptr) { + return CStringNum{0}; + } + cStringNum.headNum = (int32_t*)malloc(sizeof(int32_t) * results.size()); + if (cStringNum.headNum == nullptr) { + free(cStringNum.headChar); + return CStringNum{0}; + } + cStringNum.size = results.size(); + int64_t i = 0; + for (auto& it : results) { + cStringNum.headChar[i] = MallocCString(it.first); + cStringNum.headNum[i] = ConvertCJErrCode(it.second); + i++; + } + return cStringNum; +} + +CStringNum CJSingleKVStore::DeleteBackup(const CArrStr &cArrStr, int32_t& errCode) +{ + std::map results; + Status status = kvStore_->DeleteBackup(CArrStrToVectorString(cArrStr), param_->baseDir, results); + errCode = ConvertCJErrCode(status); + return MapToCStringNum(results); +} + +int32_t CJSingleKVStore::StartTransaction() +{ + Status status = kvStore_->StartTransaction(); + return ConvertCJErrCode(status); +} + +int32_t CJSingleKVStore::Commit() +{ + Status status = kvStore_->Commit(); + return ConvertCJErrCode(status); +} + +int32_t CJSingleKVStore::Rollback() +{ + Status status = kvStore_->Rollback(); + return ConvertCJErrCode(status); +} + +int32_t CJSingleKVStore::EnableSync(bool enabled) +{ + Status status = kvStore_->SetCapabilityEnabled(enabled); + return ConvertCJErrCode(status); +} + +int32_t CJSingleKVStore::SetSyncRange(const CArrStr &localLabels, const CArrStr &remoteSupportLabels) +{ + Status status = kvStore_->SetCapabilityRange(CArrStrToVectorString(localLabels), + CArrStrToVectorString(remoteSupportLabels)); + return ConvertCJErrCode(status); +} + +int32_t CJSingleKVStore::SetSyncParam(uint32_t defaultAllowedDelayMs) +{ + KvSyncParam syncParam { defaultAllowedDelayMs }; + Status status = kvStore_->SetSyncParam(syncParam); + return ConvertCJErrCode(status); +} + +int32_t CJSingleKVStore::Sync(const CArrStr deviceIds, uint8_t mode, uint32_t delayMs) +{ + Status status = kvStore_->Sync(CArrStrToVectorString(deviceIds), static_cast(mode), delayMs); + return ConvertCJErrCode(status); +} + +int32_t CJSingleKVStore::SyncByQuery(const CArrStr deviceIds, OHOS::sptr query, uint8_t mode, uint32_t delayMs) +{ + DistributedKVStore::DataQuery dataQuery = query->GetDataQuery(); + Status status = kvStore_->Sync(CArrStrToVectorString(deviceIds), + static_cast(mode), dataQuery, nullptr, delayMs); + return ConvertCJErrCode(status); +} + +static SubscribeType ToSubscribeType(uint8_t type) +{ + switch (type) { + case 0: // 0 means SUBSCRIBE_TYPE_LOCAL + return SubscribeType::SUBSCRIBE_TYPE_LOCAL; + case 1: // 1 means SUBSCRIBE_TYPE_REMOTE + return SubscribeType::SUBSCRIBE_TYPE_REMOTE; + case 2: // 2 means SUBSCRIBE_TYPE_ALL + return SubscribeType::SUBSCRIBE_TYPE_ALL; + default: + return SubscribeType::SUBSCRIBE_TYPE_LOCAL; + } +} + +int32_t CJSingleKVStore::OnDataChange(uint8_t type, void (*callbackId)(const CChangeNotification valueRef)) +{ + std::lock_guard lck(listMutex_); + auto onChange = [lambda = CJLambda::Create(callbackId)](const ChangeNotification& valueRef) -> + void { lambda(ChangeNotificationToCChangeNotification(valueRef)); }; + auto observer = std::make_shared(callbackId, onChange); + auto subscribeType = ToSubscribeType(type); + Status status = kvStore_->SubscribeKvStore(subscribeType, observer); + int32_t errCode = ConvertCJErrCode(status); + if (errCode != 0) { + return errCode; + } + dataObserver_[type].push_back(observer); + return errCode; +} + +int32_t CJSingleKVStore::OffDataChange(void (*callbackId)(const CChangeNotification valueRef)) +{ + std::lock_guard lck(listMutex_); + for (uint8_t type = SUBSCRIBE_LOCAL; type < SUBSCRIBE_COUNT; type++) { + auto it = dataObserver_[type].begin(); + while (it != dataObserver_[type].end()) { + int32_t errCode = 0; + if ((*it)->m_callbackId == callbackId) { + auto subscribeType = ToSubscribeType(type); + Status status = kvStore_->UnSubscribeKvStore(subscribeType, *it); + errCode = ConvertCJErrCode(status); + it = dataObserver_[type].erase(it); + } + if (errCode != 0) { + return errCode; + } + ++it; + } + } + return 0; +} + +int32_t CJSingleKVStore::OffAllDataChange() +{ + std::lock_guard lck(listMutex_); + for (uint8_t type = SUBSCRIBE_LOCAL; type < SUBSCRIBE_COUNT; type++) { + for (auto& observer : dataObserver_[type]) { + auto subscribeType = ToSubscribeType(type); + Status status = kvStore_->UnSubscribeKvStore(subscribeType, observer); + int32_t errCode = ConvertCJErrCode(status); + if (errCode != 0) { + return errCode; + } + } + dataObserver_[type].clear(); + } + return 0; +} + +int32_t CJSingleKVStore::OnSyncComplete(void (*callbackId)(const CStringNum valueRef)) +{ + std::lock_guard lck(listMutex_); + auto onChange = [lambda = CJLambda::Create(callbackId)] + (const std::map& valueRef) -> + void { lambda(MapToCStringNum(valueRef)); }; + auto observer = std::make_shared(callbackId, onChange); + Status status = kvStore_->RegisterSyncCallback(observer); + int32_t errCode = ConvertCJErrCode(status); + if (errCode != 0) { + return errCode; + } + syncObservers_.push_back(observer); + return errCode; +} + +int32_t CJSingleKVStore::OffAllSyncComplete() +{ + std::lock_guard lck(listMutex_); + Status status = kvStore_->UnRegisterSyncCallback(); + int32_t errCode = ConvertCJErrCode(status); + if (errCode == 0) { + syncObservers_.clear(); + } + return errCode; +} + +int32_t CJSingleKVStore::GetSecurityLevel(int32_t& errCode) +{ + SecurityLevel securityLevel; + Status status = kvStore_->GetSecurityLevel(securityLevel); + errCode = ConvertCJErrCode(status); + return static_cast(securityLevel); +} + +constexpr int DEVICEID_WIDTH = 4; + +static std::string GetDeviceKey(const std::string& deviceId, const std::string& key) +{ + std::ostringstream oss; + if (!deviceId.empty()) { + oss << std::setfill('0') << std::setw(DEVICEID_WIDTH) << deviceId.length() << deviceId; + } + oss << key; + return oss.str(); +} + +CJDeviceKVStore::CJDeviceKVStore(const std::string& storeId) + : CJSingleKVStore(storeId) +{ +} + +ValueType CJDeviceKVStore::Get(const std::string &deviceId, const std::string &key, int32_t& errCode) +{ + std::string deviceKey = GetDeviceKey(deviceId, key); + auto s_key = DistributedKv::Key(deviceKey); + OHOS::DistributedKv::Value value; + Status status = GetKvStorePtr()->Get(key, value); + errCode = ConvertCJErrCode(status); + if (errCode != 0) { + return ValueType{0}; + } + return KVValueToValueType(value); +} + +CArrEntry CJDeviceKVStore::GetEntriesByDataQuery(DistributedKVStore::DataQuery dataQuery, int32_t& errCode) +{ + std::vector entries; + Status status = GetKvStorePtr()->GetEntries(dataQuery, entries); + errCode = ConvertCJErrCode(status); + if (errCode != 0) { + return CArrEntry{}; + } + CEntry *cEntries = static_cast(malloc(entries.size() * sizeof(CEntry))); + if (cEntries == nullptr) { + errCode = -1; + return CArrEntry{}; + } + for (size_t i = 0; i < entries.size(); i++) { + cEntries[i].key = MallocCString(entries[i].key.ToString()); + cEntries[i].value = KVValueToValueType(entries[i].value); + } + return CArrEntry{.head = cEntries, .size = int64_t(entries.size())}; +} + +CArrEntry CJDeviceKVStore::GetEntries(const std::string &deviceId, const std::string &keyPrefix, int32_t& errCode) +{ + DistributedKVStore::DataQuery dataQuery; + dataQuery.KeyPrefix(keyPrefix); + dataQuery.DeviceId(deviceId); + + return GetEntriesByDataQuery(dataQuery, errCode); +} + +CArrEntry CJDeviceKVStore::GetEntries(const std::string &deviceId, OHOS::sptr query, int32_t& errCode) +{ + DistributedKVStore::DataQuery dataQuery = query->GetDataQuery(); + dataQuery.DeviceId(deviceId); + + return GetEntriesByDataQuery(dataQuery, errCode); +} + +int64_t CJDeviceKVStore::GetResultSet(const std::string &deviceId, const std::string &keyPrefix, int32_t& errCode) +{ + DistributedKVStore::DataQuery dataQuery; + dataQuery.KeyPrefix(keyPrefix); + dataQuery.DeviceId(deviceId); + + std::shared_ptr kvResultSet; + Status status = GetKvStorePtr()->GetResultSet(dataQuery, kvResultSet); + errCode = ConvertCJErrCode(status); + if (errCode != 0) { + return -1; + } + auto nativeCKvStoreResultSet = FFIData::Create(kvResultSet); + if (nativeCKvStoreResultSet == nullptr) { + errCode = -1; + return -1; + } + return nativeCKvStoreResultSet->GetID(); +} + +int64_t CJDeviceKVStore::GetResultSetQuery(const std::string &deviceId, OHOS::sptr query, int32_t& errCode) +{ + DistributedKVStore::DataQuery dataQuery = query->GetDataQuery(); + dataQuery.DeviceId(deviceId); + + std::shared_ptr kvResultSet; + Status status = GetKvStorePtr()->GetResultSet(dataQuery, kvResultSet); + errCode = ConvertCJErrCode(status); + if (errCode != 0) { + return -1; + } + auto nativeCKvStoreResultSet = FFIData::Create(kvResultSet); + if (nativeCKvStoreResultSet == nullptr) { + errCode = -1; + return -1; + } + return nativeCKvStoreResultSet->GetID(); +} + +int32_t CJDeviceKVStore::GetResultSize(const std::string &deviceId, OHOS::sptr query, int32_t& errCode) +{ + DistributedKVStore::DataQuery dataQuery = query->GetDataQuery(); + dataQuery.DeviceId(deviceId); + + int32_t resultSize = 0; + Status status = GetKvStorePtr()->GetCount(dataQuery, resultSize); + errCode = ConvertCJErrCode(status); + return resultSize; +} + +CKvStoreResultSet::CKvStoreResultSet(std::shared_ptr cKvResultSet) +{ + kvResultSet = cKvResultSet; +} + +std::shared_ptr CKvStoreResultSet::GetKvStoreResultSet() +{ + return kvResultSet; +} + +int32_t CKvStoreResultSet::GetCount() +{ + return kvResultSet->GetCount(); +} + +int32_t CKvStoreResultSet::GetPosition() +{ + return kvResultSet->GetPosition(); +} + +bool CKvStoreResultSet::MoveToFirst() +{ + return kvResultSet->MoveToFirst(); +} + +bool CKvStoreResultSet::MoveToLast() +{ + return kvResultSet->MoveToLast(); +} + +bool CKvStoreResultSet::MoveToNext() +{ + return kvResultSet->MoveToNext(); +} + +bool CKvStoreResultSet::MoveToPrevious() +{ + return kvResultSet->MoveToPrevious(); +} + +bool CKvStoreResultSet::Move(int32_t offset) +{ + return kvResultSet->Move(offset); +} + +bool CKvStoreResultSet::MoveToPosition(int32_t position) +{ + return kvResultSet->MoveToPosition(position); +} + +bool CKvStoreResultSet::IsFirst() +{ + return kvResultSet->IsFirst(); +} + +bool CKvStoreResultSet::IsLast() +{ + return kvResultSet->IsLast(); +} + +bool CKvStoreResultSet::IsBeforeFirst() +{ + return kvResultSet->IsBeforeFirst(); +} + +bool CKvStoreResultSet::IsAfterLast() +{ + return kvResultSet->IsAfterLast(); +} + +CEntry CKvStoreResultSet::GetEntry() +{ + Entry entry; + auto status = kvResultSet->GetEntry(entry); + if (status != Status::SUCCESS) + return CEntry{}; + auto& data = entry.key.Data(); + return CEntry{.key = MallocCString(std::string(data.begin(), data.end())), + .value = KVValueToValueType(entry.value)}; +} + +const DistributedKv::DataQuery& CQuery::GetDataQuery() const +{ + return query_; +} + +void CQuery::Reset() +{ + query_.Reset(); +} + +void CQuery::EqualTo(const std::string &field, ValueType &value) +{ + switch (value.tag) { + case STRING: { + std::string str = value.string; + query_.EqualTo(field, str); + break; + } + case INTEGER: { + query_.EqualTo(field, value.integer); + break; + } + case FLOAT: { + query_.EqualTo(field, value.flo); + break; + } + case BOOLEAN: { + query_.EqualTo(field, value.boolean); + break; + } + case DOUBLE: { + query_.EqualTo(field, value.dou); + break; + } + default: { + break; + } + } +} + +void CQuery::NotEqualTo(const std::string &field, ValueType &value) +{ + switch (value.tag) { + case STRING: { + std::string str = value.string; + query_.NotEqualTo(field, str); + break; + } + case INTEGER: { + query_.NotEqualTo(field, value.integer); + break; + } + case FLOAT: { + query_.NotEqualTo(field, value.flo); + break; + } + case BOOLEAN: { + query_.NotEqualTo(field, value.boolean); + break; + } + case DOUBLE: { + query_.NotEqualTo(field, value.dou); + break; + } + default: { + break; + } + } +} + +void CQuery::GreaterThan(const std::string &field, ValueType &value) +{ + switch (value.tag) { + case STRING: { + std::string str = value.string; + query_.GreaterThan(field, str); + break; + } + case INTEGER: { + query_.GreaterThan(field, value.integer); + break; + } + case FLOAT: { + query_.GreaterThan(field, value.flo); + break; + } + case BOOLEAN: { + query_.GreaterThan(field, value.boolean); + break; + } + case DOUBLE: { + query_.GreaterThan(field, value.dou); + break; + } + default: { + break; + } + } +} + +void CQuery::LessThan(const std::string &field, ValueType &value) +{ + switch (value.tag) { + case STRING: { + std::string str = value.string; + query_.LessThan(field, str); + break; + } + case INTEGER: { + query_.LessThan(field, value.integer); + break; + } + case FLOAT: { + query_.LessThan(field, value.flo); + break; + } + case BOOLEAN: { + query_.LessThan(field, value.boolean); + break; + } + case DOUBLE: { + query_.LessThan(field, value.dou); + break; + } + default: { + break; + } + } +} + +void CQuery::GreaterThanOrEqualTo(const std::string &field, ValueType &value) +{ + switch (value.tag) { + case STRING: { + std::string str = value.string; + query_.GreaterThanOrEqualTo(field, str); + break; + } + case INTEGER: { + query_.GreaterThanOrEqualTo(field, value.integer); + break; + } + case FLOAT: { + query_.GreaterThanOrEqualTo(field, value.flo); + break; + } + case BOOLEAN: { + query_.GreaterThanOrEqualTo(field, value.boolean); + break; + } + case DOUBLE: { + query_.GreaterThanOrEqualTo(field, value.dou); + break; + } + default: { + break; + } + } +} + +void CQuery::LessThanOrEqualTo(const std::string &field, ValueType &value) +{ + switch (value.tag) { + case STRING: { + std::string str = value.string; + query_.LessThanOrEqualTo(field, str); + break; + } + case INTEGER: { + query_.LessThanOrEqualTo(field, value.integer); + break; + } + case FLOAT: { + query_.LessThanOrEqualTo(field, value.flo); + break; + } + case BOOLEAN: { + query_.LessThanOrEqualTo(field, value.boolean); + break; + } + case DOUBLE: { + query_.LessThanOrEqualTo(field, value.dou); + break; + } + default: { + break; + } + } +} + +void CQuery::IsNull(const std::string &field) +{ + query_.IsNull(field); +} + +void CQuery::InNumber(const std::string &field, const CArrNumber &valueList) +{ + switch (valueList.tag) { + case INTEGER: { + query_.In(field, std::vector(valueList.intList, valueList.intList + valueList.size)); + break; + } + case FLOAT: { + query_.In(field, std::vector(valueList.floatList, valueList.floatList + valueList.size)); + break; + } + case DOUBLE: { + query_.In(field, std::vector(valueList.doubleList, valueList.doubleList + valueList.size)); + break; + } + default: { + break; + } + } +} + +static std::vector CArrayStrToVectorString(const CArrStr &cArrStr) +{ + std::vector strs; + int64_t size = cArrStr.size; + for (int64_t i = 0; i < size; i++) { + std::string str = cArrStr.head[i]; + strs.push_back(str); + } + return strs; +} + +void CQuery::InString(const std::string &field, const CArrStr &valueList) +{ + query_.In(field, CArrayStrToVectorString(valueList)); +} + +void CQuery::NotInNumber(const std::string &field, const CArrNumber &valueList) +{ + switch (valueList.tag) { + case INTEGER: { + query_.NotIn(field, std::vector(valueList.intList, valueList.intList + valueList.size)); + break; + } + case FLOAT: { + query_.NotIn(field, std::vector(valueList.floatList, valueList.floatList + valueList.size)); + break; + } + case DOUBLE: { + query_.NotIn(field, std::vector(valueList.doubleList, valueList.doubleList + valueList.size)); + break; + } + default: { + break; + } + } +} + +void CQuery::NotInString(const std::string &field, const CArrStr &valueList) +{ + query_.NotIn(field, CArrayStrToVectorString(valueList)); +} + +void CQuery::Like(const std::string &field, const std::string &value) +{ + query_.Like(field, value); +} + +void CQuery::Unlike(const std::string &field, const std::string &value) +{ + query_.Unlike(field, value); +} + +void CQuery::And() +{ + query_.And(); +} + +void CQuery::Or() +{ + query_.Or(); +} + +void CQuery::OrderByAsc(const std::string &field) +{ + query_.OrderByAsc(field); +} + +void CQuery::OrderByDesc(const std::string &field) +{ + query_.OrderByDesc(field); +} + +void CQuery::Limit(int32_t total, int32_t offset) +{ + query_.Limit(total, offset); +} + +void CQuery::IsNotNull(const std::string &field) +{ + query_.IsNotNull(field); +} + +void CQuery::BeginGroup() +{ + query_.BeginGroup(); +} + +void CQuery::EndGroup() +{ + query_.EndGroup(); +} + +void CQuery::PrefixKey(const std::string &prefix) +{ + query_.KeyPrefix(prefix); +} + +void CQuery::SetSuggestIndex(const std::string &index) +{ + query_.SetSuggestIndex(index); +} + +void CQuery::DeviceId(const std::string &deviceId) +{ + query_.DeviceId(deviceId); +} + +const std::string CQuery::GetSqlLike() +{ + return query_.ToString(); +} + +CJKVManager::DeathRecipient::DeathRecipient(void (*callbackId)(), const std::function& callbackRef) +{ + if (callbackId == nullptr) { + LOGI("WARNING: nullptr"); + } + m_callbackId = callbackId; + m_callbackRef = callbackRef; +} + +void CJKVManager::DeathRecipient::OnRemoteDied() +{ + m_callbackRef(); +} + +CJSingleKVStore::DataObserver::DataObserver(void (*callbackId)(const CChangeNotification), + const std::function& callbackRef) +{ + if (callbackId == nullptr) { + LOGI("WARNING: nullptr"); + } + m_callbackId = callbackId; + m_callbackRef = callbackRef; +} + +void CJSingleKVStore::DataObserver::OnChange(const DistributedKv::ChangeNotification& notification) +{ + m_callbackRef(notification); +} + +CJSingleKVStore::SyncObserver::SyncObserver(void (*callbackId)(const CStringNum), + const std::function)>& callbackRef) +{ + if (callbackId == nullptr) { + LOGI("WARNING: nullptr"); + } + m_callbackId = callbackId; + m_callbackRef = callbackRef; +} + +void CJSingleKVStore::SyncObserver::SyncCompleted(const std::map& results) +{ + m_callbackRef(results); +} +} \ No newline at end of file diff --git a/frameworks/cj/src/distributed_kv_store_utils.cpp b/frameworks/cj/src/distributed_kv_store_utils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a1c1df00fb8d7eb7bceef200632ff2200823424b --- /dev/null +++ b/frameworks/cj/src/distributed_kv_store_utils.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "distributed_kv_store_utils.h" + +namespace OHOS { +namespace DistributedKVStore { + char* MallocCString(const std::string& origin) + { + if (origin.empty()) { + return nullptr; + } + auto len = origin.length() + 1; + char* res = static_cast(malloc(sizeof(char) * len)); + if (res == nullptr) { + return nullptr; + } + return std::char_traits::copy(res, origin.c_str(), len); + } + void FreeCString(char* str) + { + free(str); + } +} +} \ No newline at end of file diff --git a/frameworks/common/BUILD.gn b/frameworks/common/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..9b2388b7536e752cc5782ed89f3d6a8d0485cce6 --- /dev/null +++ b/frameworks/common/BUILD.gn @@ -0,0 +1,38 @@ +# 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/kv_store/kv_store.gni") +config("datamgr_common_config") { + visibility = [ ":*" ] + + include_dirs = [ + "${kv_store_base_path}/frameworks/common", + "${kv_store_base_path}/interfaces/innerkits/distributeddata/include", + ] +} + +ohos_static_library("datamgr_common") { + branch_protector_ret = "pac_ret" + sanitize = { + ubsan = true + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + } + cflags = [ "-Wno-c99-designator" ] + public_configs = [ ":datamgr_common_config" ] + + subsystem_name = "distributeddatamgr" + part_name = "kv_store" +} diff --git a/frameworks/common/block_data.h b/frameworks/common/block_data.h index 9c148b4687dde84cb2ba23b97c4013155d68e5fe..839df28720fa4e2215d13efa4d09946b7013b282 100644 --- a/frameworks/common/block_data.h +++ b/frameworks/common/block_data.h @@ -18,14 +18,13 @@ #include namespace OHOS { -template +template class BlockData { public: explicit BlockData(uint32_t interval, const T &invalid = T()) : INTERVAL(interval), data_(invalid) {} ~BlockData() {} -public: void SetValue(const T &data) { std::lock_guard lock(mutex_); @@ -37,7 +36,7 @@ public: T GetValue() { std::unique_lock lock(mutex_); - cv_.wait_for(lock, std::chrono::seconds(INTERVAL), [this]() { + cv_.wait_for(lock, Dur(INTERVAL), [this]() { return isSet_; }); T data = data_; diff --git a/frameworks/common/concurrent_map.h b/frameworks/common/concurrent_map.h index a1cb7286e4d9005c6bb3b59a3f7f58625b89b76a..747212eee05e1a2a5246166a094ec5ceeb3471f2 100644 --- a/frameworks/common/concurrent_map.h +++ b/frameworks/common/concurrent_map.h @@ -81,22 +81,22 @@ public: template typename std::enable_if()), filter_type>, bool>::type - Emplace(_Args &&...__args) noexcept + Emplace(_Args &&...args) noexcept { std::lock_guard lock(mutex_); - auto it = entries_.emplace(std::forward<_Args>(__args)...); + auto it = entries_.emplace(std::forward<_Args>(args)...); return it.second; } template typename std::enable_if, bool>::type - Emplace(const _Filter &filter, _Args &&...__args) noexcept + Emplace(const _Filter &filter, _Args &&...args) noexcept { std::lock_guard lock(mutex_); if (!filter(entries_)) { return false; } - auto it = entries_.emplace(std::forward<_Args>(__args)...); + auto it = entries_.emplace(std::forward<_Args>(args)...); return it.second; } @@ -111,6 +111,19 @@ public: return std::pair { true, it->second }; } + bool ContainIf(const key_type &key, const std::function &action) const noexcept + { + std::lock_guard lock(mutex_); + auto it = entries_.find(key); + if (it == entries_.end()) { + return false; + } + if (action) { + return action(it->second); + } + return true; + } + bool Contains(const key_type &key) const noexcept { std::lock_guard lock(mutex_); @@ -181,12 +194,6 @@ public: return count; } - mapped_type &operator[](const key_type &key) noexcept - { - std::lock_guard lock(mutex_); - return entries_[key]; - } - void ForEach(const std::function &action) { if (action == nullptr) { diff --git a/frameworks/common/itypes_util.h b/frameworks/common/itypes_util.h index f88cc7c86bdbb74dfaff5a4b2a6ab9ae729c0794..60ac43ed5e6f486027c31a508a6c7810fc4e2bc3 100644 --- a/frameworks/common/itypes_util.h +++ b/frameworks/common/itypes_util.h @@ -58,6 +58,16 @@ static inline bool Unmarshalling(int16_t &output, MessageParcel &data) return data.ReadInt16(output); } +static inline bool Marshalling(uint16_t input, MessageParcel &data) +{ + return data.WriteUint16(input); +} + +static inline bool Unmarshalling(uint16_t &output, MessageParcel &data) +{ + return data.ReadUint16(output); +} + static inline bool Marshalling(uint32_t input, MessageParcel &data) { return data.WriteUint32(input); @@ -128,6 +138,16 @@ static inline bool Unmarshalling(std::monostate &output, MessageParcel &data) return true; } +static inline bool Marshalling(const std::vector &input, MessageParcel &data) +{ + return data.WriteFloatVector(input); +} + +static inline bool Unmarshalling(std::vector &output, MessageParcel &data) +{ + return data.ReadFloatVector(&output); +} + static inline bool Marshalling(const std::string &input, MessageParcel &data) { return data.WriteString(input); @@ -138,6 +158,16 @@ static inline bool Unmarshalling(std::string &output, MessageParcel &data) return data.ReadString(output); } +static inline bool Marshalling(const std::u16string &input, MessageParcel &data) +{ + return data.WriteString16(input); +} + +static inline bool Unmarshalling(std::u16string &output, MessageParcel &data) +{ + return data.ReadString16(output); +} + static inline bool Marshalling(const std::vector &input, MessageParcel &data) { return data.WriteUInt8Vector(input); @@ -298,10 +328,7 @@ bool ITypesUtil::Marshalling(const std::map &result, MessageParcel &parcel return false; } for (const auto &entry : result) { - if (!ITypesUtil::Marshalling(entry.first, parcel)) { - return false; - } - if (!ITypesUtil::Marshalling(entry.second, parcel)) { + if ((!ITypesUtil::Marshalling(entry.first, parcel)) || (!ITypesUtil::Marshalling(entry.second, parcel))) { return false; } } @@ -326,10 +353,7 @@ bool ITypesUtil::Unmarshalling(std::map &val, MessageParcel &parcel) for (int32_t i = 0; i < size; i++) { K key; - if (!ITypesUtil::Unmarshalling(key, parcel)) { - return false; - } - if (!ITypesUtil::Unmarshalling(val[key], parcel)) { + if ((!ITypesUtil::Unmarshalling(key, parcel)) || (!ITypesUtil::Unmarshalling(val[key], parcel))) { return false; } } diff --git a/frameworks/common/js_proxy.h b/frameworks/common/js_proxy.h new file mode 100644 index 0000000000000000000000000000000000000000..19b5dccedc3a9471dcd1ca3b6c32f5e4d5a5fd46 --- /dev/null +++ b/frameworks/common/js_proxy.h @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2023 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef OHOS_DISTRIBUTED_DATA_FRAMEWORKS_COMMON_JS_PROXY_H +#define OHOS_DISTRIBUTED_DATA_FRAMEWORKS_COMMON_JS_PROXY_H +#include +namespace OHOS::JSProxy { +template +class JSCreator { +public: + // This method will be used to call different subclasses for implementation + virtual std::shared_ptr Create() = 0; + +protected: + // It is not allowed to directly use parent class objects for construction and destruction + JSCreator() = default; + ~JSCreator() = default; +}; + +template +class JSProxy { +public: + void SetInstance(std::shared_ptr instance) + { + instance_ = std::move(instance); + } + + std::shared_ptr GetInstance() const + { + return instance_; + } + +protected: + // It is not allowed to directly use parent class objects for construction and destruction + JSProxy() = default; + ~JSProxy() = default; + +private: + std::shared_ptr instance_; +}; + +template +class JSEntity : public JSCreator, public JSProxy { +protected: + // It is not allowed to directly use parent class objects for construction and destruction + JSEntity() = default; + ~JSEntity() = default; +}; +} // namespace OHOS::JSProxy +#endif // OHOS_DISTRIBUTED_DATA_FRAMEWORKS_COMMON_JS_PROXY_H diff --git a/frameworks/common/log_print.h b/frameworks/common/log_print.h index b2ab441fca6b24939e0a1bbeaab8c59f3bde228e..76dfee9c0bf1f6db515ebf519ff492a4203a7c51 100644 --- a/frameworks/common/log_print.h +++ b/frameworks/common/log_print.h @@ -90,47 +90,54 @@ static inline OHOS::HiviewDFX::HiLogLabel LogLabel() return { LOG_CORE, 0xD001656, "DSRCH" }; } } // end namespace DataSearchable + +namespace ConnectInner { + static inline OHOS::HiviewDFX::HiLogLabel LogLabel() + { + return { LOG_CORE, 0xD001610, "Connect" }; + } +} // end namespace ConnectInner } // end namespace OHOS -#define ZLOGD(fmt, ...) \ - do { \ - using HiLog = OHOS::HiviewDFX::HiLog; \ - auto lable = LogLabel(); \ - if (!HiLogIsLoggable(lable.domain, lable.tag, LOG_DEBUG)) { \ - break; \ - } \ - HiLog::Debug(lable, LOG_TAG "::%{public}s: " fmt, __FUNCTION__, ##__VA_ARGS__); \ +#define ZLOGD(fmt, ...) \ + do { \ + auto lable = LogLabel(); \ + if (!HiLogIsLoggable(lable.domain, LOG_TAG, LOG_DEBUG)) { \ + break; \ + } \ + ((void)HILOG_IMPL(lable.type, LOG_DEBUG, lable.domain, LOG_TAG, \ + "%{public}s: " fmt, __FUNCTION__, ##__VA_ARGS__)); \ } while (0) -#define ZLOGI(fmt, ...) \ - do { \ - using HiLog = OHOS::HiviewDFX::HiLog; \ - auto lable = LogLabel(); \ - if (!HiLogIsLoggable(lable.domain, lable.tag, LOG_INFO)) { \ - break; \ - } \ - HiLog::Info(lable, LOG_TAG "::%{public}s: " fmt, __FUNCTION__, ##__VA_ARGS__); \ +#define ZLOGI(fmt, ...) \ + do { \ + auto lable = LogLabel(); \ + if (!HiLogIsLoggable(lable.domain, LOG_TAG, LOG_INFO)) { \ + break; \ + } \ + ((void)HILOG_IMPL(lable.type, LOG_INFO, lable.domain, LOG_TAG, \ + "%{public}s: " fmt, __FUNCTION__, ##__VA_ARGS__)); \ } while (0) -#define ZLOGW(fmt, ...) \ - do { \ - using HiLog = OHOS::HiviewDFX::HiLog; \ - auto lable = LogLabel(); \ - if (!HiLogIsLoggable(lable.domain, lable.tag, LOG_WARN)) { \ - break; \ - } \ - HiLog::Warn(lable, LOG_TAG "::%{public}s: " fmt, __FUNCTION__, ##__VA_ARGS__); \ +#define ZLOGW(fmt, ...) \ + do { \ + auto lable = LogLabel(); \ + if (!HiLogIsLoggable(lable.domain, LOG_TAG, LOG_WARN)) { \ + break; \ + } \ + ((void)HILOG_IMPL(lable.type, LOG_WARN, lable.domain, LOG_TAG, \ + "%{public}s: " fmt, __FUNCTION__, ##__VA_ARGS__)); \ } while (0) -#define ZLOGE(fmt, ...) \ - do { \ - using HiLog = OHOS::HiviewDFX::HiLog; \ - auto lable = LogLabel(); \ - if (!HiLogIsLoggable(lable.domain, lable.tag, LOG_ERROR)) { \ - break; \ - } \ - HiLog::Error(lable, LOG_TAG "::%{public}s: " fmt, __FUNCTION__, ##__VA_ARGS__); \ - } while (0) +#define ZLOGE(fmt, ...) \ + do { \ + auto lable = LogLabel(); \ + if (!HiLogIsLoggable(lable.domain, LOG_TAG, LOG_ERROR)) { \ + break; \ + } \ + ((void)HILOG_IMPL(lable.type, LOG_ERROR, lable.domain, LOG_TAG, \ + "%{public}s: " fmt, __FUNCTION__, ##__VA_ARGS__)); \ + } while (0) \ #else #error // unknown system diff --git a/frameworks/common/lru_bucket.h b/frameworks/common/lru_bucket.h index ff4437855f993ca8e72546d10546c367c5bfe075..a8db5a2649cd4d89d806346f2a55d632848adbfe 100644 --- a/frameworks/common/lru_bucket.h +++ b/frameworks/common/lru_bucket.h @@ -18,12 +18,13 @@ #include #include -#include - +#include namespace OHOS { template class LRUBucket { public: + using LRUMemento = std::pair, std::vector<_Tp>>; + LRUBucket(size_t capacity) : size_(0), capacity_(capacity) {} @@ -40,6 +41,33 @@ public: } } + bool Initialize(const LRUMemento &memento) + { + auto &[keys, values] = memento; + std::lock_guard lock(mutex_); + while (size_ > 0) { + PopBack(); + } + + if (capacity_ < keys.size()) { + capacity_ = keys.size(); + } + + size_t i = 0; + for (auto &key : keys) { + auto *node = new(std::nothrow) Node(i < values.size() ? values[i] : _Tp()); + i++; + if (node == nullptr) { + return false; + } + + Insert(&head_, node); + auto pair = indexes_.emplace(key, node); + node->iterator_ = pair.first; + } + return true; + } + size_t Size() const { return size_; @@ -68,7 +96,7 @@ public: std::lock_guard lock(mutex_); auto it = indexes_.find(key); if (it != indexes_.end()) { - if (isLRU) { + if (isLRU && !IsLRUHeader(it->second)) { // move node from the list; Remove(it->second); // insert node to the head @@ -80,6 +108,26 @@ public: return false; } + /** + * The time complexity is O(log(index size)) + **/ + std::pair Contains(const _Key &key, bool isLRU = true) + { + std::lock_guard lock(mutex_); + auto it = indexes_.find(key); + if (it != indexes_.end()) { + if ((isLRU && !IsLRUHeader(it->second))) { + // move node from the list; + Remove(it->second); + // insert node to the head + Insert(&head_, it->second); + return { true, true }; + } + return { true, false }; + } + return { false, false }; + } + /** * The time complexity is O(log(index size)) **/ @@ -170,6 +218,12 @@ public: return false; } + LRUMemento DumpMemento() + { + std::lock_guard lock(mutex_); + return ToMemento(); + } + private: struct Node final { using iterator = typename std::map<_Key, Node *>::iterator; @@ -216,7 +270,27 @@ private: delete node; } - mutable std::recursive_mutex mutex_; + bool IsLRUHeader(Node *node) + { + return (node == head_.next_ || node == &head_); + } + + std::pair, std::vector<_Tp>> ToMemento() + { + std::pair, std::vector<_Tp>> memento; + auto &[keys, values] = memento; + auto current = head_.prev_; + size_t i = 0; + while (current != &head_ && i < size_) { + keys.emplace_back(current->iterator_->first); + values.emplace_back(current->value_); + current = current->prev_; + i++; + } + return memento; + } + + mutable std::mutex mutex_; std::map<_Key, Node *> indexes_; Node head_; size_t size_; diff --git a/frameworks/common/test/BUILD.gn b/frameworks/common/test/BUILD.gn index 6029e40392d41be792d59d4b4a1d40c0d49865b8..cf928c8176074c437768e4a0cdd056009f88e803 100644 --- a/frameworks/common/test/BUILD.gn +++ b/frameworks/common/test/BUILD.gn @@ -13,12 +13,14 @@ import("//build/test.gni") import("//foundation/distributeddatamgr/kv_store/kv_store.gni") -module_output_path = "kv_store/common" +module_output_path = "kv_store/kv_store/common" ############################################################################### config("module_private_config") { visibility = [ ":*" ] + cflags = [ "-Wno-c99-designator" ] + include_dirs = [ "../", "${kv_store_base_path}/interfaces/innerkits/distributeddata/include", @@ -35,13 +37,13 @@ ohos_unittest("ConcurrentMapTest") { external_deps = [ "c_utils:utils", + "googletest:gtest", "hilog:libhilog", "ipc:ipc_single", "safwk:system_ability_fwk", "samgr:samgr_proxy", ] - deps = [ "//third_party/googletest:gtest" ] } ohos_unittest("ExecutorPoolTest") { @@ -51,9 +53,12 @@ ohos_unittest("ExecutorPoolTest") { configs = [ ":module_private_config" ] - external_deps = [ "c_utils:utils" ] + external_deps = [ + "c_utils:utils", + "googletest:gtest", + "hilog:libhilog", + ] - deps = [ "//third_party/googletest:gtest" ] } ohos_unittest("LruBucketTest") { @@ -63,9 +68,12 @@ ohos_unittest("LruBucketTest") { configs = [ ":module_private_config" ] - external_deps = [ "c_utils:utils" ] + external_deps = [ + "c_utils:utils", + "googletest:gtest", + "hilog:libhilog", + ] - deps = [ "//third_party/googletest:gtest" ] } ohos_unittest("TaskSchedulerTest") { @@ -75,9 +83,12 @@ ohos_unittest("TaskSchedulerTest") { configs = [ ":module_private_config" ] - external_deps = [ "c_utils:utils" ] + external_deps = [ + "c_utils:utils", + "googletest:gtest", + "hilog:libhilog", + ] - deps = [ "//third_party/googletest:gtest" ] } ohos_unittest("TraitsTest") { @@ -87,9 +98,12 @@ ohos_unittest("TraitsTest") { configs = [ ":module_private_config" ] - external_deps = [ "c_utils:utils" ] + external_deps = [ + "c_utils:utils", + "googletest:gtest", + "hilog:libhilog", + ] - deps = [ "//third_party/googletest:gtest" ] } ohos_unittest("PoolTest") { @@ -99,15 +113,33 @@ ohos_unittest("PoolTest") { configs = [ ":module_private_config" ] + external_deps = [ + "c_utils:utils", + "googletest:gtest", + "hilog:libhilog", + "ipc:ipc_single", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", + ] + +} + +ohos_unittest("PriorityQueueTest") { + module_out_path = module_output_path + + sources = [ "priority_queue_test.cpp" ] + + configs = [ ":module_private_config" ] + external_deps = [ "c_utils:utils", "hilog:libhilog", + "googletest:gtest", "ipc:ipc_single", "safwk:system_ability_fwk", "samgr:samgr_proxy", ] - deps = [ "//third_party/googletest:gtest" ] } ############################################################################### @@ -120,6 +152,7 @@ group("unittest") { ":ExecutorPoolTest", ":LruBucketTest", ":PoolTest", + ":PriorityQueueTest", ":TaskSchedulerTest", ":TraitsTest", ] diff --git a/frameworks/common/test/concurrent_map_test.cpp b/frameworks/common/test/concurrent_map_test.cpp index 0ef31a6870c7600cc4a243710415e6cbe4fa85f0..eeb1cdeec26849048bfc0dc04ed12cbdce827a20 100644 --- a/frameworks/common/test/concurrent_map_test.cpp +++ b/frameworks/common/test/concurrent_map_test.cpp @@ -19,7 +19,8 @@ #include "gtest/gtest.h" using namespace testing::ext; namespace OHOS::Test { -template using ConcurrentMap = OHOS::ConcurrentMap<_Key, _Tp>; +template +using ConcurrentMap = OHOS::ConcurrentMap<_Key, _Tp>; class ConcurrentMapTest : public testing::Test { public: struct TestValue { @@ -27,9 +28,9 @@ public: std::string name; std::string testCase; }; - static void SetUpTestCase(void) {} + static void SetUpTestCase(void) { } - static void TearDownTestCase(void) {} + static void TearDownTestCase(void) { } protected: void SetUp() @@ -46,12 +47,12 @@ protected: }; /** -* @tc.name: EmplaceWithNone -* @tc.desc: test the bool Emplace() noexcept function. -* @tc.type: FUNC -* @tc.require: -* @tc.author: Sven Wang -*/ + * @tc.name: EmplaceWithNone + * @tc.desc: test the bool Emplace() noexcept function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ HWTEST_F(ConcurrentMapTest, EmplaceWithNone, TestSize.Level0) { values_.Emplace(); @@ -60,28 +61,28 @@ HWTEST_F(ConcurrentMapTest, EmplaceWithNone, TestSize.Level0) } /** -* @tc.name: EmplaceWithFilter -* @tc.desc: test the function: + * @tc.name: EmplaceWithFilter + * @tc.desc: test the function: * template * typename std::enable_if, bool>::type - * Emplace(const _Filter &filter, _Args &&...__args) noexcept -* @tc.type: FUNC -* @tc.require: -* @tc.author: Sven Wang -*/ + * Emplace(const _Filter &filter, _Args &&...args) noexcept + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ HWTEST_F(ConcurrentMapTest, EmplaceWithFilter, TestSize.Level0) { auto success = values_.Emplace( [](const decltype(values_)::map_type &entries) { return (entries.find("test") == entries.end()); }, - "test", TestValue{ "id", "name", "test case" }); + "test", TestValue { "id", "name", "test case" }); ASSERT_TRUE(success); success = values_.Emplace( [](const decltype(values_)::map_type &entries) { return (entries.find("test") == entries.end()); }, - "test", TestValue{ "id", "name", "test case" }); + "test", TestValue { "id", "name", "test case" }); ASSERT_TRUE(!success); success = values_.Emplace( [](decltype(values_)::map_type &entries) { @@ -92,20 +93,20 @@ HWTEST_F(ConcurrentMapTest, EmplaceWithFilter, TestSize.Level0) } return (it == entries.end()); }, - "test", TestValue{ "id", "name", "test case" }); + "test", TestValue { "id", "name", "test case" }); ASSERT_TRUE(success); } /** -* @tc.name: EmplaceWithArgs -* @tc.desc: test the function: + * @tc.name: EmplaceWithArgs + * @tc.desc: test the function: * template * typename std::enable_if()), filter_type>, bool>::type - * Emplace(_Args &&...__args) noexcept -* @tc.type: FUNC -* @tc.require: -* @tc.author: Sven Wang -*/ + * Emplace(_Args &&...args) noexcept + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ HWTEST_F(ConcurrentMapTest, EmplaceWithArgs, TestSize.Level0) { TestValue value = { "id", "name", "test case" }; diff --git a/frameworks/common/test/executor_pool_test.cpp b/frameworks/common/test/executor_pool_test.cpp index 6dbea3eb2d2b030939b853edf8126944849f624e..bef0fb7de76f1f39da3ae2a47897e3e100915ca7 100644 --- a/frameworks/common/test/executor_pool_test.cpp +++ b/frameworks/common/test/executor_pool_test.cpp @@ -1,17 +1,17 @@ /* -* Copyright (c) 2023 Huawei Device Co., Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "block_data.h" @@ -35,23 +35,23 @@ public: static constexpr uint32_t SHORT_INTERVAL = 100; // ms static constexpr uint32_t LONG_INTERVAL = 1; // s static std::shared_ptr executorPool_; - static void SetUpTestCase(void){}; + static void SetUpTestCase(void) {}; static void TearDownTestCase(void) { executorPool_ = nullptr; }; - void SetUp(){}; - void TearDown() {} + void SetUp() {}; + void TearDown() { } }; std::shared_ptr ExecutorPoolTest::executorPool_ = std::make_shared(12, 5); /** -* @tc.name: Execute -* @tc.desc: -* @tc.type: FUNC -* @tc.require: -* @tc.author: CRJ -*/ + * @tc.name: Execute + * @tc.desc: + * @tc.type: FUNC + * @tc.require: + * @tc.author: CRJ + */ HWTEST_F(ExecutorPoolTest, Execute, TestSize.Level0) { auto expiredTime = std::chrono::milliseconds(SHORT_INTERVAL); @@ -72,12 +72,12 @@ HWTEST_F(ExecutorPoolTest, Execute, TestSize.Level0) } /** -* @tc.name: Schedule -* @tc.desc: -* @tc.type: FUNC -* @tc.require: -* @tc.author: CRJ -*/ + * @tc.name: Schedule + * @tc.desc: + * @tc.type: FUNC + * @tc.require: + * @tc.author: CRJ + */ HWTEST_F(ExecutorPoolTest, Schedule, TestSize.Level0) { auto expiredTime = std::chrono::milliseconds(SHORT_INTERVAL); @@ -88,18 +88,18 @@ HWTEST_F(ExecutorPoolTest, Schedule, TestSize.Level0) }, expiredTime); ASSERT_NE(taskId, ExecutorPool::INVALID_TASK_ID); - std::this_thread::sleep_for(std::chrono::milliseconds(SHORT_INTERVAL * 10)); - ASSERT_EQ(testData->data, 10); + std::this_thread::sleep_for(std::chrono::milliseconds(SHORT_INTERVAL * 12)); + ASSERT_GT(testData->data, 10); executorPool_->Remove(taskId); } /** -* @tc.name: MultiSchedule -* @tc.desc: -* @tc.type: FUNC -* @tc.require: -* @tc.author: CRJ -*/ + * @tc.name: MultiSchedule + * @tc.desc: + * @tc.type: FUNC + * @tc.require: + * @tc.author: CRJ + */ HWTEST_F(ExecutorPoolTest, MultiSchedule, TestSize.Level0) { auto data = std::make_shared(); @@ -119,12 +119,12 @@ HWTEST_F(ExecutorPoolTest, MultiSchedule, TestSize.Level0) } } /** -* @tc.name: Remove -* @tc.desc: -* @tc.type: FUNC -* @tc.require: -* @tc.author: CRJ -*/ + * @tc.name: Remove + * @tc.desc: + * @tc.type: FUNC + * @tc.require: + * @tc.author: CRJ + */ HWTEST_F(ExecutorPoolTest, Remove, TestSize.Level0) { auto expiredTime = std::chrono::milliseconds(SHORT_INTERVAL); @@ -140,12 +140,12 @@ HWTEST_F(ExecutorPoolTest, Remove, TestSize.Level0) ASSERT_EQ(data->data, 1); } /** -* @tc.name: Reset -* @tc.desc: -* @tc.type: FUNC -* @tc.require: -* @tc.author: CRJ -*/ + * @tc.name: Reset + * @tc.desc: + * @tc.type: FUNC + * @tc.require: + * @tc.author: CRJ + */ HWTEST_F(ExecutorPoolTest, Reset, TestSize.Level0) { auto expiredTime = std::chrono::milliseconds(SHORT_INTERVAL); @@ -163,12 +163,12 @@ HWTEST_F(ExecutorPoolTest, Reset, TestSize.Level0) } /** -* @tc.name: MaxEqualsOne -* @tc.desc: -* @tc.type: FUNC -* @tc.require: -* @tc.author: CRJ -*/ + * @tc.name: MaxEqualsOne + * @tc.desc: + * @tc.type: FUNC + * @tc.require: + * @tc.author: CRJ + */ HWTEST_F(ExecutorPoolTest, MaxEqualsOne, TestSize.Level0) { auto executors = std::make_shared(1, 0); @@ -189,12 +189,12 @@ HWTEST_F(ExecutorPoolTest, MaxEqualsOne, TestSize.Level0) } /** -* @tc.name: RemoveInExcuteTask -* @tc.desc: test remove task when the task is running. -* @tc.type: FUNC -* @tc.require: -* @tc.author: ht -*/ + * @tc.name: RemoveInExcuteTask + * @tc.desc: test remove task when the task is running. + * @tc.type: FUNC + * @tc.require: + * @tc.author: ht + */ HWTEST_F(ExecutorPoolTest, RemoveWhenExcute, TestSize.Level0) { auto executors = std::make_shared(1, 1); diff --git a/frameworks/common/test/lru_bucket_test.cpp b/frameworks/common/test/lru_bucket_test.cpp index 50f7dfbf66d9fa366b3ebc75abd896cb9bdb092e..fbbe2458413568f524b11ae1de60af8e0822027d 100644 --- a/frameworks/common/test/lru_bucket_test.cpp +++ b/frameworks/common/test/lru_bucket_test.cpp @@ -19,7 +19,8 @@ #include "gtest/gtest.h" namespace OHOS::Test { using namespace testing::ext; -template using LRUBucket = OHOS::LRUBucket<_Key, _Tp>; +template +using LRUBucket = OHOS::LRUBucket<_Key, _Tp>; class LRUBucketTest : public testing::Test { public: @@ -30,9 +31,9 @@ public: }; static constexpr size_t TEST_CAPACITY = 10; - static void SetUpTestCase(void) {} + static void SetUpTestCase(void) { } - static void TearDownTestCase(void) {} + static void TearDownTestCase(void) { } protected: void SetUp() @@ -41,26 +42,26 @@ protected: bucket_.ResetCapacity(TEST_CAPACITY); for (size_t i = 0; i < TEST_CAPACITY; ++i) { std::string key = std::string("test_") + std::to_string(i); - TestValue value = {key, key, "case"}; + TestValue value = { key, key, "case" }; bucket_.Set(key, value); } } - void TearDown() {} + void TearDown() { } - LRUBucket bucket_{TEST_CAPACITY}; + LRUBucket bucket_ { TEST_CAPACITY }; }; /** -* @tc.name: insert -* @tc.desc: Set the value to the lru bucket, whose capacity is more than one. -* @tc.type: FUNC -* @tc.require: -* @tc.author: Sven Wang -*/ + * @tc.name: insert + * @tc.desc: Set the value to the lru bucket, whose capacity is more than one. + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ HWTEST_F(LRUBucketTest, insert, TestSize.Level0) { - bucket_.Set("test_10", {"test_10", "test_10", "case"}); + bucket_.Set("test_10", { "test_10", "test_10", "case" }); TestValue value; ASSERT_TRUE(!bucket_.Get("test_0", value)); ASSERT_TRUE(bucket_.Get("test_6", value)); @@ -71,18 +72,18 @@ HWTEST_F(LRUBucketTest, insert, TestSize.Level0) } /** -* @tc.name: cap_one_insert -* @tc.desc: Set the value to the lru bucket, whose capacity is one. -* @tc.type: FUNC -* @tc.require: -* @tc.author: Sven Wang -*/ + * @tc.name: cap_one_insert + * @tc.desc: Set the value to the lru bucket, whose capacity is one. + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ HWTEST_F(LRUBucketTest, cap_one_insert, TestSize.Level0) { bucket_.ResetCapacity(1); for (size_t i = 0; i <= TEST_CAPACITY; ++i) { std::string key = std::string("test_") + std::to_string(i); - TestValue value = {key, key, "find"}; + TestValue value = { key, key, "find" }; bucket_.Set(key, value); } TestValue value; @@ -91,18 +92,18 @@ HWTEST_F(LRUBucketTest, cap_one_insert, TestSize.Level0) } /** -* @tc.name: cap_zero_insert -* @tc.desc: Set the value to the lru bucket, whose capacity is zero. -* @tc.type: FUNC -* @tc.require: -* @tc.author: Sven Wang -*/ + * @tc.name: cap_zero_insert + * @tc.desc: Set the value to the lru bucket, whose capacity is zero. + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ HWTEST_F(LRUBucketTest, cap_zero_insert, TestSize.Level0) { bucket_.ResetCapacity(0); for (size_t i = 0; i <= TEST_CAPACITY; ++i) { std::string key = std::string("test_") + std::to_string(i); - TestValue value = {key, key, "find"}; + TestValue value = { key, key, "find" }; bucket_.Set(key, value); } TestValue value; @@ -110,12 +111,12 @@ HWTEST_F(LRUBucketTest, cap_zero_insert, TestSize.Level0) } /** -* @tc.name: find_head -* @tc.desc: find the head element from the lru bucket. -* @tc.type: FUNC -* @tc.require: -* @tc.author: Sven Wang -*/ + * @tc.name: find_head + * @tc.desc: find the head element from the lru bucket. + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ HWTEST_F(LRUBucketTest, find_head, TestSize.Level0) { TestValue value; @@ -126,12 +127,12 @@ HWTEST_F(LRUBucketTest, find_head, TestSize.Level0) } /** -* @tc.name: find_tail -* @tc.desc: find the tail element, then the element will move to head. -* @tc.type: FUNC -* @tc.require: -* @tc.author: Sven Wang -*/ + * @tc.name: find_tail + * @tc.desc: find the tail element, then the element will move to head. + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ HWTEST_F(LRUBucketTest, find_tail, TestSize.Level0) { TestValue value; @@ -143,12 +144,12 @@ HWTEST_F(LRUBucketTest, find_tail, TestSize.Level0) } /** -* @tc.name: find_mid -* @tc.desc: find the mid element, then the element will move to head. -* @tc.type: FUNC -* @tc.require: -* @tc.author: Sven Wang -*/ + * @tc.name: find_mid + * @tc.desc: find the mid element, then the element will move to head. + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ HWTEST_F(LRUBucketTest, find_mid, TestSize.Level0) { TestValue value; @@ -160,22 +161,22 @@ HWTEST_F(LRUBucketTest, find_mid, TestSize.Level0) } /** -* @tc.name: find_and_insert -* @tc.desc: find the tail element, then the element will move to head. -* @tc.type: FUNC -* @tc.require: -* @tc.author: Sven Wang -*/ + * @tc.name: find_and_insert + * @tc.desc: find the tail element, then the element will move to head. + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ HWTEST_F(LRUBucketTest, find_and_insert, TestSize.Level0) { TestValue value; if (!bucket_.Get("MyTest", value)) { - bucket_.Set("MyTest", {"MyTest", "MyTest", "case"}); + bucket_.Set("MyTest", { "MyTest", "MyTest", "case" }); } ASSERT_TRUE(bucket_.Get("MyTest", value)); if (!bucket_.Get("test_0", value)) { - bucket_.Set("test_0", {"test_0", "test_0", "case"}); + bucket_.Set("test_0", { "test_0", "test_0", "case" }); } ASSERT_TRUE(bucket_.Get("test_0", value)); ASSERT_TRUE(bucket_.Get("test_5", value)); @@ -185,12 +186,12 @@ HWTEST_F(LRUBucketTest, find_and_insert, TestSize.Level0) } /** -* @tc.name: del_head -* @tc.desc: delete the head element, then the next element will move to head. -* @tc.type: FUNC -* @tc.require: -* @tc.author: Sven Wang -*/ + * @tc.name: del_head + * @tc.desc: delete the head element, then the next element will move to head. + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ HWTEST_F(LRUBucketTest, del_head, TestSize.Level0) { TestValue value; @@ -203,12 +204,12 @@ HWTEST_F(LRUBucketTest, del_head, TestSize.Level0) } /** -* @tc.name: del_head -* @tc.desc: delete the tail element, then the lru chain keep valid. -* @tc.type: FUNC -* @tc.require: -* @tc.author: Sven Wang -*/ + * @tc.name: del_head + * @tc.desc: delete the tail element, then the lru chain keep valid. + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ HWTEST_F(LRUBucketTest, del_tail, TestSize.Level0) { TestValue value; @@ -222,12 +223,12 @@ HWTEST_F(LRUBucketTest, del_tail, TestSize.Level0) } /** -* @tc.name: del_mid -* @tc.desc: delete the mid element, then the lru chain keep valid. -* @tc.type: FUNC -* @tc.require: -* @tc.author: Sven Wang -*/ + * @tc.name: del_mid + * @tc.desc: delete the mid element, then the lru chain keep valid. + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ HWTEST_F(LRUBucketTest, del_mid, TestSize.Level0) { TestValue value; @@ -243,12 +244,12 @@ HWTEST_F(LRUBucketTest, del_mid, TestSize.Level0) } /** -* @tc.name: del_mid -* @tc.desc: the lru bucket has only one element, then delete it. -* @tc.type: FUNC -* @tc.require: -* @tc.author: Sven Wang -*/ + * @tc.name: del_mid + * @tc.desc: the lru bucket has only one element, then delete it. + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ HWTEST_F(LRUBucketTest, cap_one_del, TestSize.Level0) { TestValue value; @@ -258,12 +259,12 @@ HWTEST_F(LRUBucketTest, cap_one_del, TestSize.Level0) } /** -* @tc.name: del_mid -* @tc.desc: the lru bucket has no element. -* @tc.type: FUNC -* @tc.require: -* @tc.author: Sven Wang -*/ + * @tc.name: del_mid + * @tc.desc: the lru bucket has no element. + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ HWTEST_F(LRUBucketTest, cap_zero_del, TestSize.Level0) { TestValue value; @@ -273,19 +274,19 @@ HWTEST_F(LRUBucketTest, cap_zero_del, TestSize.Level0) } /** -* @tc.name: update_one -* @tc.desc: update the value and the lru chain won't change. -* @tc.type: FUNC -* @tc.require: -* @tc.author: Sven Wang -*/ + * @tc.name: update_one + * @tc.desc: update the value and the lru chain won't change. + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ HWTEST_F(LRUBucketTest, update_one, TestSize.Level0) { TestValue value; - ASSERT_TRUE(bucket_.Update("test_4", {"test_4", "test_4", "update"})); + ASSERT_TRUE(bucket_.Update("test_4", { "test_4", "test_4", "update" })); ASSERT_TRUE(bucket_.Get("test_4", value)); ASSERT_TRUE(value.testCase == "update"); - ASSERT_TRUE(bucket_.Update("test_9", {"test_9", "test_9", "update"})); + ASSERT_TRUE(bucket_.Update("test_9", { "test_9", "test_9", "update" })); ASSERT_TRUE(bucket_.ResetCapacity(1)); ASSERT_TRUE(bucket_.Capacity() == 1); ASSERT_TRUE(bucket_.Size() <= 1); @@ -294,18 +295,20 @@ HWTEST_F(LRUBucketTest, update_one, TestSize.Level0) } /** -* @tc.name: update_several -* @tc.desc: update several values and the lru chain won't change. -* @tc.type: FUNC -* @tc.require: -* @tc.author: Sven Wang -*/ + * @tc.name: update_several + * @tc.desc: update several values and the lru chain won't change. + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ HWTEST_F(LRUBucketTest, update_several, TestSize.Level0) { TestValue value; - std::map values = {{"test_2", {"test_2", "test_2", "update"}}, - {"test_3", {"test_3", "test_3", "update"}}, - {"test_6", {"test_6", "test_6", "update"}}}; + std::map values = { + { "test_2", { "test_2", "test_2", "update" } }, + { "test_3", { "test_3", "test_3", "update" } }, + { "test_6", { "test_6", "test_6", "update" } } + }; ASSERT_TRUE(bucket_.Update(values)); ASSERT_TRUE(bucket_.ResetCapacity(3)); ASSERT_TRUE(bucket_.Capacity() == 3); @@ -317,4 +320,299 @@ HWTEST_F(LRUBucketTest, update_several, TestSize.Level0) ASSERT_TRUE(bucket_.Get("test_8", value)); ASSERT_TRUE(bucket_.Get("test_7", value)); } + +/** + * @tc.name: Contains + * @tc.desc: contains the key and change the lru position. + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ +HWTEST_F(LRUBucketTest, contains_with_change, TestSize.Level0) +{ + std::vector keys = { + "deviceId0", "deviceId1", "deviceId2", "deviceId3", "deviceId4", + "deviceId5", "deviceId6", "deviceId7", "deviceId8", "deviceId9", + }; + std::vector values = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + LRUBucket bucket{ TEST_CAPACITY }; + auto success = bucket.Initialize({ keys, values }); + ASSERT_TRUE(success); + auto [exists, changed] = bucket.Contains("deviceId0"); + ASSERT_TRUE(exists); + ASSERT_TRUE(changed); + auto [keyMemo, valMemo] = bucket.DumpMemento(); + std::vector keyTag = { + "deviceId1", "deviceId2", "deviceId3", "deviceId4", "deviceId5", + "deviceId6", "deviceId7", "deviceId8", "deviceId9", "deviceId0", + }; + std::vector valTag = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; + EXPECT_EQ(keyMemo, keyTag); + EXPECT_EQ(valMemo, valTag); + + std::tie(exists, changed) = bucket.Contains("deviceId5"); + ASSERT_TRUE(exists); + ASSERT_TRUE(changed); + std::tie(keyMemo, valMemo) = bucket.DumpMemento(); + keyTag = { + "deviceId1", "deviceId2", "deviceId3", "deviceId4", "deviceId6", + "deviceId7", "deviceId8", "deviceId9", "deviceId0", "deviceId5", + }; + valTag = { 1, 2, 3, 4, 6, 7, 8, 9, 0, 5 }; + EXPECT_EQ(keyMemo, keyTag); + EXPECT_EQ(valMemo, valTag); +} + +/** + * @tc.name: Contains + * @tc.desc: contains the key and change the lru position. + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ +HWTEST_F(LRUBucketTest, contains_with_change_base5, TestSize.Level0) +{ + std::vector keys = { + "deviceId0", "deviceId1", "deviceId2", "deviceId3", "deviceId4", + }; + std::vector values = { 0, 1, 2, 3, 4 }; + LRUBucket bucket{ TEST_CAPACITY }; + auto success = bucket.Initialize({ keys, values }); + ASSERT_TRUE(success); + auto [exists, changed] = bucket.Contains("deviceId0"); + ASSERT_TRUE(exists); + ASSERT_TRUE(changed); + auto [keyMemo, valMemo] = bucket.DumpMemento(); + std::vector keyTag = { + "deviceId1", "deviceId2", "deviceId3", "deviceId4", "deviceId0", + }; + std::vector valTag = { 1, 2, 3, 4, 0 }; + EXPECT_EQ(keyMemo, keyTag); + EXPECT_EQ(valMemo, valTag); + + std::tie(exists, changed) = bucket.Contains("deviceId3"); + ASSERT_TRUE(exists); + ASSERT_TRUE(changed); + std::tie(keyMemo, valMemo) = bucket.DumpMemento(); + keyTag = { + "deviceId1", "deviceId2", "deviceId4", "deviceId0", "deviceId3", + }; + valTag = { 1, 2, 4, 0, 3 }; + EXPECT_EQ(keyMemo, keyTag); + EXPECT_EQ(valMemo, valTag); +} + +/** + * @tc.name: Contains + * @tc.desc: contains the key and not change the lru position. + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ +HWTEST_F(LRUBucketTest, contains_with_no_change, TestSize.Level0) +{ + std::vector keys = { + "deviceId0", "deviceId1", "deviceId2", "deviceId3", "deviceId4", + "deviceId5", "deviceId6", "deviceId7", "deviceId8", "deviceId9", + }; + std::vector values = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + LRUBucket bucket{ TEST_CAPACITY }; + auto success = bucket.Initialize({ keys, values }); + ASSERT_TRUE(success); + auto [exists, changed] = bucket.Contains("deviceId9"); + ASSERT_TRUE(exists); + ASSERT_FALSE(changed); + auto [keyMemo, valueMemo] = bucket.DumpMemento(); + EXPECT_EQ(keyMemo, keys); + EXPECT_EQ(valueMemo, values); +} + +/** + * @tc.name: Contains + * @tc.desc: contains the key and not change the lru position. + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ +HWTEST_F(LRUBucketTest, contains_with_no_change_base5, TestSize.Level0) +{ + std::vector keys = { + "deviceId0", "deviceId1", "deviceId2", "deviceId3", "deviceId4", + }; + std::vector values = { 0, 1, 2, 3, 4 }; + LRUBucket bucket{ TEST_CAPACITY }; + auto success = bucket.Initialize({ keys, values }); + ASSERT_TRUE(success); + auto [exists, changed] = bucket.Contains("deviceId4"); + ASSERT_TRUE(exists); + ASSERT_FALSE(changed); + auto [keyMemo, valMemo] = bucket.DumpMemento(); + EXPECT_EQ(keyMemo, keys); + EXPECT_EQ(valMemo, values); +} + +/** + * @tc.name: Contains + * @tc.desc: not contains the key. + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ +HWTEST_F(LRUBucketTest, not_contains, TestSize.Level0) +{ + std::vector keys = { + "deviceId0", "deviceId1", "deviceId2", "deviceId3", "deviceId4", + "deviceId5", "deviceId6", "deviceId7", "deviceId8", "deviceId9", + }; + std::vector values = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + LRUBucket bucket{ TEST_CAPACITY }; + auto success = bucket.Initialize({ keys, values }); + ASSERT_TRUE(success); + auto [exists, changed] = bucket.Contains("deviceId10"); + ASSERT_FALSE(exists); + ASSERT_FALSE(changed); + auto [keyMemo, valMemo] = bucket.DumpMemento(); + EXPECT_EQ(keyMemo, keys); + EXPECT_EQ(valMemo, values); +} + +/** + * @tc.name: Contains + * @tc.desc: not contains the key. + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ +HWTEST_F(LRUBucketTest, not_contains_base5, TestSize.Level0) +{ + std::vector keys = { + "deviceId0", "deviceId1", "deviceId2", "deviceId3", "deviceId4", + }; + std::vector values = { 0, 1, 2, 3, 4 }; + LRUBucket bucket{ TEST_CAPACITY }; + auto success = bucket.Initialize({ keys, values }); + ASSERT_TRUE(success); + auto [exists, changed] = bucket.Contains("deviceId10"); + ASSERT_FALSE(exists); + ASSERT_FALSE(changed); + auto [keyMemo, valMemo] = bucket.DumpMemento(); + EXPECT_EQ(keyMemo, keys); + EXPECT_EQ(valMemo, values); +} + +/** + * @tc.name: Contains + * @tc.desc: not contains the key and set the new value. + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ +HWTEST_F(LRUBucketTest, not_contains_and_set, TestSize.Level0) +{ + std::vector keys = { + "deviceId0", "deviceId1", "deviceId2", "deviceId3", "deviceId4", + "deviceId5", "deviceId6", "deviceId7", "deviceId8", "deviceId9", + }; + std::vector values = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + LRUBucket bucket{ TEST_CAPACITY }; + auto success = bucket.Initialize({ keys, values }); + ASSERT_TRUE(success); + auto [exists, changed] = bucket.Contains("deviceId10"); + ASSERT_FALSE(exists); + ASSERT_FALSE(changed); + success = bucket.Set("deviceId10", 10); + ASSERT_TRUE(success); + std::vector keyTag = { + "deviceId1", "deviceId2", "deviceId3", "deviceId4", "deviceId5", + "deviceId6", "deviceId7", "deviceId8", "deviceId9", "deviceId10", + }; + std::vector valTag = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + auto [keyMemo, valMemo] = bucket.DumpMemento(); + EXPECT_EQ(keyMemo, keyTag); + EXPECT_EQ(valMemo, valTag); +} + +/** + * @tc.name: Contains + * @tc.desc: not contains the key and set the new value. + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ +HWTEST_F(LRUBucketTest, not_contains_and_set_base5, TestSize.Level0) +{ + std::vector keys = { + "deviceId0", "deviceId1", "deviceId2", "deviceId3", "deviceId4", + }; + std::vector values = { 0, 1, 2, 3, 4 }; + LRUBucket bucket{ TEST_CAPACITY }; + auto success = bucket.Initialize({ keys, values }); + ASSERT_TRUE(success); + auto [exists, changed] = bucket.Contains("deviceId10"); + ASSERT_FALSE(exists); + ASSERT_FALSE(changed); + success = bucket.Set("deviceId10", 10); + ASSERT_TRUE(success); + std::vector result = { + "deviceId0", "deviceId1", "deviceId2", "deviceId3", "deviceId4", "deviceId10", + }; + std::vector valResult = { 0, 1, 2, 3, 4, 10 }; + auto [keyMemo, valMemo] = bucket.DumpMemento(); + EXPECT_EQ(keyMemo, result); + EXPECT_EQ(valMemo, valResult); + success = bucket.Set("deviceId4", 4); + ASSERT_TRUE(success); + result = { + "deviceId0", "deviceId1", "deviceId2", "deviceId3", "deviceId10", "deviceId4", + }; + valResult = { 0, 1, 2, 3, 10, 4 }; + std::tie(keyMemo, valMemo) = bucket.DumpMemento(); + EXPECT_EQ(keyMemo, result); + EXPECT_EQ(valMemo, valResult); +} + +/** + * @tc.name: Initialize + * @tc.desc: use the Memento to init the lru. + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ +HWTEST_F(LRUBucketTest, initialize, TestSize.Level0) +{ + std::vector keys = { + "deviceId0", "deviceId1", "deviceId2", "deviceId3", "deviceId4", + "deviceId5", "deviceId6", "deviceId7", "deviceId8", "deviceId9", + }; + std::vector values = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + LRUBucket bucket{ TEST_CAPACITY }; + auto success = bucket.Initialize({ keys, values }); + ASSERT_TRUE(success); + auto [keyMemo, valMemo] = bucket.DumpMemento(); + EXPECT_EQ(keyMemo, keys); + EXPECT_EQ(valMemo, values); +} + +/** + * @tc.name: Initialize + * @tc.desc: use the Memento to init the lru. + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ +HWTEST_F(LRUBucketTest, initialize_not_enough, TestSize.Level0) +{ + std::vector keys = { + "deviceId0", "deviceId1", "deviceId2", "deviceId3", "deviceId4", + }; + std::vector values = { 0, 1, 2, 3, 4 }; + LRUBucket bucket{ TEST_CAPACITY }; + auto success = bucket.Initialize({ keys, values }); + ASSERT_TRUE(success); + EXPECT_EQ(5, bucket.Size()); + EXPECT_EQ(TEST_CAPACITY, bucket.Capacity()); + auto [keyMemo, valMemo] = bucket.DumpMemento(); + EXPECT_EQ(keyMemo, keys); + EXPECT_EQ(valMemo, values); +} } // namespace OHOS::Test \ No newline at end of file diff --git a/frameworks/common/test/pool_test.cpp b/frameworks/common/test/pool_test.cpp index 5a69c70a38872704567e6bb2693e7717be6e8234..e0a711ae20a3380486331f12b4b869490eeba05e 100644 --- a/frameworks/common/test/pool_test.cpp +++ b/frameworks/common/test/pool_test.cpp @@ -16,13 +16,15 @@ #include #include -#include "gtest/gtest.h" -#include "pool.h" #include "log_print.h" +#include "pool.h" +#include "gtest/gtest.h" using namespace testing::ext; using namespace OHOS; namespace OHOS::Test { +static constexpr uint32_t CAPABILITY_TEST = 3; // capability +static constexpr uint32_t MIN_TEST = 1; // min class PoolTest : public testing::Test { public: struct Node { @@ -31,27 +33,22 @@ public: { return value == other.value; } + explicit Node(const std::string &threadName = "pool_test") {}; }; static void SetUpTestCase(void); static void TearDownTestCase(void); void SetUp(); void TearDown(); - protected: - static constexpr uint32_t CAPABILITY_TEST = 3; // capability - static constexpr uint32_t MIN_TEST = 1; // min static Pool pool_; }; -Pool PoolTest::pool_ = Pool(CAPABILITY_TEST, MIN_TEST); +Pool PoolTest::pool_ = Pool(CAPABILITY_TEST, MIN_TEST, "pool_test"); -void PoolTest::SetUpTestCase(void) -{} +void PoolTest::SetUpTestCase(void) { } -void PoolTest::TearDownTestCase(void) -{} +void PoolTest::TearDownTestCase(void) { } -void PoolTest::SetUp(void) -{} +void PoolTest::SetUp(void) { } void PoolTest::TearDown(void) { @@ -63,12 +60,12 @@ void PoolTest::TearDown(void) } /** -* @tc.name: Get_001 -* @tc.desc: test the std::shared_ptr Get(bool isForce = false) function. -* @tc.type: FUNC -* @tc.require: -* @tc.author: suoqilong -*/ + * @tc.name: Get_001 + * @tc.desc: test the std::shared_ptr Get(bool isForce = false) function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suoqilong + */ HWTEST_F(PoolTest, Get_001, TestSize.Level1) { int index = 0; @@ -89,12 +86,12 @@ HWTEST_F(PoolTest, Get_001, TestSize.Level1) } /** -* @tc.name: Get_002 -* @tc.desc: test the std::shared_ptr Get(bool isForce = false) function. -* @tc.type: FUNC -* @tc.require: -* @tc.author: suoqilong -*/ + * @tc.name: Get_002 + * @tc.desc: test the std::shared_ptr Get(bool isForce = false) function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suoqilong + */ HWTEST_F(PoolTest, Get_002, TestSize.Level1) { int index = 0; @@ -119,12 +116,12 @@ HWTEST_F(PoolTest, Get_002, TestSize.Level1) } /** -* @tc.name: Release_001 -* @tc.desc: test the int32_t Release(std::shared_ptr data, bool force = false) function. -* @tc.type: FUNC -* @tc.require: -* @tc.author: suoqilong -*/ + * @tc.name: Release_001 + * @tc.desc: test the int32_t Release(std::shared_ptr data, bool force = false) function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suoqilong + */ HWTEST_F(PoolTest, Release_001, TestSize.Level1) { int index = 0; @@ -141,12 +138,12 @@ HWTEST_F(PoolTest, Release_001, TestSize.Level1) } /** -* @tc.name: Release_002 -* @tc.desc: test the int32_t Release(std::shared_ptr data, bool force = false) function. -* @tc.type: FUNC -* @tc.require: -* @tc.author: suoqilong -*/ + * @tc.name: Release_002 + * @tc.desc: test the int32_t Release(std::shared_ptr data, bool force = false) function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suoqilong + */ HWTEST_F(PoolTest, Release_002, TestSize.Level1) { auto ret = pool_.Get(); @@ -158,12 +155,12 @@ HWTEST_F(PoolTest, Release_002, TestSize.Level1) } /** -* @tc.name: Release_003 -* @tc.desc: test the int32_t Release(std::shared_ptr data, bool force = false) function. -* @tc.type: FUNC -* @tc.require: -* @tc.author: suoqilong -*/ + * @tc.name: Release_003 + * @tc.desc: test the int32_t Release(std::shared_ptr data, bool force = false) function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suoqilong + */ HWTEST_F(PoolTest, Release_003, TestSize.Level1) { int index = 0; @@ -180,12 +177,12 @@ HWTEST_F(PoolTest, Release_003, TestSize.Level1) } /** -* @tc.name: Release_004 -* @tc.desc: test the int32_t Release(std::shared_ptr data, bool force = false) function. -* @tc.type: FUNC -* @tc.require: -* @tc.author: suoqilong -*/ + * @tc.name: Release_004 + * @tc.desc: test the int32_t Release(std::shared_ptr data, bool force = false) function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suoqilong + */ HWTEST_F(PoolTest, Release_004, TestSize.Level1) { int index = 0; @@ -214,12 +211,12 @@ HWTEST_F(PoolTest, Release_004, TestSize.Level1) } /** -* @tc.name: Release_005 -* @tc.desc: test the int32_t Release(std::shared_ptr data, bool force = false) function. -* @tc.type: FUNC -* @tc.require: -* @tc.author: suoqilong -*/ + * @tc.name: Release_005 + * @tc.desc: test the int32_t Release(std::shared_ptr data, bool force = false) function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suoqilong + */ HWTEST_F(PoolTest, Release_005, TestSize.Level1) { int index = 0; @@ -237,12 +234,12 @@ HWTEST_F(PoolTest, Release_005, TestSize.Level1) } /** -* @tc.name: Release_006 -* @tc.desc: test the int32_t Release(std::shared_ptr data, bool force = false) function. -* @tc.type: FUNC -* @tc.require: -* @tc.author: suoqilong -*/ + * @tc.name: Release_006 + * @tc.desc: test the int32_t Release(std::shared_ptr data, bool force = false) function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suoqilong + */ HWTEST_F(PoolTest, Release_006, TestSize.Level1) { auto ret = pool_.Get(); @@ -254,12 +251,12 @@ HWTEST_F(PoolTest, Release_006, TestSize.Level1) } /** -* @tc.name: Release_007 -* @tc.desc: test the int32_t Release(std::shared_ptr data, bool force = false) function. -* @tc.type: FUNC -* @tc.require: -* @tc.author: suoqilong -*/ + * @tc.name: Release_007 + * @tc.desc: test the int32_t Release(std::shared_ptr data, bool force = false) function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suoqilong + */ HWTEST_F(PoolTest, Release_007, TestSize.Level1) { auto ret = nullptr; @@ -268,12 +265,12 @@ HWTEST_F(PoolTest, Release_007, TestSize.Level1) } /** -* @tc.name: Idle_001 -* @tc.desc: test the void Idle(std::shared_ptr data) function. -* @tc.type: FUNC -* @tc.require: -* @tc.author: suoqilong -*/ + * @tc.name: Idle_001 + * @tc.desc: test the void Idle(std::shared_ptr data) function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suoqilong + */ HWTEST_F(PoolTest, Idle_001, TestSize.Level1) { int index = 0; @@ -294,12 +291,12 @@ HWTEST_F(PoolTest, Idle_001, TestSize.Level1) } /** -* @tc.name: Clean_001 -* @tc.desc: test the int32_t Clean(std::function)> close) noexcept function. -* @tc.type: FUNC -* @tc.require: -* @tc.author: suoqilong -*/ + * @tc.name: Clean_001 + * @tc.desc: test the int32_t Clean(std::function)> close) noexcept function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suoqilong + */ HWTEST_F(PoolTest, Clean_001, TestSize.Level1) { int index = 0; diff --git a/frameworks/common/test/priority_queue_test.cpp b/frameworks/common/test/priority_queue_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..23b519c9bbf24518e62fd6f721616989fd7e14f4 --- /dev/null +++ b/frameworks/common/test/priority_queue_test.cpp @@ -0,0 +1,537 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "priority_queue.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace OHOS::Test { +using namespace testing::ext; +using namespace OHOS; +using TaskId = uint64_t; +using Task = std::function; +using Duration = std::chrono::steady_clock::duration; +using Time = std::chrono::steady_clock::time_point; +static constexpr Duration INVALID_INTERVAL = std::chrono::milliseconds(0); +static constexpr uint64_t UNLIMITED_TIMES = std::numeric_limits::max(); +static constexpr TaskId INVALID_TASK_ID = static_cast(0); +static constexpr uint32_t SHORT_INTERVAL = 100; // ms +class PriorityQueueTest : public testing::Test { +public: + struct TestTask { + std::function exec = []() {}; + Duration interval = INVALID_INTERVAL; + uint64_t times = UNLIMITED_TIMES; + TaskId taskId = INVALID_TASK_ID; + TestTask() = default; + + bool Valid() const + { + return taskId != INVALID_TASK_ID; + } + }; + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + +protected: + static PriorityQueue priorityqueue_; + static PriorityQueue::PQMatrix pqMatrix; +}; +using TestTask = PriorityQueueTest::TestTask; +PriorityQueue PriorityQueueTest::priorityqueue_ = + PriorityQueue(TestTask()); +PriorityQueue::PQMatrix PriorityQueueTest::pqMatrix = + PriorityQueue::PQMatrix(TestTask(), INVALID_TASK_ID); + +void PriorityQueueTest::SetUpTestCase(void) { } + +void PriorityQueueTest::TearDownTestCase(void) { } + +void PriorityQueueTest::SetUp(void) { } + +void PriorityQueueTest::TearDown(void) +{ + priorityqueue_.Clean(); +} + +/** + * @tc.name: PQMatrix_001 + * @tc.desc: test the PQMatrix(_Tsk task, _Tid id) function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suoqilong + */ +HWTEST_F(PriorityQueueTest, PQMatrix_001, TestSize.Level1) +{ + TestTask testTask; + auto id = testTask.taskId; + EXPECT_EQ(pqMatrix.id_, id); +} + +/** + * @tc.name: PushPopSize_001 + * @tc.desc: Invalid test task. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suoqilong + */ +HWTEST_F(PriorityQueueTest, PushPopSize_001, TestSize.Level1) +{ + TestTask testTask; + auto id = testTask.taskId; + auto timely = std::chrono::seconds(0); + auto ret = priorityqueue_.Push(testTask, id, std::chrono::steady_clock::now() + timely); + EXPECT_EQ(ret, false); + auto retSize = priorityqueue_.Size(); + EXPECT_EQ(retSize, 0u); + auto retPop = priorityqueue_.Pop(); + EXPECT_EQ(retPop.taskId, INVALID_TASK_ID); + retSize = priorityqueue_.Size(); + EXPECT_EQ(retSize, 0u); +} + +/** + * @tc.name: PushPopSize_002 + * @tc.desc: Testing a single task. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suoqilong + */ +HWTEST_F(PriorityQueueTest, PushPopSize_002, TestSize.Level1) +{ + TestTask testTask; + auto id = ++(testTask.taskId); + auto timely = std::chrono::seconds(0); + auto ret = priorityqueue_.Push(testTask, id, std::chrono::steady_clock::now() + timely); + EXPECT_EQ(ret, true); + auto retSize = priorityqueue_.Size(); + EXPECT_EQ(retSize, 1u); + auto retPop = priorityqueue_.Pop(); + EXPECT_EQ(retPop.taskId, id); + retSize = priorityqueue_.Size(); + EXPECT_EQ(retSize, 0u); +} + +/** + * @tc.name: PushPopSize_003 + * @tc.desc: Testing multiple tasks. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suoqilong + */ +HWTEST_F(PriorityQueueTest, PushPopSize_003, TestSize.Level1) +{ + TestTask testTask; + for (int i = 0; i < 10; ++i) { + auto timely = std::chrono::seconds(0); + auto id = ++(testTask.taskId); + auto ret = priorityqueue_.Push(testTask, id, std::chrono::steady_clock::now() + timely); + EXPECT_EQ(ret, true); + } + auto retSize = priorityqueue_.Size(); + EXPECT_EQ(retSize, 10u); + auto retPop = priorityqueue_.Pop(); + EXPECT_EQ(retPop.taskId, 1); + retSize = priorityqueue_.Size(); + EXPECT_EQ(retSize, 9u); +} + +/** + * @tc.name: PushPopSize_004 + * @tc.desc: Test the delay task. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suoqilong + */ +HWTEST_F(PriorityQueueTest, PushPopSize_004, TestSize.Level1) +{ + TestTask testTask; + testTask.times = 1; + for (int i = 0; i < 5; ++i) { + auto delay = std::chrono::milliseconds(SHORT_INTERVAL); + auto id = ++(testTask.taskId); + auto ret = priorityqueue_.Push(testTask, id, std::chrono::steady_clock::now() + delay); + EXPECT_EQ(ret, true); + } + for (int i = 0; i < 5; ++i) { + auto timely = std::chrono::seconds(0); + auto id = ++(testTask.taskId); + auto ret = priorityqueue_.Push(testTask, id, std::chrono::steady_clock::now() + timely); + EXPECT_EQ(ret, true); + } + auto retSize = priorityqueue_.Size(); + EXPECT_EQ(retSize, 10u); + for (int i = 0; i < 5; ++i) { + auto retPop = priorityqueue_.Pop(); + EXPECT_EQ(retPop.taskId, i + 6); + } + for (int i = 0; i < 5; ++i) { + auto retPop = priorityqueue_.Pop(); + EXPECT_EQ(retPop.taskId, i + 1); + } + retSize = priorityqueue_.Size(); + EXPECT_EQ(retSize, 0u); +} + +/** + * @tc.name: PushPopSize_005 + * @tc.desc: Test the delay task. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suoqilong + */ +HWTEST_F(PriorityQueueTest, PushPopSize_005, TestSize.Level1) +{ + TestTask testTask; + testTask.times = 1; + auto delay = std::chrono::milliseconds(SHORT_INTERVAL); + auto id = ++(testTask.taskId); + auto ret = priorityqueue_.Push(testTask, id, std::chrono::steady_clock::now() + delay); + EXPECT_EQ(ret, true); + auto retSize = priorityqueue_.Size(); + EXPECT_EQ(retSize, 1u); + auto delayA = std::chrono::steady_clock::now(); + auto retPop = priorityqueue_.Pop(); + EXPECT_EQ(retPop.taskId, id); + auto delayB = std::chrono::steady_clock::now(); + auto diff = std::chrono::duration_cast(delayB - delayA).count(); + auto delayms = std::chrono::duration_cast(delay).count(); + EXPECT_LT(diff, delayms * 1.5); + retSize = priorityqueue_.Size(); + EXPECT_EQ(retSize, 0u); +} + +/** + * @tc.name: Find_001 + * @tc.desc: Invalid test task. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suoqilong + */ +HWTEST_F(PriorityQueueTest, Find_001, TestSize.Level1) +{ + TestTask testTask; + auto id = testTask.taskId; + auto timely = std::chrono::seconds(0); + auto ret = priorityqueue_.Push(testTask, id, std::chrono::steady_clock::now() + timely); + EXPECT_EQ(ret, false); + auto retFind = priorityqueue_.Find(id); + EXPECT_EQ(retFind.taskId, INVALID_TASK_ID); +} + +/** + * @tc.name: Find_002 + * @tc.desc: test the priority_queue _Tsk Find(_Tid id) function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suoqilong + */ +HWTEST_F(PriorityQueueTest, Find_002, TestSize.Level1) +{ + TestTask testTask; + for (int i = 0; i < 10; ++i) { + auto timely = std::chrono::seconds(0); + auto id = ++(testTask.taskId); + auto ret = priorityqueue_.Push(testTask, id, std::chrono::steady_clock::now() + timely); + EXPECT_EQ(ret, true); + } + auto retSize = priorityqueue_.Size(); + EXPECT_EQ(retSize, 10u); + auto retFind = priorityqueue_.Find(5); + EXPECT_EQ(retFind.taskId, 5); + retFind = priorityqueue_.Find(20); + EXPECT_EQ(retFind.taskId, INVALID_TASK_ID); +} + +/** + * @tc.name: Update_001 + * @tc.desc: Invalid test task. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suoqilong + */ +HWTEST_F(PriorityQueueTest, Update_001, TestSize.Level1) +{ + auto updater = [](TestTask &) { + return std::pair { false, Time() }; + }; + auto delay = std::chrono::milliseconds(SHORT_INTERVAL); + TestTask testTask; + testTask.times = 3; + auto id = testTask.taskId; + auto ret = priorityqueue_.Push(testTask, id, std::chrono::steady_clock::now() + delay); + EXPECT_EQ(ret, false); + auto retUpdate = priorityqueue_.Update(id, updater); + EXPECT_EQ(retUpdate, false); +} + +/** + * @tc.name: Update_002 + * @tc.desc: Test normal tasks. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suoqilong + */ +HWTEST_F(PriorityQueueTest, Update_002, TestSize.Level1) +{ + auto updater = [](TestTask &) { + return std::pair { false, Time() }; + }; + auto delay = std::chrono::milliseconds(SHORT_INTERVAL); + TestTask testTask; + testTask.times = 3; + auto id = ++(testTask.taskId); + auto ret = priorityqueue_.Push(testTask, id, std::chrono::steady_clock::now() + delay); + EXPECT_EQ(ret, true); + auto retUpdate = priorityqueue_.Update(id, updater); + EXPECT_EQ(retUpdate, true); +} + +/** + * @tc.name: Update_003 + * @tc.desc: Test the running tasks. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suoqilong + */ +HWTEST_F(PriorityQueueTest, Update_003, TestSize.Level1) +{ + auto updater = [](TestTask &) { + return std::pair { false, Time() }; + }; + auto delay = std::chrono::milliseconds(SHORT_INTERVAL); + TestTask testTask; + testTask.times = 3; + auto id = ++(testTask.taskId); + auto ret = priorityqueue_.Push(testTask, id, std::chrono::steady_clock::now() + delay); + EXPECT_EQ(ret, true); + auto retPop = priorityqueue_.Pop(); + auto retUpdate = priorityqueue_.Update(retPop.taskId, updater); + EXPECT_EQ(retUpdate, false); +} + +/** + * @tc.name: Update_004 + * @tc.desc: Test the running tasks. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suoqilong + */ +HWTEST_F(PriorityQueueTest, Update_004, TestSize.Level1) +{ + auto updater = [](TestTask &) { + return std::pair { true, Time() }; + }; + auto delay = std::chrono::milliseconds(SHORT_INTERVAL); + TestTask testTask; + testTask.times = 3; + auto id = ++(testTask.taskId); + auto ret = priorityqueue_.Push(testTask, id, std::chrono::steady_clock::now() + delay); + EXPECT_EQ(ret, true); + auto retPop = priorityqueue_.Pop(); + auto retUpdate = priorityqueue_.Update(retPop.taskId, updater); + EXPECT_EQ(retUpdate, true); +} + +/** + * @tc.name: Update_005 + * @tc.desc: Test the running and finish tasks. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suoqilong + */ +HWTEST_F(PriorityQueueTest, Update_005, TestSize.Level1) +{ + auto updater = [](TestTask &) { + return std::pair { false, Time() }; + }; + auto delay = std::chrono::milliseconds(SHORT_INTERVAL); + TestTask testTask; + testTask.times = 3; + auto id = ++(testTask.taskId); + auto ret = priorityqueue_.Push(testTask, id, std::chrono::steady_clock::now() + delay); + EXPECT_EQ(ret, true); + auto retPop = priorityqueue_.Pop(); + priorityqueue_.Finish(id); + auto retUpdate = priorityqueue_.Update(retPop.taskId, updater); + EXPECT_EQ(retUpdate, false); +} + +/** + * @tc.name: Update_006 + * @tc.desc: Test the running and finish tasks. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suoqilong + */ +HWTEST_F(PriorityQueueTest, Update_006, TestSize.Level1) +{ + auto updater = [](TestTask &) { + return std::pair { true, Time() }; + }; + auto delay = std::chrono::milliseconds(SHORT_INTERVAL); + TestTask testTask; + testTask.times = 3; + auto id = ++(testTask.taskId); + auto ret = priorityqueue_.Push(testTask, id, std::chrono::steady_clock::now() + delay); + EXPECT_EQ(ret, true); + auto retPop = priorityqueue_.Pop(); + priorityqueue_.Finish(id); + auto retUpdate = priorityqueue_.Update(retPop.taskId, updater); + EXPECT_EQ(retUpdate, false); +} + +/** + * @tc.name: Remove_001 + * @tc.desc: Invalid test task. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suoqilong + */ +HWTEST_F(PriorityQueueTest, Remove_001, TestSize.Level1) +{ + TestTask testTask; + auto id = testTask.taskId; + auto delay = std::chrono::milliseconds(SHORT_INTERVAL); + auto ret = priorityqueue_.Push(testTask, id, std::chrono::steady_clock::now() + delay); + EXPECT_EQ(ret, false); + auto retRemove = priorityqueue_.Remove(id, false); + EXPECT_EQ(retRemove, false); + auto retSize = priorityqueue_.Size(); + EXPECT_EQ(retSize, 0u); +} + +/** + * @tc.name: Remove_002 + * @tc.desc: Single and don't wait test task. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suoqilong + */ +HWTEST_F(PriorityQueueTest, Remove_002, TestSize.Level1) +{ + TestTask testTask; + auto id = ++(testTask.taskId); + auto delay = std::chrono::milliseconds(SHORT_INTERVAL); + auto ret = priorityqueue_.Push(testTask, id, std::chrono::steady_clock::now() + delay); + EXPECT_EQ(ret, true); + auto retSize = priorityqueue_.Size(); + EXPECT_EQ(retSize, 1u); + auto retRemove = priorityqueue_.Remove(id, false); + EXPECT_EQ(retRemove, true); + retSize = priorityqueue_.Size(); + EXPECT_EQ(retSize, 0u); +} + +/** + * @tc.name: Remove_003 + * @tc.desc: Single and wait test task. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suoqilong + */ +HWTEST_F(PriorityQueueTest, Remove_003, TestSize.Level1) +{ + TestTask testTask; + auto id = ++(testTask.taskId); + auto delay = std::chrono::milliseconds(SHORT_INTERVAL); + auto ret = priorityqueue_.Push(testTask, id, std::chrono::steady_clock::now() + delay); + EXPECT_EQ(ret, true); + auto retSize = priorityqueue_.Size(); + EXPECT_EQ(retSize, 1u); + priorityqueue_.Finish(id); + auto retRemove = priorityqueue_.Remove(id, true); + EXPECT_EQ(retRemove, true); + retSize = priorityqueue_.Size(); + EXPECT_EQ(retSize, 0u); +} + +/** + * @tc.name: Clean_001 + * @tc.desc: Testing a single task. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suoqilong + */ +HWTEST_F(PriorityQueueTest, Clean_001, TestSize.Level1) +{ + TestTask testTask; + auto timely = std::chrono::seconds(0); + auto id = ++(testTask.taskId); + auto ret = priorityqueue_.Push(testTask, id, std::chrono::steady_clock::now() + timely); + EXPECT_EQ(ret, true); + auto retSize = priorityqueue_.Size(); + EXPECT_EQ(retSize, 1u); + priorityqueue_.Clean(); + retSize = priorityqueue_.Size(); + EXPECT_EQ(retSize, 0u); +} + +/** + * @tc.name: Clean_002 + * @tc.desc: Testing multiple tasks. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suoqilong + */ +HWTEST_F(PriorityQueueTest, Clean_002, TestSize.Level1) +{ + TestTask testTask; + for (int i = 0; i < 10; ++i) { + auto timely = std::chrono::seconds(0); + auto id = ++(testTask.taskId); + auto ret = priorityqueue_.Push(testTask, id, std::chrono::steady_clock::now() + timely); + EXPECT_EQ(ret, true); + } + auto retSize = priorityqueue_.Size(); + EXPECT_EQ(retSize, 10u); + priorityqueue_.Clean(); + retSize = priorityqueue_.Size(); + EXPECT_EQ(retSize, 0u); +} + +/** + * @tc.name: Finish_001 + * @tc.desc: test the priority_queue void Finish(_Tid id) function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: suoqilong + */ +HWTEST_F(PriorityQueueTest, Finish_001, TestSize.Level1) +{ + TestTask testTask; + auto id = ++(testTask.taskId); + auto delay = std::chrono::milliseconds(SHORT_INTERVAL); + auto ret = priorityqueue_.Push(testTask, id, std::chrono::steady_clock::now() + delay); + EXPECT_EQ(ret, true); + auto retSize = priorityqueue_.Size(); + EXPECT_EQ(retSize, 1u); + priorityqueue_.Finish(id); // Marking Finish + auto retRemove = priorityqueue_.Remove(id, true); + EXPECT_EQ(retRemove, true); + retSize = priorityqueue_.Size(); + EXPECT_EQ(retSize, 0u); +} +} // namespace OHOS::Test diff --git a/frameworks/common/test/task_scheduler_test.cpp b/frameworks/common/test/task_scheduler_test.cpp index e4a1c667e53eabbcbebd8a87f8a0f6091a74b0d0..79bfa81f774211d9e612441735c025c912f65e01 100644 --- a/frameworks/common/test/task_scheduler_test.cpp +++ b/frameworks/common/test/task_scheduler_test.cpp @@ -1,17 +1,17 @@ /* -* Copyright (c) 2022 Huawei Device Co., Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include "task_scheduler.h" @@ -26,19 +26,19 @@ class TaskSchedulerTest : public testing::Test { public: static constexpr uint32_t SHORT_INTERVAL = 100; // ms static constexpr uint32_t LONG_INTERVAL = 1; // s - static void SetUpTestCase(void){}; - static void TearDownTestCase(void){}; - void SetUp(){}; - void TearDown() {} + static void SetUpTestCase(void) {}; + static void TearDownTestCase(void) {}; + void SetUp() {}; + void TearDown() { } }; /** -* @tc.name: At -* @tc.desc: -* @tc.type: FUNC -* @tc.require: -* @tc.author: ht -*/ + * @tc.name: At + * @tc.desc: + * @tc.type: FUNC + * @tc.require: + * @tc.author: ht + */ HWTEST_F(TaskSchedulerTest, At, TestSize.Level0) { TaskScheduler taskScheduler("atTest"); @@ -61,12 +61,12 @@ HWTEST_F(TaskSchedulerTest, At, TestSize.Level0) } /** -* @tc.name: Every -* @tc.desc:execute task periodically with duration -* @tc.type: FUNC -* @tc.require: -* @tc.author: ht -*/ + * @tc.name: Every + * @tc.desc:execute task periodically with duration + * @tc.type: FUNC + * @tc.require: + * @tc.author: ht + */ HWTEST_F(TaskSchedulerTest, ExecuteDuration, TestSize.Level0) { TaskScheduler taskScheduler("everyTest"); @@ -83,12 +83,12 @@ HWTEST_F(TaskSchedulerTest, ExecuteDuration, TestSize.Level0) } /** -* @tc.name: Reset -* @tc.desc: Reset before task execution and the task is tasks_.begin() or not -* @tc.type: FUNC -* @tc.require: -* @tc.author: ht -*/ + * @tc.name: Reset + * @tc.desc: Reset before task execution and the task is tasks_.begin() or not + * @tc.type: FUNC + * @tc.require: + * @tc.author: ht + */ HWTEST_F(TaskSchedulerTest, Reset1, TestSize.Level0) { TaskScheduler taskScheduler("reset1Test"); @@ -107,12 +107,12 @@ HWTEST_F(TaskSchedulerTest, Reset1, TestSize.Level0) } /** -* @tc.name: Reset -* @tc.desc: Reset during task execution -* @tc.type: FUNC -* @tc.require: -* @tc.author: ht -*/ + * @tc.name: Reset + * @tc.desc: Reset during task execution + * @tc.type: FUNC + * @tc.require: + * @tc.author: ht + */ HWTEST_F(TaskSchedulerTest, Reset2, TestSize.Level0) { TaskScheduler taskScheduler("reset2Test"); @@ -130,12 +130,12 @@ HWTEST_F(TaskSchedulerTest, Reset2, TestSize.Level0) } /** -* @tc.name: Reset -* @tc.desc: Reset after task execution -* @tc.type: FUNC -* @tc.require: -* @tc.author: ht -*/ + * @tc.name: Reset + * @tc.desc: Reset after task execution + * @tc.type: FUNC + * @tc.require: + * @tc.author: ht + */ HWTEST_F(TaskSchedulerTest, Reset3, TestSize.Level0) { TaskScheduler taskScheduler("reset3Test"); @@ -155,27 +155,27 @@ HWTEST_F(TaskSchedulerTest, Reset3, TestSize.Level0) } /** -* @tc.name: Every -* @tc.desc: execute task for some times periodically with duration. -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: Every + * @tc.desc: execute task for some times periodically with duration. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(TaskSchedulerTest, EveryExecuteTimes, TestSize.Level0) { TaskScheduler taskScheduler("everyTimes"); auto blockData = std::make_shared>(LONG_INTERVAL, 0); int testData = 0; int times = 5; - auto taskId = taskScheduler.Every(times, std::chrono::milliseconds(0), - std::chrono::milliseconds(SHORT_INTERVAL), [blockData, times, &testData]() { - testData++; - if (testData < times) { - blockData->Clear(testData); - return; - } - blockData->SetValue(testData); - }); + auto taskId = taskScheduler.Every(times, std::chrono::milliseconds(0), std::chrono::milliseconds(SHORT_INTERVAL), + [blockData, times, &testData]() { + testData++; + if (testData < times) { + blockData->Clear(testData); + return; + } + blockData->SetValue(testData); + }); ASSERT_EQ(blockData->GetValue(), times); auto resetId = taskScheduler.Reset(taskId, std::chrono::milliseconds(SHORT_INTERVAL)); ASSERT_EQ(resetId, TaskScheduler::INVALID_TASK_ID); @@ -183,22 +183,25 @@ HWTEST_F(TaskSchedulerTest, EveryExecuteTimes, TestSize.Level0) } /** -* @tc.name: Remove -* @tc.desc: remove task before execute. -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: Remove + * @tc.desc: remove task before execute. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(TaskSchedulerTest, RemoveBeforeExecute, TestSize.Level0) { TaskScheduler taskScheduler("RemoveBeforeExecute"); auto expiredTime = std::chrono::steady_clock::now() + std::chrono::milliseconds(SHORT_INTERVAL); auto blockData = std::make_shared>(LONG_INTERVAL, 0); int testData = 0; - auto taskId = taskScheduler.At(expiredTime, [blockData, testData]() { - int tmpData = testData + 1; - blockData->SetValue(tmpData); - }, std::chrono::milliseconds(SHORT_INTERVAL)); + auto taskId = taskScheduler.At( + expiredTime, + [blockData, testData]() { + int tmpData = testData + 1; + blockData->SetValue(tmpData); + }, + std::chrono::milliseconds(SHORT_INTERVAL)); taskScheduler.Remove(taskId); auto resetId = taskScheduler.Reset(taskId, std::chrono::milliseconds(SHORT_INTERVAL)); ASSERT_EQ(resetId, TaskScheduler::INVALID_TASK_ID); @@ -206,12 +209,12 @@ HWTEST_F(TaskSchedulerTest, RemoveBeforeExecute, TestSize.Level0) } /** -* @tc.name: Remove -* @tc.desc: remove task during execute, and waiting. -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: Remove + * @tc.desc: remove task during execute, and waiting. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(TaskSchedulerTest, RemoveWaitExecute, TestSize.Level0) { TaskScheduler taskScheduler("RemoveWaitExecute"); @@ -219,12 +222,15 @@ HWTEST_F(TaskSchedulerTest, RemoveWaitExecute, TestSize.Level0) auto blockDataTest = std::make_shared>(LONG_INTERVAL, 0); auto blockDataWait = std::make_shared>(LONG_INTERVAL, 0); int testData = 1; - auto taskId = taskScheduler.At(expiredTime, [blockDataTest, blockDataWait, &testData]() { - blockDataTest->SetValue(testData); - blockDataWait->GetValue(); - int tmpData = testData + 1; - blockDataTest->SetValue(tmpData); - }, std::chrono::milliseconds(SHORT_INTERVAL)); + auto taskId = taskScheduler.At( + expiredTime, + [blockDataTest, blockDataWait, &testData]() { + blockDataTest->SetValue(testData); + blockDataWait->GetValue(); + int tmpData = testData + 1; + blockDataTest->SetValue(tmpData); + }, + std::chrono::milliseconds(SHORT_INTERVAL)); ASSERT_EQ(blockDataTest->GetValue(), testData); auto resetId = taskScheduler.Reset(taskId, std::chrono::milliseconds(SHORT_INTERVAL)); ASSERT_EQ(taskId, resetId); @@ -233,12 +239,12 @@ HWTEST_F(TaskSchedulerTest, RemoveWaitExecute, TestSize.Level0) } /** -* @tc.name: Remove -* @tc.desc: remove task during execute, but no wait. -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: Remove + * @tc.desc: remove task during execute, but no wait. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(TaskSchedulerTest, RemoveNoWaitExecute, TestSize.Level0) { TaskScheduler taskScheduler("RemoveNoWaitExecute"); diff --git a/frameworks/common/test/traits_test.cpp b/frameworks/common/test/traits_test.cpp index 15c1d664ebd811daaadd39baeb58d4fa6e9e1ebf..2ea7b063c0a525d2732adf5dabe0ca3e56b7a777 100644 --- a/frameworks/common/test/traits_test.cpp +++ b/frameworks/common/test/traits_test.cpp @@ -21,13 +21,13 @@ class TraitsTest : public testing::Test { public: class From { public: - From() {} + From() { } }; class Convertible { public: // Convertible is auto convert type, do not add explicit to stop the type convert. Convertible(const From &) {}; - Convertible() {} + Convertible() { } Convertible(Convertible &&) noexcept {}; Convertible &operator=(Convertible &&) noexcept { @@ -38,19 +38,19 @@ public: return From(); } }; - static void SetUpTestCase(void){}; - static void TearDownTestCase(void){}; - void SetUp(){}; - void TearDown() {} + static void SetUpTestCase(void) {}; + static void TearDownTestCase(void) {}; + void SetUp() {}; + void TearDown() { } }; /** -* @tc.name: same_index_of_v -* @tc.desc: -* @tc.type: FUNC -* @tc.require: -* @tc.author: Sven Wang -*/ + * @tc.name: same_index_of_v + * @tc.desc: + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ HWTEST_F(TraitsTest, same_index_of_v, TestSize.Level0) { auto index = Traits::same_index_of_v>; @@ -62,12 +62,12 @@ HWTEST_F(TraitsTest, same_index_of_v, TestSize.Level0) } /** -* @tc.name: same_in_v -* @tc.desc: -* @tc.type: FUNC -* @tc.require: -* @tc.author: Sven Wang -*/ + * @tc.name: same_in_v + * @tc.desc: + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ HWTEST_F(TraitsTest, same_in_v, TestSize.Level0) { auto exist = Traits::same_in_v>; @@ -79,12 +79,12 @@ HWTEST_F(TraitsTest, same_in_v, TestSize.Level0) } /** -* @tc.name: convertible_index_of_v -* @tc.desc: -* @tc.type: FUNC -* @tc.require: -* @tc.author: Sven Wang -*/ + * @tc.name: convertible_index_of_v + * @tc.desc: + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ HWTEST_F(TraitsTest, convertible_index_of_v, TestSize.Level0) { auto index = Traits::convertible_index_of_v>; @@ -98,12 +98,12 @@ HWTEST_F(TraitsTest, convertible_index_of_v, TestSize.Level0) } /** -* @tc.name: convertible_in_v -* @tc.desc: -* @tc.type: FUNC -* @tc.require: -* @tc.author: Sven Wang -*/ + * @tc.name: convertible_in_v + * @tc.desc: + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ HWTEST_F(TraitsTest, convertible_in_v, TestSize.Level0) { auto convertible = Traits::convertible_in_v>; @@ -117,12 +117,12 @@ HWTEST_F(TraitsTest, convertible_in_v, TestSize.Level0) } /** -* @tc.name: variant_size_of_v -* @tc.desc: -* @tc.type: FUNC -* @tc.require: -* @tc.author: Sven Wang -*/ + * @tc.name: variant_size_of_v + * @tc.desc: + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ HWTEST_F(TraitsTest, variant_size_of_v, TestSize.Level0) { std::variant> value; @@ -134,12 +134,12 @@ HWTEST_F(TraitsTest, variant_size_of_v, TestSize.Level0) } /** -* @tc.name: variant_index_of_v -* @tc.desc: -* @tc.type: FUNC -* @tc.require: -* @tc.author: Sven Wang -*/ + * @tc.name: variant_index_of_v + * @tc.desc: + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ HWTEST_F(TraitsTest, variant_index_of_v, TestSize.Level0) { std::variant> value; @@ -160,12 +160,12 @@ HWTEST_F(TraitsTest, variant_index_of_v, TestSize.Level0) } /** -* @tc.name: get_if_same_type -* @tc.desc: -* @tc.type: FUNC -* @tc.require: -* @tc.author: Sven Wang -*/ + * @tc.name: get_if_same_type + * @tc.desc: + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ HWTEST_F(TraitsTest, get_if_same_type, TestSize.Level0) { // 1. When the _Tp is a type in the ..._Types, the get_if is equal to the std::get_if. @@ -188,12 +188,12 @@ HWTEST_F(TraitsTest, get_if_same_type, TestSize.Level0) ASSERT_TRUE(strcmp(*charPtr, "test case") == 0); } /** -* @tc.name: get_if_convertible_type -* @tc.desc: -* @tc.type: FUNC -* @tc.require: -* @tc.author: Sven Wang -*/ + * @tc.name: get_if_convertible_type + * @tc.desc: + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ HWTEST_F(TraitsTest, get_if_convertible_type, TestSize.Level0) { // 2. When the _Tp is not a type in the ..._Types but someone in the ...Types can convert to _Tp implicitly, @@ -219,12 +219,12 @@ HWTEST_F(TraitsTest, get_if_convertible_type, TestSize.Level0) } /** -* @tc.name: get_if_invalid_type -* @tc.desc: -* @tc.type: FUNC -* @tc.require: -* @tc.author: Sven Wang -*/ + * @tc.name: get_if_invalid_type + * @tc.desc: + * @tc.type: FUNC + * @tc.require: + * @tc.author: Sven Wang + */ HWTEST_F(TraitsTest, get_if_invalid_type, TestSize.Level0) { // 3. When the _Tp is not a type in the ..._Types and can't convert, the get_if will return nullptr. diff --git a/frameworks/ets/taihe/kv_store/BUILD.gn b/frameworks/ets/taihe/kv_store/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..711f48a2a33b57454724eb74f4b0bd34a3e81bc5 --- /dev/null +++ b/frameworks/ets/taihe/kv_store/BUILD.gn @@ -0,0 +1,112 @@ +# Copyright (C) 2025-2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/config/components/ets_frontend/ets2abc_config.gni") +import("//build/ohos.gni") +import("//build/ohos/taihe_idl/taihe.gni") +import("//foundation/distributeddatamgr/kv_store/kv_store.gni") + +subsystem_name = "distributeddatamgr" +part_name = "kv_store" +taihe_generated_file_path = "$taihe_file_path/out/$subsystem_name/$part_name" + +copy_taihe_idl("copy_taihe") { + sources = [ "${kv_store_base_path}/frameworks/ets/taihe/kv_store/idl/ohos.data.distributedkvstore.taihe" ] +} + +ohos_taihe("run_taihe") { + taihe_generated_file_path = "$taihe_generated_file_path" + deps = [ ":copy_taihe" ] + outputs = [ + "$taihe_generated_file_path/src/ohos.data.distributedkvstore.ani.cpp", + "$taihe_generated_file_path/src/ohos.data.distributedkvstore.abi.c", + ] +} + +taihe_shared_library("distributedkvstore_ani") { + taihe_generated_file_path = "$taihe_generated_file_path" + subsystem_name = "$subsystem_name" + part_name = "$part_name" + include_dirs = [ + "${kv_store_base_path}/interfaces/innerkits/distributeddata/include", + "${kv_store_base_path}/frameworks/ets/taihe/kv_store/include", + "${kv_store_base_path}/frameworks/common", + "${kv_store_base_path}/frameworks/innerkitsimpl/distributeddatafwk/include", + ] + sources = get_target_outputs(":run_taihe") + sources += [ + "${kv_store_base_path}/frameworks/ets/taihe/kv_store/src/ani_ability_utils.cpp", + "${kv_store_base_path}/frameworks/ets/taihe/kv_store/src/ani_constructor.cpp", + "${kv_store_base_path}/frameworks/ets/taihe/kv_store/src/ani_error_utils.cpp", + "${kv_store_base_path}/frameworks/ets/taihe/kv_store/src/ani_kvstore_utils.cpp", + "${kv_store_base_path}/frameworks/ets/taihe/kv_store/src/ani_observer_utils.cpp", + "${kv_store_base_path}/frameworks/ets/taihe/kv_store/src/ani_utils.cpp", + "${kv_store_base_path}/frameworks/ets/taihe/kv_store/src/ohos.data.distributedkvstore.impl.cpp", + "${kv_store_base_path}/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_datashare_bridge.cpp", + ] + deps = [ + ":run_taihe", + "${kv_store_base_path}/frameworks/common:datamgr_common", + "${kv_store_base_path}/interfaces/innerkits/distributeddata:distributeddata_inner", + ] + + if (os_level == "standard") { + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + } + cflags = [ + "-DHILOG_ENABLE", + "-fPIC", + "-g3", + ] + external_deps = [ + "ability_runtime:abilitykit_native", + "ability_runtime:ani_base_context", + "ability_runtime:app_context", + "ability_runtime:extensionkit_native", + "ability_runtime:napi_base_context", + "cJSON:cjson", + "data_share:datashare_common", + "data_share:datashare_common_lite", + "eventhandler:libeventhandler", + "hilog:libhilog", + "napi:ace_napi", + ] +} + +generate_static_abc("distributedkvstore_abc") { + base_url = "$taihe_generated_file_path" + files = [ "$taihe_generated_file_path/@ohos.data.distributedKVStore.ets" ] + dst_file = "$target_out_dir/distributedkvstore.abc" + is_boot_abc = "True" + device_dst_file = "/system/framework/distributedkvstore.abc" + dependencies = [ ":run_taihe" ] +} + +ohos_prebuilt_etc("distributedkvstore_etc") { + source = "$target_out_dir/distributedkvstore.abc" + module_install_dir = "framework" + subsystem_name = "distributeddatamgr" + part_name = "kv_store" + deps = [ ":distributedkvstore_abc" ] +} + +group("distributedkvstore_ani_pack") { + deps = [ + ":distributedkvstore_ani", + ":distributedkvstore_etc", + ] +} diff --git a/frameworks/ets/taihe/kv_store/idl/ohos.data.distributedkvstore.taihe b/frameworks/ets/taihe/kv_store/idl/ohos.data.distributedkvstore.taihe new file mode 100644 index 0000000000000000000000000000000000000000..c68ba3b6cc1caf04b53259234caadf08705c09c1 --- /dev/null +++ b/frameworks/ets/taihe/kv_store/idl/ohos.data.distributedkvstore.taihe @@ -0,0 +1,421 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@!namespace("@ohos.data.distributedKVStore", "distributedKVStore") +@!sts_export_default + +@!sts_inject_into_module(""" +import BaseContext from 'application.BaseContext'; +import common from '@ohos.app.ability.common'; +import { AsyncCallback, Callback } from '@ohos.base'; +import { ValuesBucket } from '@ohos.data.ValuesBucket'; +import dataSharePredicates from '@ohos.data.dataSharePredicates'; +""") + +@!sts_inject(""" + static { loadLibrary("distributedkvstore_ani.z"); } +""") + +struct KVManagerConfig { + bundleName: String; + context: @sts_type("BaseContext") Opaque; +} + +enum Constants : i32 { + MAX_KEY_LENGTH = 1024, + MAX_VALUE_LENGTH = 4194303, + MAX_KEY_LENGTH_DEVICE = 896, + MAX_STORE_ID_LENGTH = 128, + MAX_QUERY_LENGTH = 512000, + MAX_BATCH_SIZE = 128, +} + +enum ValueType : i32 { + STRING, + BYTE_ARRAY, + BOOLEAN, + DOUBLE, + LONG +} + +union ValueUnion { + STRING: String; + UINT8Array: @typedarray Array; + BOOL: bool; + F64: f64; + INT64: i64; +} + +union DataShareValueUnion { + INT64: i64; + F64: f64; + STRING: String; + BOOL: bool; + UINT8Array: @typedarray Array; +} + +struct Value { + type: ValueType; + value: ValueUnion; +} + +struct Entry { + key: String; + value: Value; +} + +struct ChangeNotification { + insertEntries: Array; + updateEntries: Array; + deleteEntries: Array; + deviceId: String; +} + +enum SyncMode : i32 { + PULL_ONLY, + PUSH_ONLY, + PUSH_PULL +} + +enum SubscribeType : i32 { + SUBSCRIBE_TYPE_LOCAL = 1, + SUBSCRIBE_TYPE_REMOTE, + SUBSCRIBE_TYPE_ALL +} + +enum KVStoreType : i32 { + DEVICE_COLLABORATION, + SINGLE_VERSION +} + +enum SecurityLevel : i32 { + S1, + S2, + S3, + S4 +} + +struct Options { + createIfMissing: Optional; + encrypt: Optional; + backup: Optional; + autoSync: Optional; + kvStoreType: Optional; + securityLevel: Optional; + schema: Optional; +} + +union OneUndef { + @undefined UNDEFINED; +} + +@class +interface Schema { + GetInner (): i64; + @get GetRoot(): FieldNode; + @set SetRoot(para :FieldNode): void; + @get GetIndexes(): Array; + @set SetIndexes(para :Array): void; + @get GetMode(): i32; + @set SetMode(para :i32): void; + @get GetSkip(): i32; + @set SetSkip(para :i32): void; +} +@ctor("Schema") +function CreateSchema(): Schema; + +@class +interface FieldNode { + GetInner (): i64; + AppendChild(child: FieldNode): bool; + @get GetDefaultValue(): String; + @set SetDefaultValue(para :String): void; + @get GetNullable(): bool; + @set SetNullable(para :bool): void; + @get GetType(): i32; + @set SetType(para : i32): void; +} +@ctor("FieldNode") +function CreateFieldNode(name: String): FieldNode; + +interface KVStoreResultSet { + GetInner (): i64; + GetProxy (): i64; + GetCount(): i32; + GetPosition(): i32; + MoveToFirst(): bool; + MoveToLast(): bool; + MoveToNext(): bool; + MoveToPrevious(): bool; + Move(offset: i32): bool; + MoveToPosition(position: i32): bool; + IsFirst(): bool; + IsLast(): bool; + IsBeforeFirst(): bool; + IsAfterLast(): bool; + GetEntry(): Entry; +} + +union LongDoubleStringBool { + INT64: i64; + F64: f64; + STRING: String; + BOOL: bool; +} + +union LongDoubleString { + INT64: i64; + F64: f64; + STRING: String; +} + +union LongDouble { + F64: f64; + INT64: i64; +} + +@class +interface Query { + GetInner (): i64; + + Reset(@sts_this thiz : Query): Query; + + EqualTo(@sts_this thiz : Query, field: String, value: LongDoubleStringBool): Query; + + NotEqualTo(@sts_this thiz : Query, field: String, value: LongDoubleStringBool): Query; + + GreaterThan(@sts_this thiz : Query, field: String, value: LongDoubleStringBool): Query; + + LessThan(@sts_this thiz : Query, field: String, value: LongDoubleString): Query; + + GreaterThanOrEqualTo(@sts_this thiz : Query, field: String, value: LongDoubleString): Query; + + LessThanOrEqualTo(@sts_this thiz : Query, field: String, value: LongDoubleString): Query; + + IsNull(@sts_this thiz : Query, field: String): Query; + + InNumber(@sts_this thiz : Query, field: String, valueList: Array): Query; + + InString(@sts_this thiz : Query, field: String, valueList: Array): Query; + + NotInNumber(@sts_this thiz : Query, field: String, valueList: Array): Query; + + NotInString(@sts_this thiz : Query, field: String, valueList: Array): Query; + + Like(@sts_this thiz : Query, field: String, value: String): Query; + + Unlike(@sts_this thiz : Query, field: String, value: String): Query; + + And(@sts_this thiz : Query, ): Query; + + Or(@sts_this thiz : Query, ): Query; + + OrderByAsc(@sts_this thiz : Query, field: String): Query; + + OrderByDesc(@sts_this thiz : Query, field: String): Query; + + Limit(@sts_this thiz : Query, total: i32, offset: i32): Query; + + IsNotNull(@sts_this thiz : Query, field: String): Query; + + BeginGroup(@sts_this thiz : Query): Query; + + EndGroup(@sts_this thiz : Query): Query; + + PrefixKey(@sts_this thiz : Query, prefix: String): Query; + + SetSuggestIndex(@sts_this thiz : Query, index: String): Query; + + DeviceId(@sts_this thiz : Query, deviceId: String): Query; + + GetSqlLike(): String; +} +@ctor("Query") +function CreateQuery(): Query; + +interface SingleKVStore { + GetInner (): i64; + + @gen_async("put") + @gen_promise("put") + PutSync(key: String, value: ValueUnion): void; + + @gen_async("putBatch") + @gen_promise("putBatch") + PutBatchSync(entries: Array): void; + + @gen_async("putValuesBuckets") + @gen_promise("putValuesBuckets") + PutValuesBucketsSync(value: Array<@record Map>): void; + + @gen_async("delete") + @gen_promise("delete") + DeleteSync(key: String): void; + + @gen_async("delete") + @gen_promise("delete") + DeleteByPredicatesSync(predicates: @sts_type("dataSharePredicates.DataSharePredicates") Opaque): void; + + @gen_async("deleteBatch") + @gen_promise("deleteBatch") + DeleteBatchSync(keys: Array): void; + + @gen_async("removeDeviceData") + @gen_promise("removeDeviceData") + RemoveDeviceDataSync(deviceId: String): void; + + @gen_async("get") + @gen_promise("get") + GetSync(key: String): ValueUnion; + + @gen_async("getEntries") + @gen_promise("getEntries") + GetEntriesSync(keyPrefix: String): Array; + + @gen_async("getEntries") + @gen_promise("getEntries") + GetEntriesByQuerySync(query: Query): Array; + + @gen_async("getResultSet") + @gen_promise("getResultSet") + GetResultSetSync(keyPrefix: String): KVStoreResultSet; + + @gen_async("getResultSet") + @gen_promise("getResultSet") + GetResultSetByQuerySync(query: Query): KVStoreResultSet; + + @gen_async("getResultSet") + @gen_promise("getResultSet") + GetResultSetByPredicatesSync(predicates: @sts_type("dataSharePredicates.DataSharePredicates") Opaque): KVStoreResultSet; + + @gen_async("closeResultSet") + @gen_promise("closeResultSet") + CloseResultSetSync(resultSet: KVStoreResultSet): void; + + @gen_async("getResultSize") + @gen_promise("getResultSize") + GetResultSizeSync(query: Query): i32; + + @gen_async("backup") + @gen_promise("backup") + BackupSync(file: String): void; + + @gen_async("restore") + @gen_promise("restore") + RestoreSync(file: String): void; + + @gen_async("deleteBackup") + @gen_promise("deleteBackup") + DeleteBackupSync(files: Array): Array; + + @gen_async("startTransaction") + @gen_promise("startTransaction") + StartTransactionSync(): void; + + @gen_async("commit") + @gen_promise("commit") + CommitSync(): void; + + @gen_async("rollback") + @gen_promise("rollback") + RollbackSync(): void; + + @gen_async("enableSync") + @gen_promise("enableSync") + EnableSyncSync(enabled: bool): void; + + @gen_async("setSyncRange") + @gen_promise("setSyncRange") + SetSyncRangeSync(localLabels: Array, remoteSupportLabels: Array): void; + + @gen_async("setSyncParam") + @gen_promise("setSyncParam") + SetSyncParamSync(defaultAllowedDelayMs: i32): void; + + @overload("sync") + Sync(deviceIds: Array, mode: SyncMode, delayMs: Optional): void; + + @overload("sync") + SyncByQuery(deviceIds: Array, query: Query, mode: SyncMode, delayMs: Optional): void; + + OnDataChange(type: SubscribeType, f: (info: ChangeNotification) => void, @sts_last opq: Opaque): void; + OffDataChange(opq: Optional<@sts_type("Function1") Opaque>): void; + + OnSyncComplete(f: (info: Array) => void, @sts_last opq: Opaque): void; + OffSyncComplete(opq: Optional<@sts_type("Function1, void>") Opaque>): void; + + @gen_async("getSecurityLevel") + @gen_promise("getSecurityLevel") + GetSecurityLevelSync(): SecurityLevel; +} + +interface DeviceKVStore : SingleKVStore { + @gen_async("get") + @gen_promise("get") + GetByDeviceIdSync(deviceId: String, key: String): ValueUnion; + + @gen_async("getEntries") + @gen_promise("getEntries") + GetEntriesByDeviceIdSync(deviceId: String, keyPrefix: String): Array; + + @gen_async("getEntries") + @gen_promise("getEntries") + GetEntriesByDeviceIdAndQuerySync(deviceId: String, query: Query): Array; + + @gen_async("getResultSet") + @gen_promise("getResultSet") + GetResultSetByDeviceIdAndPrefixSync(deviceId: String, keyPrefix: String): KVStoreResultSet; + + @gen_async("getResultSet") + @gen_promise("getResultSet") + GetResultSetByDeviceIdAndQuerySync(deviceId: String, query: Query): KVStoreResultSet; + + @gen_async("getResultSet") + @gen_promise("getResultSet") + GetResultSetByDeviceIdAndPredicateSync(deviceId: String, predicates: @sts_type("dataSharePredicates.DataSharePredicates") Opaque): KVStoreResultSet; + + @gen_async("getResultSize") + @gen_promise("getResultSize") + GetResultSizeByDeviceIdSync(deviceId: String, query: Query): i32; +} + +function createKVManager(config: KVManagerConfig): KVManager; + +union KvStoreTypeUnion { + singleKVStore: SingleKVStore; + deviceKVStore: DeviceKVStore; + kvStore: Opaque; +} + +interface KVManager { + @gen_async("getKVStore") + @gen_promise("getKVStore") + GetKVStoreSync(storeId: String, options: Options): KvStoreTypeUnion; + + @gen_async("closeKVStore") + @gen_promise("closeKVStore") + CloseKVStoreSync(appId: String, storeId: String): void; + + @gen_async("deleteKVStore") + @gen_promise("deleteKVStore") + DeleteKVStoreSync(appId: String, storeId: String): void; + + @gen_async("getAllKVStoreId") + @gen_promise("getAllKVStoreId") + GetAllKVStoreIdSync(appId: String): Array; + + OnDistributedDataServiceDie(f: (para: OneUndef) => void, @sts_last opq: Opaque): void; + OffDistributedDataServiceDie(opq: Optional<@sts_type("Function1") Opaque>): void; +} \ No newline at end of file diff --git a/frameworks/ets/taihe/kv_store/include/ani_ability_utils.h b/frameworks/ets/taihe/kv_store/include/ani_ability_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..3dff158161048b84195d094638f1792e1e33d798 --- /dev/null +++ b/frameworks/ets/taihe/kv_store/include/ani_ability_utils.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OHOS_KV_STORE_ANI_ABILITY_UTILS_H_ +#define OHOS_KV_STORE_ANI_ABILITY_UTILS_H_ + +#include "taihe/runtime.hpp" +#include "ani_base_context.h" +#include "types.h" + +namespace OHOS { +namespace DistributedKVStore { +using namespace OHOS; + +struct ContextParam { + std::string baseDir = ""; + std::string hapName = ""; + int32_t area = DistributedKv::Area::EL1; + bool isSystemApp = false; + int32_t apiVersion = 9; +}; + +int32_t GetHapVersion(ani_env *env, ani_object value); +std::shared_ptr GetStageModeContext(ani_env *env, ani_object value); +int32_t AniGetContext(ani_object jsValue, ContextParam ¶m); +} +} +#endif \ No newline at end of file diff --git a/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_sync_callback_client.cpp b/frameworks/ets/taihe/kv_store/include/ani_error_utils.h similarity index 32% rename from frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_sync_callback_client.cpp rename to frameworks/ets/taihe/kv_store/include/ani_error_utils.h index 5e70f0dd806bca92e9748547855c1441328e9045..4b6b37f26cf282286a862bf710fc297e58a2409d 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_sync_callback_client.cpp +++ b/frameworks/ets/taihe/kv_store/include/ani_error_utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,49 +12,37 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -#define LOG_TAG "KvStoreSyncCallbackClient" - -#include "kvstore_sync_callback_client.h" -#include -#include -#include "dds_trace.h" +#ifndef OHOS_ANI_ERROR_UTILS_H +#define OHOS_ANI_ERROR_UTILS_H +#include +#include +#include "store_errno.h" #include "log_print.h" namespace OHOS { -namespace DistributedKv { -using namespace OHOS::DistributedDataDfx; -KvStoreSyncCallbackClient::~KvStoreSyncCallbackClient() -{ - syncCallbackInfo_.Clear(); -} +namespace DistributedKVStore { +using Status = OHOS::DistributedKv::Status; + +struct JsErrorCode { + int32_t status; + int32_t jsCode; + const char *message; +}; + +const std::optional GetJsErrorCode(int32_t errorCode); -void KvStoreSyncCallbackClient::SyncCompleted(const std::map &results, uint64_t sequenceId) -{ - DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__), TraceSwitch::BYTRACE_ON); - auto finded = syncCallbackInfo_.Find(sequenceId); - if (finded.first) { - finded.second->SyncCompleted(results); - DeleteSyncCallback(sequenceId); - } -} +void ThrowError(const char* message); +void ThrowError(int32_t code, const char* message); +void ThrowAniError(int32_t errCode, const std::string &errMessage); -void KvStoreSyncCallbackClient::AddSyncCallback( - const std::shared_ptr callback, uint64_t sequenceId) -{ - if (callback == nullptr) { - ZLOGE("callback is nullptr"); - return; - } - auto inserted = syncCallbackInfo_.Insert(sequenceId, callback); - if (!inserted) { - ZLOGE("The sequeuceId %{public}" PRIu64 "is repeat!", sequenceId); - } -} +#define ANI_ASSERT(assertion, message, retVal) \ + do { \ + if (!(assertion)) { \ + ThrowError("assertion (" #assertion ") failed: " message); \ + return retVal; \ + } \ + } while (0) -void KvStoreSyncCallbackClient::DeleteSyncCallback(uint64_t sequenceId) -{ - syncCallbackInfo_.Erase(sequenceId); -} -} // namespace DistributedKv +} // namespace DistributedKVStore } // namespace OHOS +#endif // OHOS_ANI_ERROR_UTILS_H diff --git a/frameworks/ets/taihe/kv_store/include/ani_kvstore_utils.h b/frameworks/ets/taihe/kv_store/include/ani_kvstore_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..3bf6c9b9e0b90de764c75baf1c75d358fbadf177 --- /dev/null +++ b/frameworks/ets/taihe/kv_store/include/ani_kvstore_utils.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OHOS_ANI_KVSTORE_UTILS_H +#define OHOS_ANI_KVSTORE_UTILS_H +#include "taihe/runtime.hpp" +#include "ohos.data.distributedkvstore.proj.hpp" +#include "ohos.data.distributedkvstore.impl.hpp" +#include +#include +#include + +#include "event_handler.h" +#include "event_runner.h" +#include "blob.h" +#include "datashare_values_bucket.h" +#include "types.h" +#include "kvstore_observer.h" +#include "kvstore_sync_callback.h" +#include "kvstore_death_recipient.h" + +static constexpr const char* SCHEMA_VERSION = "SCHEMA_VERSION"; +static constexpr const char* SCHEMA_MODE = "SCHEMA_MODE"; +static constexpr const char* SCHEMA_DEFINE = "SCHEMA_DEFINE"; +static constexpr const char* SCHEMA_INDEXES = "SCHEMA_INDEXES"; +static constexpr const char* SCHEMA_SKIPSIZE = "SCHEMA_SKIPSIZE"; +static constexpr const char* DEFAULT_SCHEMA_VERSION = "1.0"; +static constexpr const char* SCHEMA_STRICT = "STRICT"; +static constexpr const char* SCHEMA_COMPATIBLE = "COMPATIBLE"; + +static constexpr const char* FIELD_NAME = "FIELD_NAME"; +static constexpr const char* VALUE_TYPE = "VALUE_TYPE"; +static constexpr const char* DEFAULT_VALUE = "DEFAULT_VALUE"; +static constexpr const char* IS_DEFAULT_VALUE = "IS_DEFAULT_VALUE"; +static constexpr const char* IS_NULLABLE = "IS_NULLABLE"; +static constexpr const char* CHILDREN = "CHILDREN"; +static constexpr const char* SPLIT = ","; +static constexpr const char* NOT_NULL = ", NOT NULL,"; +static constexpr const char* DEFAULT = " DEFAULT "; +static constexpr const char* MARK = "'"; + +enum { + SCHEMA_MODE_SLOPPY, + SCHEMA_MODE_STRICT, +}; + +enum { + JS_SECURITY_LEVEL_S1 = 0, + JS_SECURITY_LEVEL_S2, + JS_SECURITY_LEVEL_S3, + JS_SECURITY_LEVEL_S4, +}; + +namespace ani_kvstoreutils { +using namespace OHOS; +using ValueVariant = std::variant, bool, double, int64_t>; +using DataShareValueVariant = DataShare::DataShareValueObject::Type; + +enum { + /* Blob's first byte is the blob's data ValueType */ + STRING = 0, + INTEGER = 1, + FLOAT = 2, + BYTE_ARRAY = 3, + BOOLEAN = 4, + DOUBLE = 5, + LONG = 6, + INVALID = 255 +}; + +enum { + /* exported js SubscribeType is (DistributedKv::SubscribeType-1) */ + SUBSCRIBE_LOCAL = 0, /* i.e. SubscribeType::SUBSCRIBE_TYPE_LOCAL-1 */ + SUBSCRIBE_REMOTE = 1, /* i.e. SubscribeType::SUBSCRIBE_TYPE_REMOTE-1 */ + SUBSCRIBE_LOCAL_REMOTE = 2, /* i.e. SubscribeType::SUBSCRIBE_TYPE_ALL-1 */ + SUBSCRIBE_COUNT = 3 +}; + +bool IsValidStoreId(std::string const& storeId); +bool IsStoreTypeSupported(DistributedKv::Options const& options); +bool TaiheSecurityLevelToNative(int32_t level, int32_t &out); +bool SecurityLevelToTaihe(int32_t level, int32_t &out); +DistributedKv::SubscribeType SubscribeTypeToNative(::ohos::data::distributedkvstore::SubscribeType type); +DistributedKv::SubscribeType SubscribeTypeToNative(uint8_t type); +void TaiheValueUnionToNativeVariant(::ohos::data::distributedkvstore::ValueUnion const& value, + ValueVariant &resultObj); +void TaiheValueToVariant(::ohos::data::distributedkvstore::Value const& value, + ValueVariant &resultObj); +void TaiheDataShareValueToVariant(::ohos::data::distributedkvstore::DataShareValueUnion const& value, + DataShareValueVariant &resultObj); +::ohos::data::distributedkvstore::ValueUnion Blob2TaiheValue(DistributedKv::Blob const& blob, uint8_t &resultType); +DistributedKv::Blob VariantValue2Blob(ValueVariant const& value); +bool EntryArrayToNative(::taihe::array_view<::ohos::data::distributedkvstore::Entry> const& taiheEntries, + std::vector &out, bool hasSchema); +std::vector StringArrayToNative(::taihe::array_view<::taihe::string> const& para); +::ohos::data::distributedkvstore::Entry GetEmptyTaiheEntry(); +::ohos::data::distributedkvstore::Entry KvEntryToTaihe(DistributedKv::Entry const& kventry, bool hasSchema); +::taihe::array<::ohos::data::distributedkvstore::Entry> KvEntryArrayToTaihe( + std::vector const& kventries, bool hasSchema); +::ohos::data::distributedkvstore::ChangeNotification KvChangeNotificationToTaihe( + DistributedKv::ChangeNotification const& kvNotification, bool hasSchema); +::taihe::map<::taihe::string, int32_t> KvStatusMapToTaiheMap( + std::map const& mapInfo); +::taihe::array KvStatusMapToTaiheArray(ani_env* env, + std::map const& mapInfo); +int32_t TaiheValueTypeToNative(int32_t taiheType); +::ohos::data::distributedkvstore::ValueType NativeTypeToTaihe(int32_t taiheType); +} // namespace ani_kvstoreutils +#endif // OHOS_ANI_KVSTORE_UTILS_H diff --git a/frameworks/ets/taihe/kv_store/include/ani_observer_utils.h b/frameworks/ets/taihe/kv_store/include/ani_observer_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..9461779141fcff879de2b9afc65d51558ee1f30d --- /dev/null +++ b/frameworks/ets/taihe/kv_store/include/ani_observer_utils.h @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OHOS_ANI_OBSERVER_UTILS_H +#define OHOS_ANI_OBSERVER_UTILS_H +#include "taihe/runtime.hpp" +#include "ohos.data.distributedkvstore.proj.hpp" +#include "ohos.data.distributedkvstore.impl.hpp" +#include +#include +#include + +#include "event_handler.h" +#include "event_runner.h" +#include "types.h" +#include "kvstore_observer.h" +#include "kvstore_sync_callback.h" +#include "kvstore_death_recipient.h" + +namespace ani_observerutils { + +using namespace OHOS; + +class GlobalRefGuard { + ani_env *env_ = nullptr; + ani_ref ref_ = nullptr; + +public: + GlobalRefGuard(ani_env *env, ani_object obj) : env_(env) + { + if (!env_ || !obj) + return; + if (ANI_OK != env_->GlobalReference_Create(obj, &ref_)) { + ref_ = nullptr; + } + } + explicit operator bool() const + { + return ref_ != nullptr; + } + ani_ref get() const + { + return ref_; + } + ~GlobalRefGuard() + { + if (env_ && ref_) { + env_->GlobalReference_Delete(ref_); + } + } + + GlobalRefGuard(const GlobalRefGuard &) = delete; + GlobalRefGuard &operator=(const GlobalRefGuard &) = delete; +}; + +using JsDataChangeCallbackType = ::taihe::callback; +using JsSyncCompleteCallbackType = ::taihe::callback)>; +using JsServiceDeathType = ::taihe::callback; +using VarCallbackType = std::variant< + std::monostate, + ::taihe::callback, + ::taihe::callback)>, + ::taihe::callback>; + +class JsBaseObserver { +public: + JsBaseObserver(VarCallbackType cb, ani_ref jsCallbackRef); + virtual ~JsBaseObserver() {} + bool SendEventToMainThread(const std::function func); + void Release(); + + std::recursive_mutex mutex_; + VarCallbackType jsCallback_; + ani_ref jsCallbackRef_ = nullptr; + static std::shared_ptr mainHandler_; +}; + +template +ani_ref CreateCallbackRefIfNotDuplicate(std::vector> const& cbVec, + ani_object callbackObj) +{ + ani_ref callbackRef = nullptr; + ani_env *env = taihe::get_env(); + if (env == nullptr || ANI_OK != env->GlobalReference_Create(callbackObj, &callbackRef)) { + return nullptr; + } + bool isDuplicate = std::any_of(cbVec.begin(), cbVec.end(), + [env, callbackRef](std::shared_ptr const& obj) { + ani_boolean isEqual = false; + return (ANI_OK == env->Reference_StrictEquals(callbackRef, obj->jsCallbackRef_, &isEqual)) && isEqual; + }); + if (isDuplicate) { + env->GlobalReference_Delete(callbackRef); + return nullptr; + } + return callbackRef; +} + +class DataObserver : public JsBaseObserver, + public DistributedKv::KvStoreObserver, public DistributedKv::KvStoreSyncCallback, + public std::enable_shared_from_this { +public: + DataObserver(VarCallbackType cb, ani_ref jsCallbackRef); + ~DataObserver(); + void SetIsSchemaStore(bool isSchemaStore); + void OnChange(const DistributedKv::ChangeNotification& info) override; + void OnChangeInMainThread(const DistributedKv::ChangeNotification& info); + void SyncCompleted(const std::map& results) override; + void SyncCompletedInMainThread(const std::map& results); + +protected: + bool isSchemaStore_ = false; +}; + +class ManagerObserver : public JsBaseObserver, public DistributedKv::KvStoreDeathRecipient, + public std::enable_shared_from_this { +public: + ManagerObserver(VarCallbackType cb, ani_ref jsCallbackRef); + ~ManagerObserver(); + void OnRemoteDied() override; + void OnRemoteDiedInMainThread(); +}; + +} // namespace ani_observerutils +#endif // OHOS_ANI_OBSERVER_UTILS_H diff --git a/frameworks/ets/taihe/kv_store/include/ani_utils.h b/frameworks/ets/taihe/kv_store/include/ani_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..df430d5f078f0deb8111b4976c776d81fe23c1e3 --- /dev/null +++ b/frameworks/ets/taihe/kv_store/include/ani_utils.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OHOS_ANI_UTILS_H +#define OHOS_ANI_UTILS_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "taihe/runtime.hpp" + +namespace ani_utils { +int32_t AniGetProperty(ani_env *env, ani_object ani_obj, const char *property, std::string &result, + bool optional = false); +int32_t AniGetProperty(ani_env *env, ani_object ani_obj, const char *property, bool &result, + bool optional = false); +int32_t AniGetProperty(ani_env *env, ani_object ani_obj, const char *property, int32_t &result, + bool optional = false); +int32_t AniGetProperty(ani_env *env, ani_object ani_obj, const char *property, uint32_t &result, + bool optional = false); +int32_t AniGetProperty(ani_env *env, ani_object ani_obj, const char *property, ani_object &result, + bool optional = false); + +class AniObjectUtils { +public: + template + static ani_status Wrap(ani_env *env, ani_object object, T *nativePtr, const char *propName = "nativePtr") + { + return env->Object_SetFieldByName_Long(object, propName, reinterpret_cast(nativePtr)); + } + + template + static T* Unwrap(ani_env *env, ani_object object, const char *propName = "nativePtr") + { + ani_long nativePtr; + if (ANI_OK != env->Object_GetFieldByName_Long(object, propName, &nativePtr)) { + return nullptr; + } + return reinterpret_cast(nativePtr); + } +}; + +class AniStringUtils { +public: + static std::string ToStd(ani_env *env, ani_string ani_str); + static ani_string ToAni(ani_env *env, const std::string& str); +}; + +ani_status AniCreateInt(ani_env* env, int32_t value, ani_object& result); +bool AniCreateTuple(ani_env* env, ani_ref item1, ani_ref item2, ani_tuple_value &tuple); + +bool AniIsInstanceOf(ani_env* aniEnv, ani_ref aniRef, const std::string& cls_name); + +} //namespace ani_utils +#endif + diff --git a/frameworks/ets/taihe/kv_store/src/ani_ability_utils.cpp b/frameworks/ets/taihe/kv_store/src/ani_ability_utils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..68349674359bc76da3bcc73f4dfd198640580813 --- /dev/null +++ b/frameworks/ets/taihe/kv_store/src/ani_ability_utils.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "AniAbilityUtils" +#include "ani_ability_utils.h" +#include "ani_utils.h" +#include "log_print.h" + +#include + +namespace OHOS { +namespace DistributedKVStore { + +using namespace taihe; +using namespace OHOS; +using namespace OHOS::DistributedKVStore; + +static constexpr int32_t INVALID_HAP_VERSION = -1; +static constexpr int DEFAULT_API_VERSION = 9; + +#define API_VERSION_MOD 100 + +int32_t GetHapVersion(ani_env *env, ani_object value) +{ + auto stageContext = OHOS::AbilityRuntime::GetStageModeContext(env, value); + if (stageContext == nullptr) { + ZLOGE("GetStageModeContext failed."); + return INVALID_HAP_VERSION ; + } + auto appInfo = stageContext->GetApplicationInfo(); + if (appInfo != nullptr) { + return appInfo->apiTargetVersion % API_VERSION_MOD; + } + ZLOGW("GetApplicationInfo failed."); + return INVALID_HAP_VERSION ; +} + +int32_t GetApiVersion(ani_env* env, ani_object value) +{ + auto context = OHOS::AbilityRuntime::GetStageModeContext(env, value); + if (context == nullptr) { + ZLOGW("get context fail."); + return DEFAULT_API_VERSION; + } + auto appInfo = context->GetApplicationInfo(); + if (appInfo == nullptr) { + ZLOGW("get app info fail."); + return DEFAULT_API_VERSION; + } + return appInfo->apiTargetVersion % API_VERSION_MOD; +} + +std::shared_ptr GetStageModeContext(ani_env *env, ani_object value) +{ + return OHOS::AbilityRuntime::GetStageModeContext(env, value); +} + +int32_t AniGetContext(ani_object jsValue, ContextParam ¶m) +{ + ani_env *env = taihe::get_env(); + if (jsValue == nullptr) { + ZLOGE("jsValue nullptr"); + return ANI_INVALID_ARGS; + } + int32_t status = ani_utils::AniGetProperty(env, jsValue, "databaseDir", param.baseDir); + if (status != ANI_OK) { + ZLOGE("get databaseDir failed."); + return ANI_INVALID_ARGS; + } + status = ani_utils::AniGetProperty(env, jsValue, "area", param.area, true); + if (status != ANI_OK) { + ZLOGE("get area failed."); + return ANI_INVALID_ARGS; + } + ani_object hapInfo = nullptr; + status = ani_utils::AniGetProperty(env, jsValue, "currentHapModuleInfo", hapInfo); + if (status != ANI_OK) { + ZLOGE("get currentHapModuleInfo failed."); + return ANI_INVALID_ARGS; + } + if (hapInfo != nullptr) { + status = ani_utils::AniGetProperty(env, hapInfo, "name", param.hapName); + if (status != ANI_OK) { + ZLOGE("get hap name failed"); + return ANI_INVALID_ARGS; + } + } + ani_object appInfo = nullptr; + status = ani_utils::AniGetProperty(env, jsValue, "applicationInfo", appInfo); + if (status != ANI_OK) { + ZLOGE("get applicationInfo failed."); + return ANI_INVALID_ARGS; + } + if (appInfo != nullptr) { + status = ani_utils::AniGetProperty(env, appInfo, "systemApp", param.isSystemApp, true); + if (status != ANI_OK) { + ZLOGE("get applicationInfo.systemApp failed"); + return ANI_INVALID_ARGS; + } + param.apiVersion = GetApiVersion(env, jsValue); + } + return ANI_OK; +} + +} +} \ No newline at end of file diff --git a/frameworks/ets/taihe/kv_store/src/ani_constructor.cpp b/frameworks/ets/taihe/kv_store/src/ani_constructor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d0f21d138887c8df654bd055cab4a636bced93bf --- /dev/null +++ b/frameworks/ets/taihe/kv_store/src/ani_constructor.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "ohos.data.distributedkvstore.ani.hpp" +#if __has_include() +#include +#elif __has_include() +#include +#else +#error "ani.h not found. Please ensure the Ani SDK is correctly installed." +#endif +ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) +{ + ani_env *env; + if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env)) { + return ANI_ERROR; + } + ani_status status = ANI_OK; + if (ANI_OK != ohos::data::distributedkvstore::ANIRegister(env)) { + std::cerr << "Error from ohos::data::distributedkvstore::ANIRegister" << std::endl; + status = ANI_ERROR; + } + *result = ANI_VERSION_1; + return status; +} diff --git a/frameworks/ets/taihe/kv_store/src/ani_error_utils.cpp b/frameworks/ets/taihe/kv_store/src/ani_error_utils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..62998ef80f816a699d181794cc15f463a3611af0 --- /dev/null +++ b/frameworks/ets/taihe/kv_store/src/ani_error_utils.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "AniErrorUtils" +#include "taihe/runtime.hpp" +#include "ani_error_utils.h" + +#include + +namespace OHOS::DistributedKVStore { +using JsErrorCode = OHOS::DistributedKVStore::JsErrorCode; + +static constexpr JsErrorCode JS_ERROR_CODE_MSGS[] = { + { Status::INVALID_ARGUMENT, 401, "Parameter error: Parameters verification failed." }, + { 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::PERMISSION_DENIED, 202, "Permission denied" }, + { Status::CRYPT_ERROR, 15100003, "Database corrupted." }, + { Status::OVER_MAX_LIMITS, 15100001, "Over max limits." }, + { 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."} +}; + +const std::optional GetJsErrorCode(int32_t errorCode) +{ + auto jsErrorCode = JsErrorCode{ errorCode, -1, "" }; + auto iter = std::lower_bound(JS_ERROR_CODE_MSGS, + JS_ERROR_CODE_MSGS + sizeof(JS_ERROR_CODE_MSGS) / sizeof(JS_ERROR_CODE_MSGS[0]), jsErrorCode, + [](const JsErrorCode &jsErrorCode1, const JsErrorCode &jsErrorCode2) { + return jsErrorCode1.status < jsErrorCode2.status; + }); + if (iter < JS_ERROR_CODE_MSGS + sizeof(JS_ERROR_CODE_MSGS) / sizeof(JS_ERROR_CODE_MSGS[0]) && + iter->status == errorCode) { + return *iter; + } + return std::nullopt; +} + +void ThrowError(const char* message) +{ + if (message == nullptr) { + return; + } + std::string errMsg(message); + taihe::set_error(errMsg); +} + +void ThrowError(int32_t code, const char* message) +{ + if (message == nullptr) { + return; + } + std::string errMsg(message); + taihe::set_business_error(code, errMsg); +} + +void ThrowAniError(int32_t status, const std::string &errMessage) +{ + ZLOGW("ThrowAniError status %{public}d, offset %{public}d, message: %{public}s", + status, status - DistributedKv::Status::ERROR, errMessage.c_str()); + if (status == DistributedKv::Status::SUCCESS) { + return; + } + auto errorMsg = GetJsErrorCode(status); + JsErrorCode aniError; + if (errorMsg.has_value()) { + aniError = errorMsg.value(); + } else { + aniError.jsCode = -1; + aniError.message = ""; + } + + std::string message(aniError.message); + if (status == DistributedKv::Status::INVALID_ARGUMENT) { + message += errMessage; + } + + if (aniError.jsCode == -1) { + ThrowError(message.c_str()); + return; + } + ThrowError(aniError.jsCode, message.c_str()); +} +} // namespace OHOS::DistributedKVStore \ No newline at end of file diff --git a/frameworks/ets/taihe/kv_store/src/ani_kvstore_utils.cpp b/frameworks/ets/taihe/kv_store/src/ani_kvstore_utils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..29521f3f4c02481b812fbc45d238f0c6c2cd2ec4 --- /dev/null +++ b/frameworks/ets/taihe/kv_store/src/ani_kvstore_utils.cpp @@ -0,0 +1,481 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "AniKvStoreUtils" +#include "ani_kvstore_utils.h" +#include "ani_utils.h" +#include +#include + +#include "log_print.h" + +using namespace ::ohos::data::distributedkvstore; +using namespace OHOS::DistributedKVStore; + +namespace ani_kvstoreutils { + +static constexpr int MAX_STORE_ID_LEN = 128; +static constexpr uint8_t UNVALID_SUBSCRIBE_TYPE = 255; + +bool IsValidStoreId(std::string const& storeId) +{ + if (storeId.empty() || storeId.size() > MAX_STORE_ID_LEN) { + return false; + } + auto iter = std::find_if_not(storeId.begin(), storeId.end(), + [](char c) { return (std::isdigit(c) || std::isalpha(c) || c == '_'); }); + return (iter == storeId.end()); +} + +bool IsStoreTypeSupported(DistributedKv::Options const& options) +{ + return (options.kvStoreType == DistributedKv::KvStoreType::DEVICE_COLLABORATION) + || (options.kvStoreType == DistributedKv::KvStoreType::SINGLE_VERSION); +} + +bool TaiheSecurityLevelToNative(int32_t level, int32_t &out) +{ + if (level == JS_SECURITY_LEVEL_S1) { + out = OHOS::DistributedKv::SecurityLevel::S1; + } else if (level == JS_SECURITY_LEVEL_S2) { + out = OHOS::DistributedKv::SecurityLevel::S2; + } else if (level == JS_SECURITY_LEVEL_S3) { + out = OHOS::DistributedKv::SecurityLevel::S3; + } else if (level == JS_SECURITY_LEVEL_S4) { + out = OHOS::DistributedKv::SecurityLevel::S4; + } else { + ZLOGE("TaiheSecurityLevelToNative failed, in level = %{public}d", level); + return false; + } + return true; +} + +bool SecurityLevelToTaihe(int32_t level, int32_t &out) +{ + if (level == OHOS::DistributedKv::SecurityLevel::S1) { + out = JS_SECURITY_LEVEL_S1; + } else if (level == OHOS::DistributedKv::SecurityLevel::S2) { + out = JS_SECURITY_LEVEL_S2; + } else if (level == OHOS::DistributedKv::SecurityLevel::S3) { + out = JS_SECURITY_LEVEL_S3; + } else if (level == OHOS::DistributedKv::SecurityLevel::S4) { + out = JS_SECURITY_LEVEL_S4; + } else { + ZLOGE("SecurityLevelToTaihe failed, in level = %{public}d", level); + return false; + } + return true; +} + +void TaiheValueUnionToNativeVariant(::ohos::data::distributedkvstore::ValueUnion const& value, + ValueVariant &resultObj) +{ + auto tag = value.get_tag(); + switch (tag) { + case ValueUnion::tag_t::F64: { + resultObj = value.get_F64_ref(); + } + break; + case ValueUnion::tag_t::INT64: { + resultObj = value.get_INT64_ref(); + } + break; + case ValueUnion::tag_t::STRING: { + resultObj = std::string(value.get_STRING_ref()); + } + break; + case ValueUnion::tag_t::BOOL: { + resultObj = value.get_BOOL_ref(); + } + break; + case ValueUnion::tag_t::UINT8Array: { + auto &tmp = value.get_UINT8Array_ref(); + std::vector stdvector(tmp.data(), tmp.data() + tmp.size()); + resultObj = stdvector; + } + break; + default: + ZLOGE("TaiheValueUnionToNativeVariant unmatched tag"); + break; + } +} + +void TaiheValueToVariant(::ohos::data::distributedkvstore::Value const& value, + ValueVariant &resultObj) +{ + ::ohos::data::distributedkvstore::ValueUnion valueUnion = value.value; + auto tag = valueUnion.get_tag(); + switch (tag) { + case ValueUnion::tag_t::F64: { + resultObj = valueUnion.get_F64_ref(); + } + break; + case ValueUnion::tag_t::INT64: { + resultObj = valueUnion.get_INT64_ref(); + } + break; + case ValueUnion::tag_t::STRING: { + resultObj = std::string(valueUnion.get_STRING_ref()); + } + break; + case ValueUnion::tag_t::BOOL: { + resultObj = valueUnion.get_BOOL_ref(); + } + break; + case ValueUnion::tag_t::UINT8Array: { + auto &tmp = valueUnion.get_UINT8Array_ref(); + std::vector stdvector(tmp.data(), tmp.data() + tmp.size()); + resultObj = stdvector; + } + break; + default: + ZLOGE("TaiheValueToVariant unmatched tag"); + break; + } +} + +void TaiheDataShareValueToVariant(::ohos::data::distributedkvstore::DataShareValueUnion const& value, + DataShareValueVariant &resultObj) +{ + auto tag = value.get_tag(); + switch (tag) { + case DataShareValueUnion::tag_t::INT64: { + resultObj = value.get_INT64_ref(); + } + break; + case DataShareValueUnion::tag_t::F64: { + resultObj = value.get_F64_ref(); + } + break; + case DataShareValueUnion::tag_t::STRING: { + resultObj = std::string(value.get_STRING_ref()); + } + break; + case DataShareValueUnion::tag_t::BOOL: { + resultObj = value.get_BOOL_ref(); + } + break; + case DataShareValueUnion::tag_t::UINT8Array: { + auto &tmp = value.get_UINT8Array_ref(); + std::vector stdvector(tmp.data(), tmp.data() + tmp.size()); + resultObj = stdvector; + } + break; + default: + ZLOGE("TaiheDataShareValueToVariant unmatched tag"); + break; + } +} + +DistributedKv::SubscribeType SubscribeTypeToNative(::ohos::data::distributedkvstore::SubscribeType type) +{ + switch (type.get_key()) { + case ::ohos::data::distributedkvstore::SubscribeType::key_t::SUBSCRIBE_TYPE_LOCAL: + return DistributedKv::SubscribeType::SUBSCRIBE_TYPE_LOCAL; + case ::ohos::data::distributedkvstore::SubscribeType::key_t::SUBSCRIBE_TYPE_REMOTE: + return DistributedKv::SubscribeType::SUBSCRIBE_TYPE_REMOTE; + case ::ohos::data::distributedkvstore::SubscribeType::key_t::SUBSCRIBE_TYPE_ALL: + return DistributedKv::SubscribeType::SUBSCRIBE_TYPE_ALL; + default: + return static_cast(UNVALID_SUBSCRIBE_TYPE); + } +} + +DistributedKv::SubscribeType SubscribeTypeToNative(uint8_t type) +{ + switch (type) { + case 0: // 0 means SUBSCRIBE_TYPE_LOCAL + return DistributedKv::SubscribeType::SUBSCRIBE_TYPE_LOCAL; + case 1: // 1 means SUBSCRIBE_TYPE_REMOTE + return DistributedKv::SubscribeType::SUBSCRIBE_TYPE_REMOTE; + case 2: // 2 means SUBSCRIBE_TYPE_ALL + return DistributedKv::SubscribeType::SUBSCRIBE_TYPE_ALL; + default: + return DistributedKv::SubscribeType::SUBSCRIBE_TYPE_LOCAL; + } +} + +::ohos::data::distributedkvstore::ValueUnion Blob2TaiheValue(DistributedKv::Blob const& blob, uint8_t &resultType) +{ + auto& data = blob.Data(); + if (data.size() < 1) { + ZLOGE("Blob have no data!"); + return ::ohos::data::distributedkvstore::ValueUnion::make_STRING(std::string("")); + } + resultType = data[0]; + std::vector real(data.begin() + 1, data.end()); + ZLOGD("Blob::type %{public}d size=%{public}d", static_cast(data[0]), static_cast(real.size())); + if (data[0] == ani_kvstoreutils::INTEGER) { + resultType = ani_kvstoreutils::LONG; + uint32_t tmp4int = be32toh(*reinterpret_cast(&(real[0]))); + int32_t tmp = *reinterpret_cast(&tmp4int); + return ::ohos::data::distributedkvstore::ValueUnion::make_INT64(tmp); + } else if (data[0] == ani_kvstoreutils::FLOAT) { + resultType = ani_kvstoreutils::DOUBLE; + uint32_t tmp4flt = be32toh(*reinterpret_cast(&(real[0]))); + float tmp = *reinterpret_cast((void*)(&tmp4flt)); + return ::ohos::data::distributedkvstore::ValueUnion::make_F64(tmp); + } else if (data[0] == ani_kvstoreutils::BYTE_ARRAY) { + auto tmp = std::vector(real.begin(), real.end()); + return ::ohos::data::distributedkvstore::ValueUnion::make_UINT8Array(tmp); + } else if (data[0] == ani_kvstoreutils::BOOLEAN) { + return ::ohos::data::distributedkvstore::ValueUnion::make_BOOL(real[0]); + } else if (data[0] == ani_kvstoreutils::DOUBLE) { + uint64_t tmp4dbl = be64toh(*reinterpret_cast(&(real[0]))); + double tmp = *reinterpret_cast((void*)(&tmp4dbl)); + return ::ohos::data::distributedkvstore::ValueUnion::make_F64(tmp); + } else if (data[0] == ani_kvstoreutils::STRING) { + auto tmp = std::string(real.begin(), real.end()); + return ::ohos::data::distributedkvstore::ValueUnion::make_STRING(tmp); + } else if (data[0] == ani_kvstoreutils::LONG) { + uint64_t tmp8int = be64toh(*reinterpret_cast(&(real[0]))); + int64_t tmp = *reinterpret_cast(&tmp8int); + return ::ohos::data::distributedkvstore::ValueUnion::make_INT64(tmp); + } else { + // for schema-db, if (data[0] == JSUtil::STRING), no beginning byte! + resultType = ani_kvstoreutils::STRING; + auto tmp = std::string(data.begin(), data.end()); + return ::ohos::data::distributedkvstore::ValueUnion::make_STRING(tmp); + } +} + +DistributedKv::Blob VariantValue2Blob(ValueVariant const& value) +{ + std::vector data; + auto strValue = std::get_if(&value); + if (strValue != nullptr) { + data.push_back(ani_kvstoreutils::STRING); + data.insert(data.end(), (*strValue).begin(), (*strValue).end()); + } + auto u8ArrayValue = std::get_if>(&value); + if (u8ArrayValue != nullptr) { + data.push_back(ani_kvstoreutils::BYTE_ARRAY); + data.insert(data.end(), (*u8ArrayValue).begin(), (*u8ArrayValue).end()); + } + auto boolValue = std::get_if(&value); + if (boolValue != nullptr) { + data.push_back(ani_kvstoreutils::BOOLEAN); + data.push_back(static_cast(*boolValue)); + } + uint8_t *res = nullptr; + auto intValue = std::get_if(&value); + if (intValue != nullptr) { + int32_t tmp = *intValue; // copy value, and make it available in stack space. + uint32_t tmp32 = htobe32(*reinterpret_cast(&tmp)); + res = reinterpret_cast(&tmp32); + data.push_back(ani_kvstoreutils::INTEGER); + data.insert(data.end(), res, res + sizeof(int32_t) / sizeof(uint8_t)); + } + auto int64Value = std::get_if(&value); + if (int64Value != nullptr) { + int64_t tmp = *int64Value; // copy value, and make it available in stack space. + uint64_t tmp64 = htobe64(*reinterpret_cast(&tmp)); + res = reinterpret_cast(&tmp64); + data.push_back(ani_kvstoreutils::LONG); + data.insert(data.end(), res, res + sizeof(int64_t) / sizeof(uint8_t)); + } + auto fltValue = std::get_if(&value); + if (fltValue != nullptr) { + float tmp = *fltValue; // copy value, and make it available in stack space. + uint32_t tmp32 = htobe32(*reinterpret_cast(&tmp)); + res = reinterpret_cast(&tmp32); + data.push_back(ani_kvstoreutils::FLOAT); + data.insert(data.end(), res, res + sizeof(float) / sizeof(uint8_t)); + } + auto dblValue = std::get_if(&value); + if (dblValue != nullptr) { + double tmp = *dblValue; // copy value, and make it available in stack space. + uint64_t tmp64 = htobe64(*reinterpret_cast(&tmp)); + res = reinterpret_cast(&tmp64); + data.push_back(ani_kvstoreutils::DOUBLE); + data.insert(data.end(), res, res + sizeof(double) / sizeof(uint8_t)); + } + return DistributedKv::Blob(data); +} + +std::vector StringArrayToNative(::taihe::array_view<::taihe::string> const& para) +{ + std::vector result(para.size()); + std::transform(para.begin(), para.end(), result.begin(), [](::taihe::string c) { + return std::string(c); + }); + return result; +} + +bool EntryArrayToNative(::taihe::array_view<::ohos::data::distributedkvstore::Entry> const& taiheEntries, + std::vector &out, bool hasSchema) +{ + for (auto iter = taiheEntries.begin(); iter != taiheEntries.end(); iter++) { + ::ohos::data::distributedkvstore::Entry &item = *iter; + DistributedKv::Entry kvEntry; + kvEntry.key = std::string(item.key); + ani_kvstoreutils::ValueVariant variant; + TaiheValueToVariant(item.value, variant); + if (hasSchema) { + if (!std::holds_alternative(variant)) { + return false; + } + kvEntry.value = std::get(variant); + } else { + kvEntry.value = VariantValue2Blob(variant); + } + out.push_back(kvEntry); + } + return true; +} + +::ohos::data::distributedkvstore::Entry GetEmptyTaiheEntry() +{ + auto taiheStringValueType = ohos::data::distributedkvstore::ValueType::from_value(0); + ::ohos::data::distributedkvstore::Entry taiEntryEmpty = { std::string(), + { taiheStringValueType, ::ohos::data::distributedkvstore::ValueUnion::make_STRING(std::string()) } + }; + return taiEntryEmpty; +} + +::ohos::data::distributedkvstore::Entry KvEntryToTaihe(DistributedKv::Entry const& kventry, bool hasSchema) +{ + if (kventry.value.Size() <= 0) { + auto taiEntryEmpty = GetEmptyTaiheEntry(); + ZLOGW("KvEntryToTaihe ret empty"); + return taiEntryEmpty; + } + if (hasSchema) { + auto strValueType = ohos::data::distributedkvstore::ValueType::from_value(0); + ::ohos::data::distributedkvstore::Entry taiEntry = { kventry.key.ToString(), + {strValueType, ::ohos::data::distributedkvstore::ValueUnion::make_STRING(kventry.value.ToString()) } + }; + return taiEntry; + } else { + uint8_t resultType = kventry.value[0]; + auto taiheTemp = Blob2TaiheValue(kventry.value, resultType); + auto taiheValueType = NativeTypeToTaihe(resultType); + ::ohos::data::distributedkvstore::Entry taiEntry = { kventry.key.ToString(), + {taiheValueType, taiheTemp } + }; + return taiEntry; + } +} + +::taihe::array<::ohos::data::distributedkvstore::Entry> KvEntryArrayToTaihe( + std::vector const& kventries, bool hasSchema) +{ + std::vector<::ohos::data::distributedkvstore::Entry> taiheEntries; + std::for_each(kventries.begin(), kventries.end(), [ hasSchema, &taiheEntries ](DistributedKv::Entry c) { + ::ohos::data::distributedkvstore::Entry taiheItem = ani_kvstoreutils::KvEntryToTaihe(c, hasSchema); + taiheEntries.push_back(taiheItem); + }); + return ::taihe::array<::ohos::data::distributedkvstore::Entry>(::taihe::copy_data_t{}, + taiheEntries.data(), taiheEntries.size()); +} + +::ohos::data::distributedkvstore::ChangeNotification KvChangeNotificationToTaihe( + DistributedKv::ChangeNotification const& kvNotification, bool hasSchema) +{ + ::ohos::data::distributedkvstore::ChangeNotification result = {{}, {}, {}, ""}; + result.insertEntries = KvEntryArrayToTaihe(kvNotification.GetInsertEntries(), hasSchema); + result.updateEntries = KvEntryArrayToTaihe(kvNotification.GetUpdateEntries(), hasSchema); + result.deleteEntries = KvEntryArrayToTaihe(kvNotification.GetDeleteEntries(), hasSchema); + result.deviceId = kvNotification.GetDeviceId(); + return result; +} + +::taihe::map<::taihe::string, int32_t> KvStatusMapToTaiheMap( + std::map const& mapInfo) +{ + ::taihe::map<::taihe::string, int32_t> result; + for (auto &[key, value] : mapInfo) { + ::taihe::string taihekey(key); + result.emplace(taihekey, value); + } + return result; +} + +::taihe::array KvStatusMapToTaiheArray(ani_env* env, + std::map const& mapInfo) +{ + if (env == nullptr) { + return {}; + } + std::vector stdArray; + for (auto &[key, value] : mapInfo) { + ani_ref strRef = ani_utils::AniStringUtils::ToAni(env, key); + ani_object valueObj = {}; + if (ANI_OK != ani_utils::AniCreateInt(env, value, valueObj)) { + break; + } + ani_tuple_value tupleItem {}; + if (!ani_utils::AniCreateTuple(env, strRef, valueObj, tupleItem)) { + break; + } + stdArray.push_back(reinterpret_cast(tupleItem)); + } + return ::taihe::array(::taihe::copy_data_t{}, stdArray.data(), stdArray.size()); +} + +int32_t TaiheValueTypeToNative(int32_t taiheType) +{ + switch (taiheType) { + case (int32_t)::ohos::data::distributedkvstore::ValueType::key_t::STRING: + return ani_kvstoreutils::STRING; + break; + case (int32_t)::ohos::data::distributedkvstore::ValueType::key_t::BYTE_ARRAY: + return ani_kvstoreutils::BYTE_ARRAY; + break; + case (int32_t)::ohos::data::distributedkvstore::ValueType::key_t::BOOLEAN: + return ani_kvstoreutils::BOOLEAN; + break; + case (int32_t)::ohos::data::distributedkvstore::ValueType::key_t::DOUBLE: + return ani_kvstoreutils::DOUBLE; + break; + case (int32_t)::ohos::data::distributedkvstore::ValueType::key_t::LONG: + return ani_kvstoreutils::LONG; + break; + default: { + ZLOGE("TaiheValueTypeToNative, unexpected taiheType type %{public}d", taiheType); + return ani_kvstoreutils::DOUBLE; + } + break; + } +} + +::ohos::data::distributedkvstore::ValueType NativeTypeToTaihe(int32_t nativeType) +{ + ::ohos::data::distributedkvstore::ValueType::key_t key = ::ohos::data::distributedkvstore::ValueType::key_t::DOUBLE; + switch (nativeType) { + case ani_kvstoreutils::STRING: + key = ::ohos::data::distributedkvstore::ValueType::key_t::STRING; + break; + case ani_kvstoreutils::BYTE_ARRAY: + key = ::ohos::data::distributedkvstore::ValueType::key_t::BYTE_ARRAY; + break; + case ani_kvstoreutils::BOOLEAN: + key = ::ohos::data::distributedkvstore::ValueType::key_t::BOOLEAN; + break; + case ani_kvstoreutils::DOUBLE: + key = ::ohos::data::distributedkvstore::ValueType::key_t::DOUBLE; + break; + case ani_kvstoreutils::LONG: + key = ::ohos::data::distributedkvstore::ValueType::key_t::LONG; + break; + default: { + ZLOGE("NativeTypeToTaihe, unexpected nativeType type %{public}d", nativeType); + key = ::ohos::data::distributedkvstore::ValueType::key_t::DOUBLE; + } + break; + } + return ::ohos::data::distributedkvstore::ValueType(key); +} + +} // namespace ani_kvstoreutils \ No newline at end of file diff --git a/frameworks/ets/taihe/kv_store/src/ani_observer_utils.cpp b/frameworks/ets/taihe/kv_store/src/ani_observer_utils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f98f8f4ef1dcbfe9b47189fcd599e9b4f96069cd --- /dev/null +++ b/frameworks/ets/taihe/kv_store/src/ani_observer_utils.cpp @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "AniObserverUtils" +#include "ani_observer_utils.h" +#include "ani_kvstore_utils.h" +#include +#include + +#include "log_print.h" + +using namespace ::ohos::data::distributedkvstore; +using namespace OHOS::DistributedKVStore; + +namespace ani_observerutils { + +std::shared_ptr JsBaseObserver::mainHandler_; +static std::once_flag g_handlerOnceFlag; + +JsBaseObserver::JsBaseObserver(VarCallbackType cb, ani_ref jsCallbackRef) + : jsCallback_(cb), jsCallbackRef_(jsCallbackRef) +{ +} + +bool JsBaseObserver::SendEventToMainThread(const std::function func) +{ + if (func == nullptr) { + return false; + } + std::call_once(g_handlerOnceFlag, [] { + auto runner = OHOS::AppExecFwk::EventRunner::GetMainEventRunner(); + if (runner) { + mainHandler_ = std::make_shared(runner); + } + }); + if (!mainHandler_) { + ZLOGE("Failed to initialize event handler"); + return false; + } + mainHandler_->PostTask(func, "", 0, OHOS::AppExecFwk::EventQueue::Priority::IMMEDIATE, {}); + return true; +} + +void JsBaseObserver::Release() +{ + ZLOGI("DataObserver::Release"); + std::lock_guard lock(mutex_); + taihe::env_guard guard; + if (auto *env = guard.get_env()) { + env->GlobalReference_Delete(jsCallbackRef_); + jsCallbackRef_ = nullptr; + } + jsCallback_ = std::monostate(); +} + +DataObserver::DataObserver(VarCallbackType cb, ani_ref jsCallbackRef) + : JsBaseObserver(cb, jsCallbackRef) +{ + ZLOGI("DataObserver"); +} + +DataObserver::~DataObserver() +{ + ZLOGI("~DataObserver"); +} + +void DataObserver::SetIsSchemaStore(bool isSchemaStore) +{ + isSchemaStore_ = isSchemaStore; +} + +void DataObserver::OnChange(const DistributedKv::ChangeNotification& info) +{ + auto sharedThis = shared_from_this(); + SendEventToMainThread([info, sharedThis] { + sharedThis->OnChangeInMainThread(info); + }); +} + +void DataObserver::OnChangeInMainThread(const DistributedKv::ChangeNotification& info) +{ + std::optional callbackTemp; + { + std::lock_guard lock(mutex_); + if (jsCallbackRef_ == nullptr || std::holds_alternative(jsCallback_)) { + return; + } + auto pTaiheCallback = std::get_if(&jsCallback_); + if (pTaiheCallback == nullptr) { + return; + } + callbackTemp = *pTaiheCallback; + } + auto jspara = ani_kvstoreutils::KvChangeNotificationToTaihe(info, isSchemaStore_); + if (callbackTemp.has_value()) { + callbackTemp.value()(jspara); + } +} + +void DataObserver::SyncCompleted(const std::map& results) +{ + auto sharedThis = shared_from_this(); + SendEventToMainThread([results, sharedThis] { + sharedThis->SyncCompletedInMainThread(results); + }); +} + +void DataObserver::SyncCompletedInMainThread(const std::map& results) +{ + ani_env *env = taihe::get_env(); + if (env == nullptr) { + return; + } + std::optional callbackTemp; + { + std::lock_guard lock(mutex_); + if (jsCallbackRef_ == nullptr || std::holds_alternative(jsCallback_)) { + return; + } + auto pTaiheCallback = std::get_if(&jsCallback_); + if (pTaiheCallback == nullptr) { + return; + } + callbackTemp = *pTaiheCallback; + } + auto jspara = ani_kvstoreutils::KvStatusMapToTaiheArray(env, results); + if (callbackTemp.has_value()) { + callbackTemp.value()(jspara); + } +} + +ManagerObserver::ManagerObserver(VarCallbackType cb, ani_ref jsCallbackRef) + : JsBaseObserver(cb, jsCallbackRef) +{ + ZLOGI("ManagerObserver"); +} + +ManagerObserver::~ManagerObserver() +{ + ZLOGI("~ManagerObserver"); +} + +void ManagerObserver::OnRemoteDied() +{ + auto sharedThis = shared_from_this(); + SendEventToMainThread([sharedThis] { + sharedThis->OnRemoteDiedInMainThread(); + }); +} + +void ManagerObserver::OnRemoteDiedInMainThread() +{ + std::optional callbackTemp; + { + std::lock_guard lock(mutex_); + if (jsCallbackRef_ == nullptr || std::holds_alternative(jsCallback_)) { + return; + } + auto pTaiheCallback = std::get_if(&jsCallback_); + if (pTaiheCallback == nullptr) { + return; + } + callbackTemp = *pTaiheCallback; + } + auto undefined = ::ohos::data::distributedkvstore::OneUndef::make_UNDEFINED(); + if (callbackTemp.has_value()) { + callbackTemp.value()(undefined); + } +} + +} // namespace ani_observerutils \ No newline at end of file diff --git a/frameworks/ets/taihe/kv_store/src/ani_utils.cpp b/frameworks/ets/taihe/kv_store/src/ani_utils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..54a6f18dbd8c0fdfe0fa54acc33ea003dfc581e9 --- /dev/null +++ b/frameworks/ets/taihe/kv_store/src/ani_utils.cpp @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "AniUtils" +#include "ani_utils.h" +#include "log_print.h" + +namespace ani_utils { +using namespace OHOS; +using namespace OHOS::DistributedKVStore; + +int32_t AniGetProperty(ani_env *env, ani_object ani_obj, const char *property, std::string &result, bool optional) +{ + if (env == nullptr || ani_obj == nullptr || property == nullptr) { + return ANI_INVALID_ARGS; + } + ani_object object = nullptr; + int32_t status = AniGetProperty(env, ani_obj, property, object, optional); + if (status == ANI_OK && object != nullptr) { + result = AniStringUtils::ToStd(env, reinterpret_cast(object)); + } + return status; +} + +int32_t AniGetProperty(ani_env *env, ani_object ani_obj, const char *property, bool &result, bool optional) +{ + if (env == nullptr || ani_obj == nullptr || property == nullptr) { + return ANI_INVALID_ARGS; + } + ani_boolean ani_field_value; + ani_status status = env->Object_GetPropertyByName_Boolean( + ani_obj, property, reinterpret_cast(&ani_field_value)); + if (status != ANI_OK) { + if (optional) { + status = ANI_OK; + } + return status; + } + result = (bool)ani_field_value; + return ANI_OK; +} + +int32_t AniGetProperty(ani_env *env, ani_object ani_obj, const char *property, int32_t &result, bool optional) +{ + if (env == nullptr || ani_obj == nullptr || property == nullptr) { + return ANI_INVALID_ARGS; + } + ani_int ani_field_value; + ani_status status = env->Object_GetPropertyByName_Int( + ani_obj, property, reinterpret_cast(&ani_field_value)); + if (status != ANI_OK) { + if (optional) { + status = ANI_OK; + } + return status; + } + result = (int32_t)ani_field_value; + return ANI_OK; +} + +int32_t AniGetProperty(ani_env *env, ani_object ani_obj, const char *property, uint32_t &result, bool optional) +{ + if (env == nullptr || ani_obj == nullptr || property == nullptr) { + return ANI_INVALID_ARGS; + } + ani_int ani_field_value; + ani_status status = env->Object_GetPropertyByName_Int( + ani_obj, property, reinterpret_cast(&ani_field_value)); + if (status != ANI_OK) { + if (optional) { + status = ANI_OK; + } + return status; + } + result = (uint32_t)ani_field_value; + return ANI_OK; +} + +int32_t AniGetProperty(ani_env *env, ani_object ani_obj, const char *property, ani_object &result, bool optional) +{ + if (env == nullptr || ani_obj == nullptr || property == nullptr) { + return ANI_INVALID_ARGS; + } + ani_status status = env->Object_GetPropertyByName_Ref(ani_obj, property, reinterpret_cast(&result)); + if (status != ANI_OK) { + if (optional) { + status = ANI_OK; + } + return status; + } + return ANI_OK; +} + +std::string AniStringUtils::ToStd(ani_env *env, ani_string ani_str) +{ + if (env == nullptr) { + return std::string(); + } + ani_size strSize = 0; + auto status = env->String_GetUTF8Size(ani_str, &strSize); + if (ANI_OK != status) { + ZLOGI("String_GetUTF8Size failed"); + return std::string(); + } + + std::vector buffer(strSize + 1); + char *utf8Buffer = buffer.data(); + + ani_size bytesWritten = 0; + status = env->String_GetUTF8(ani_str, utf8Buffer, strSize + 1, &bytesWritten); + if (ANI_OK != status) { + ZLOGI("String_GetUTF8Size failed"); + return std::string(); + } + + utf8Buffer[bytesWritten] = '\0'; + std::string content = std::string(utf8Buffer); + return content; +} + +ani_string AniStringUtils::ToAni(ani_env *env, const std::string& str) +{ + if (env == nullptr) { + return nullptr; + } + ani_string aniStr = nullptr; + if (ANI_OK != env->String_NewUTF8(str.data(), str.size(), &aniStr)) { + ZLOGI("Unsupported ANI_VERSION_1"); + return nullptr; + } + return aniStr; +} + +ani_status AniCreateInt(ani_env* env, int32_t value, ani_object& result) +{ + ani_status state; + ani_class intClass; + if ((state = env->FindClass("std.core.Int", &intClass)) != ANI_OK) { + ZLOGE("FindClass std/core/Int failed, %{public}d", state); + return state; + } + ani_method intClassCtor; + if ((state = env->Class_FindMethod(intClass, "", "i:", &intClassCtor)) != ANI_OK) { + ZLOGE("Class_FindMethod Int ctor failed, %{public}d", state); + return state; + } + ani_int aniValue = value; + if ((state = env->Object_New(intClass, intClassCtor, &result, aniValue)) != ANI_OK) { + ZLOGE("New Int object failed, %{public}d", state); + } + if (state != ANI_OK) { + result = nullptr; + } + return state; +} + +bool AniCreateTuple(ani_env* env, ani_ref item1, ani_ref item2, ani_tuple_value &tuple) +{ + if (env == nullptr) { + return false; + } + ani_class tupleCls {}; + ani_method tupleCtorMethod {}; + ani_object tupleObj {}; + if (ANI_OK != env->FindClass("std.core.Tuple2", &tupleCls)) { + ZLOGE("FindClass std.core.Tuple2 failed"); + return false; + } + if (ANI_OK != env->Class_FindMethod(tupleCls, "", nullptr, &tupleCtorMethod)) { + ZLOGE("Class_FindMethod ctor failed"); + return false; + } + if (ANI_OK != env->Object_New(tupleCls, tupleCtorMethod, &tupleObj, item1, item2)) { + ZLOGE("Object_New tupleCls failed"); + return false; + } + tuple = static_cast(tupleObj); + return true; +} + +bool AniIsInstanceOf(ani_env* aniEnv, ani_ref aniRef, const std::string& cls_name) +{ + if (aniEnv == nullptr || aniRef == nullptr) { + return false; + } + ani_boolean isNull = false; + ani_boolean isUndefined = false; + aniEnv->Reference_IsNull(aniRef, &isNull); + aniEnv->Reference_IsUndefined(aniRef, &isUndefined); + if (isNull || isUndefined) { + return false; + } + ani_class cls; + if (ANI_OK != aniEnv->FindClass(cls_name.c_str(), &cls) || cls == nullptr) { + return false; + } + ani_boolean ret; + ani_object aniObj = reinterpret_cast(aniRef); + if (ANI_OK != aniEnv->Object_InstanceOf(aniObj, cls, &ret)) { + return false; + } + return ret; +} + +} //namespace ani_utils \ No newline at end of file diff --git a/frameworks/ets/taihe/kv_store/src/ohos.data.distributedkvstore.impl.cpp b/frameworks/ets/taihe/kv_store/src/ohos.data.distributedkvstore.impl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4af1c016c729f9b80143a526efc17b3f004c37f7 --- /dev/null +++ b/frameworks/ets/taihe/kv_store/src/ohos.data.distributedkvstore.impl.cpp @@ -0,0 +1,2002 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "ohos.data.distributedkvstore.proj.hpp" +#include "ohos.data.distributedkvstore.impl.hpp" +#include "taihe/runtime.hpp" +#include "stdexcept" + +#include +#include + +#define LOG_TAG "AniKvstoreImpl" +#include "log_print.h" +#include "ani_ability_utils.h" +#include "ani_utils.h" +#include "ani_kvstore_utils.h" +#include "ani_error_utils.h" +#include "ani_observer_utils.h" +#include "types.h" +#include "distributed_kv_data_manager.h" +#include "datashare_abs_predicates.h" +#include "js_proxy.h" +#include "kv_utils.h" +#include "kvstore_datashare_bridge.h" +#include "store_errno.h" + +using namespace OHOS; +using namespace OHOS::DistributedKVStore; +using namespace ::ohos::data; +using TaiheOptions = distributedkvstore::Options; + +static constexpr int MAX_APP_ID_LEN = 256; +static constexpr int DEVICEID_WIDTH = 4; +static constexpr const char* DATA_CHANGE_EVENT = "dataChange"; +static constexpr const char* SYNC_COMPLETE_EVENT = "syncComplete"; + +static std::map valueTypeToString_ = { + { ani_kvstoreutils::STRING, std::string("STRING") }, + { ani_kvstoreutils::BYTE_ARRAY, std::string("BYTE_ARRAY") }, + { ani_kvstoreutils::BOOLEAN, std::string("BOOL") }, + { ani_kvstoreutils::DOUBLE, std::string("DOUBLE") }, + { ani_kvstoreutils::LONG, std::string("LONG") } +}; + +namespace { +class FieldNodeImpl { +public: + FieldNodeImpl() + : fieldName_(""), default_("") + { + } + + explicit FieldNodeImpl(::taihe::string_view name) + : fieldName_(""), default_("") + { + fieldName_ = std::string(name); + } + + int64_t GetInner() + { + return reinterpret_cast(this); + } + + std::string TypeToString(uint32_t type) + { + auto it = valueTypeToString_.find(type); + if (valueTypeToString_.find(type) != valueTypeToString_.end()) { + return it->second; + } else { + return std::string(); + } + } + + nlohmann::json GetValueForJson() + { + if (fields_.empty()) { + int32_t nativeType = ani_kvstoreutils::TaiheValueTypeToNative(GetType()); + std::string jsonDesc = TypeToString(nativeType) + (GetNullable() ? SPLIT : NOT_NULL) + DEFAULT; + if (nativeType == ani_kvstoreutils::STRING) { + jsonDesc += MARK + std::string(GetDefaultValue()) + MARK; + } else { + jsonDesc += std::string(GetDefaultValue()); + } + return jsonDesc; + } + + nlohmann::json jsFields; + for (auto fld : fields_) { + FieldNodeImpl* impl = reinterpret_cast(fld->GetInner()); + if (impl == nullptr) { + continue; + } + jsFields[std::string(impl->fieldName_)] = impl->GetValueForJson(); + } + return jsFields; + } + + bool AppendChild(distributedkvstore::weak::FieldNode child) + { + fields_.push_back(child); + return true; + } + + ::taihe::string GetDefaultValue() + { + return default_; + } + + void SetDefaultValue(::taihe::string_view para) + { + default_ = para; + } + + bool GetNullable() + { + return nullable_; + } + + void SetNullable(bool para) + { + nullable_ = para; + } + + int32_t GetType() + { + return valueType_; + } + + void SetType(int32_t para) + { + valueType_ = para; + } + +protected: + std::list fields_; + ::taihe::string fieldName_; + ::taihe::string default_; + int32_t valueType_ = static_cast(distributedkvstore::ValueType::key_t::STRING); + bool nullable_ = false; +}; + +class SchemaImpl { +public: + SchemaImpl() + { + } + + int64_t GetInner() + { + return reinterpret_cast(this); + } + + distributedkvstore::FieldNode GetRoot() + { + if (!root_.has_value()) { + root_ = taihe::make_holder(SCHEMA_DEFINE); + } + return root_.value(); + } + + void SetRoot(distributedkvstore::weak::FieldNode para) + { + root_ = para; + } + + ::taihe::array<::taihe::string> GetIndexes() + { + return indexes_; + } + + void SetIndexes(::taihe::array_view<::taihe::string> para) + { + indexes_ = para; + } + + int32_t GetMode() + { + return mode_; + } + + void SetMode(int32_t para) + { + mode_ = para; + } + + int32_t GetSkip() + { + return skip_; + } + + void SetSkip(int32_t para) + { + skip_ = para; + } + + static FieldNodeImpl* GetRootNodeImpl(distributedkvstore::Schema const& taiheSchema) + { + auto nativeSchemaPtr = reinterpret_cast(taiheSchema->GetInner()); + if (nativeSchemaPtr == nullptr) { + ZLOGE("DumpSchema, SchemaImpl nullptr"); + return nullptr; + } + auto rootNodeImpl = reinterpret_cast(nativeSchemaPtr->GetRoot()->GetInner()); + return rootNodeImpl; + } + + static std::string DumpSchema(distributedkvstore::Schema const& taiheSchema) + { + auto rootNodeImpl = GetRootNodeImpl(taiheSchema); + if (rootNodeImpl == nullptr) { + ZLOGE("DumpSchema, rootNodeImpl nullptr"); + return ""; + } + nlohmann::json jsIndexes = nlohmann::json::array(); + auto indexs = taiheSchema->GetIndexes(); + for (auto idx : indexs) { + jsIndexes.push_back(idx); + } + nlohmann::json js = { + { SCHEMA_VERSION, DEFAULT_SCHEMA_VERSION }, + { SCHEMA_MODE, (taiheSchema->GetMode() == SCHEMA_MODE_STRICT) ? SCHEMA_STRICT : SCHEMA_COMPATIBLE }, + { SCHEMA_DEFINE, rootNodeImpl->GetValueForJson() }, + { SCHEMA_INDEXES, jsIndexes }, + { SCHEMA_SKIPSIZE, taiheSchema->GetSkip() }, + }; + return js.dump(); + } + +protected: + std::optional root_; + ::taihe::array<::taihe::string> indexes_ = {}; + int32_t mode_ = 0; + int32_t skip_ = 0; +}; + +class ResultSetProxy final : public OHOS::JSProxy::JSCreator { +public: + ResultSetProxy() = default; + explicit ResultSetProxy(std::shared_ptr resultSet) + { + resultSet_ = resultSet; + } + + ResultSetProxy operator=(std::shared_ptr resultSet) + { + if (resultSet_ == resultSet) { + return *this; + } + resultSet_ = resultSet; + return *this; + } + + std::shared_ptr Create() override + { + if (resultSet_ == nullptr) { + ZLOGE("resultSet_ == nullptr"); + return nullptr; + } + return std::make_shared(resultSet_); + } + +protected: + std::shared_ptr resultSet_; +}; + +class KVStoreResultSetImpl { +public: + KVStoreResultSetImpl() + { + } + + explicit KVStoreResultSetImpl(std::shared_ptr kvResultSet, + bool isSchema) + { + nativeResultSet_ = kvResultSet; + proxy_ = std::make_shared(kvResultSet); + hasSchema_ = isSchema; + } + + int64_t GetInner() + { + return reinterpret_cast(this); + } + + int64_t GetProxy() + { + return reinterpret_cast(proxy_.get()); + } + + int32_t GetCount() + { + ANI_ASSERT(nativeResultSet_ != nullptr, "kvResultSet is nullptr!", 0); + return nativeResultSet_->GetCount(); + } + + int32_t GetPosition() + { + ANI_ASSERT(nativeResultSet_ != nullptr, "kvResultSet is nullptr!", 0); + return nativeResultSet_->GetPosition(); + } + + bool MoveToFirst() + { + ANI_ASSERT(nativeResultSet_ != nullptr, "kvResultSet is nullptr!", false); + return nativeResultSet_->MoveToFirst(); + } + + bool MoveToLast() + { + ANI_ASSERT(nativeResultSet_ != nullptr, "kvResultSet is nullptr!", false); + return nativeResultSet_->MoveToLast(); + } + + bool MoveToNext() + { + ANI_ASSERT(nativeResultSet_ != nullptr, "kvResultSet is nullptr!", false); + return nativeResultSet_->MoveToNext(); + } + + bool MoveToPrevious() + { + ANI_ASSERT(nativeResultSet_ != nullptr, "kvResultSet is nullptr!", false); + return nativeResultSet_->MoveToPrevious(); + } + + bool Move(int32_t offset) + { + ANI_ASSERT(nativeResultSet_ != nullptr, "kvResultSet is nullptr!", false); + return nativeResultSet_->Move(offset); + } + + bool MoveToPosition(int32_t position) + { + ANI_ASSERT(nativeResultSet_ != nullptr, "kvResultSet is nullptr!", false); + return nativeResultSet_->MoveToPosition(position); + } + + bool IsFirst() + { + ANI_ASSERT(nativeResultSet_ != nullptr, "kvResultSet is nullptr!", false); + return nativeResultSet_->IsFirst(); + } + + bool IsLast() + { + ANI_ASSERT(nativeResultSet_ != nullptr, "kvResultSet is nullptr!", false); + return nativeResultSet_->IsLast(); + } + + bool IsBeforeFirst() + { + ANI_ASSERT(nativeResultSet_ != nullptr, "kvResultSet is nullptr!", false); + return nativeResultSet_->IsBeforeFirst(); + } + + bool IsAfterLast() + { + ANI_ASSERT(nativeResultSet_ != nullptr, "kvResultSet is nullptr!", false); + return nativeResultSet_->IsAfterLast(); + } + + distributedkvstore::Entry GetEntry() + { + ANI_ASSERT(nativeResultSet_ != nullptr, "kvResultSet is nullptr!", ani_kvstoreutils::GetEmptyTaiheEntry()); + DistributedKv::Entry kventry; + Status status = nativeResultSet_->GetEntry(kventry); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + return ani_kvstoreutils::GetEmptyTaiheEntry(); + } + return ani_kvstoreutils::KvEntryToTaihe(kventry, hasSchema_); + } + + std::shared_ptr GetNativePtr() + { + return nativeResultSet_; + } + +protected: + std::shared_ptr nativeResultSet_; + std::shared_ptr proxy_; + bool hasSchema_ = false; +}; + +class QueryImpl { +public: + QueryImpl() + { + nativeQueryPtr_ = std::make_shared(); + } + + int64_t GetInner() + { + return reinterpret_cast(this); + } + + distributedkvstore::Query Reset(distributedkvstore::weak::Query thiz) + { + nativeQueryPtr_->Reset(); + return thiz; + } + + distributedkvstore::Query EqualTo(distributedkvstore::weak::Query thiz, + ::taihe::string_view field, distributedkvstore::LongDoubleStringBool const& value) + { + std::string stdField(field); + if (value.get_tag() == distributedkvstore::LongDoubleStringBool::tag_t::F64) { + nativeQueryPtr_->EqualTo(stdField, value.get_F64_ref()); + } else if (value.get_tag() == distributedkvstore::LongDoubleStringBool::tag_t::INT64) { + nativeQueryPtr_->EqualTo(stdField, value.get_INT64_ref()); + } else if (value.get_tag() == distributedkvstore::LongDoubleStringBool::tag_t::STRING) { + nativeQueryPtr_->EqualTo(stdField, std::string(value.get_STRING_ref())); + } else if (value.get_tag() == distributedkvstore::LongDoubleStringBool::tag_t::BOOL) { + nativeQueryPtr_->EqualTo(stdField, value.get_BOOL_ref()); + } + return thiz; + } + + distributedkvstore::Query NotEqualTo(distributedkvstore::weak::Query thiz, + ::taihe::string_view field, distributedkvstore::LongDoubleStringBool const& value) + { + std::string stdField(field); + if (value.get_tag() == distributedkvstore::LongDoubleStringBool::tag_t::F64) { + nativeQueryPtr_->NotEqualTo(stdField, value.get_F64_ref()); + } else if (value.get_tag() == distributedkvstore::LongDoubleStringBool::tag_t::INT64) { + nativeQueryPtr_->NotEqualTo(stdField, value.get_INT64_ref()); + } else if (value.get_tag() == distributedkvstore::LongDoubleStringBool::tag_t::STRING) { + nativeQueryPtr_->NotEqualTo(stdField, std::string(value.get_STRING_ref())); + } else if (value.get_tag() == distributedkvstore::LongDoubleStringBool::tag_t::BOOL) { + nativeQueryPtr_->NotEqualTo(stdField, value.get_BOOL_ref()); + } + return thiz; + } + + distributedkvstore::Query GreaterThan(distributedkvstore::weak::Query thiz, + ::taihe::string_view field, distributedkvstore::LongDoubleStringBool const& value) + { + std::string stdField(field); + if (value.get_tag() == distributedkvstore::LongDoubleStringBool::tag_t::F64) { + nativeQueryPtr_->GreaterThan(stdField, value.get_F64_ref()); + } else if (value.get_tag() == distributedkvstore::LongDoubleStringBool::tag_t::INT64) { + nativeQueryPtr_->GreaterThan(stdField, value.get_INT64_ref()); + } else if (value.get_tag() == distributedkvstore::LongDoubleStringBool::tag_t::STRING) { + nativeQueryPtr_->GreaterThan(stdField, std::string(value.get_STRING_ref())); + } else if (value.get_tag() == distributedkvstore::LongDoubleStringBool::tag_t::BOOL) { + nativeQueryPtr_->GreaterThan(stdField, value.get_BOOL_ref()); + } + return thiz; + } + + distributedkvstore::Query LessThan(distributedkvstore::weak::Query thiz, + ::taihe::string_view field, distributedkvstore::LongDoubleString const& value) + { + std::string stdField(field); + if (value.get_tag() == distributedkvstore::LongDoubleString::tag_t::F64) { + nativeQueryPtr_->LessThan(stdField, value.get_F64_ref()); + } else if (value.get_tag() == distributedkvstore::LongDoubleString::tag_t::INT64) { + nativeQueryPtr_->LessThan(stdField, value.get_INT64_ref()); + } else if (value.get_tag() == distributedkvstore::LongDoubleString::tag_t::STRING) { + nativeQueryPtr_->LessThan(stdField, std::string(value.get_STRING_ref())); + } + return thiz; + } + + distributedkvstore::Query GreaterThanOrEqualTo(distributedkvstore::weak::Query thiz, + ::taihe::string_view field, distributedkvstore::LongDoubleString const& value) + { + std::string stdField(field); + if (value.get_tag() == distributedkvstore::LongDoubleString::tag_t::F64) { + nativeQueryPtr_->GreaterThanOrEqualTo(stdField, value.get_F64_ref()); + } else if (value.get_tag() == distributedkvstore::LongDoubleString::tag_t::INT64) { + nativeQueryPtr_->GreaterThanOrEqualTo(stdField, value.get_INT64_ref()); + } else if (value.get_tag() == distributedkvstore::LongDoubleString::tag_t::STRING) { + nativeQueryPtr_->GreaterThanOrEqualTo(stdField, std::string(value.get_STRING_ref())); + } + return thiz; + } + + distributedkvstore::Query LessThanOrEqualTo(distributedkvstore::weak::Query thiz, + ::taihe::string_view field, distributedkvstore::LongDoubleString const& value) + { + std::string stdField(field); + if (value.get_tag() == distributedkvstore::LongDoubleString::tag_t::F64) { + nativeQueryPtr_->LessThanOrEqualTo(stdField, value.get_F64_ref()); + } else if (value.get_tag() == distributedkvstore::LongDoubleString::tag_t::INT64) { + nativeQueryPtr_->LessThanOrEqualTo(stdField, value.get_INT64_ref()); + } else if (value.get_tag() == distributedkvstore::LongDoubleString::tag_t::STRING) { + nativeQueryPtr_->LessThanOrEqualTo(stdField, std::string(value.get_STRING_ref())); + } + return thiz; + } + + distributedkvstore::Query IsNull(distributedkvstore::weak::Query thiz, + ::taihe::string_view field) + { + std::string stdField(field); + nativeQueryPtr_->IsNull(stdField); + return thiz; + } + + distributedkvstore::Query InNumber(distributedkvstore::weak::Query thiz, + ::taihe::string_view field, ::taihe::array_view valueList) + { + if (valueList.size() == 0) { + return thiz; + } + std::string stdField(field); + auto &tempItem = valueList[0]; + if (tempItem.get_tag() == distributedkvstore::LongDouble::tag_t::F64) { + std::vector doubleVector(valueList.size()); + std::transform(valueList.begin(), valueList.end(), doubleVector.begin(), + [](distributedkvstore::LongDouble c) { + return c.get_F64_ref(); + }); + nativeQueryPtr_->In(stdField, doubleVector); + } else if (tempItem.get_tag() == distributedkvstore::LongDouble::tag_t::INT64) { + std::vector longVector(valueList.size()); + std::transform(valueList.begin(), valueList.end(), longVector.begin(), + [](distributedkvstore::LongDouble c) { + return c.get_INT64_ref(); + }); + nativeQueryPtr_->In(stdField, longVector); + } + return thiz; + } + + distributedkvstore::Query InString(distributedkvstore::weak::Query thiz, + ::taihe::string_view field, ::taihe::array_view<::taihe::string> valueList) + { + auto stdArray = ani_kvstoreutils::StringArrayToNative(valueList); + nativeQueryPtr_->In(std::string(field), stdArray); + return thiz; + } + + distributedkvstore::Query NotInNumber(distributedkvstore::weak::Query thiz, + ::taihe::string_view field, ::taihe::array_view valueList) + { + if (valueList.size() == 0) { + return thiz; + } + std::string stdField(field); + auto &tempItem = valueList[0]; + if (tempItem.get_tag() == distributedkvstore::LongDouble::tag_t::F64) { + std::vector doubleVector(valueList.size()); + std::transform(valueList.begin(), valueList.end(), doubleVector.begin(), + [](distributedkvstore::LongDouble c) { + return c.get_F64_ref(); + }); + nativeQueryPtr_->NotIn(stdField, doubleVector); + } else if (tempItem.get_tag() == distributedkvstore::LongDouble::tag_t::INT64) { + std::vector longVector(valueList.size()); + std::transform(valueList.begin(), valueList.end(), longVector.begin(), + [](distributedkvstore::LongDouble c) { + return c.get_INT64_ref(); + }); + nativeQueryPtr_->NotIn(stdField, longVector); + } + return thiz; + } + + distributedkvstore::Query NotInString(distributedkvstore::weak::Query thiz, + ::taihe::string_view field, ::taihe::array_view<::taihe::string> valueList) + { + auto stdArray = ani_kvstoreutils::StringArrayToNative(valueList); + nativeQueryPtr_->NotIn(std::string(field), stdArray); + return thiz; + } + + distributedkvstore::Query Like(distributedkvstore::weak::Query thiz, + ::taihe::string_view field, ::taihe::string_view value) + { + nativeQueryPtr_->Like(std::string(field), std::string(value)); + return thiz; + } + + distributedkvstore::Query Unlike(distributedkvstore::weak::Query thiz, + ::taihe::string_view field, ::taihe::string_view value) + { + nativeQueryPtr_->Unlike(std::string(field), std::string(value)); + return thiz; + } + + distributedkvstore::Query And(distributedkvstore::weak::Query thiz) + { + nativeQueryPtr_->And(); + return thiz; + } + + distributedkvstore::Query Or(distributedkvstore::weak::Query thiz) + { + nativeQueryPtr_->Or(); + return thiz; + } + + distributedkvstore::Query OrderByAsc(distributedkvstore::weak::Query thiz, + ::taihe::string_view field) + { + nativeQueryPtr_->OrderByAsc(std::string(field)); + return thiz; + } + + distributedkvstore::Query OrderByDesc(distributedkvstore::weak::Query thiz, + ::taihe::string_view field) + { + nativeQueryPtr_->OrderByDesc(std::string(field)); + return thiz; + } + + distributedkvstore::Query Limit(distributedkvstore::weak::Query thiz, + int32_t total, int32_t offset) + { + nativeQueryPtr_->Limit(total, offset); + return thiz; + } + + distributedkvstore::Query IsNotNull(distributedkvstore::weak::Query thiz, + ::taihe::string_view field) + { + nativeQueryPtr_->IsNotNull(std::string(field)); + return thiz; + } + + distributedkvstore::Query BeginGroup(distributedkvstore::weak::Query thiz) + { + nativeQueryPtr_->BeginGroup(); + return thiz; + } + + distributedkvstore::Query EndGroup(distributedkvstore::weak::Query thiz) + { + nativeQueryPtr_->EndGroup(); + return thiz; + } + + distributedkvstore::Query PrefixKey(distributedkvstore::weak::Query thiz, + ::taihe::string_view prefix) + { + nativeQueryPtr_->KeyPrefix(std::string(prefix)); + return thiz; + } + + distributedkvstore::Query SetSuggestIndex(distributedkvstore::weak::Query thiz, + ::taihe::string_view index) + { + nativeQueryPtr_->SetSuggestIndex(std::string(index)); + return thiz; + } + + distributedkvstore::Query DeviceId(distributedkvstore::weak::Query thiz, + ::taihe::string_view deviceId) + { + nativeQueryPtr_->DeviceId(std::string(deviceId)); + return thiz; + } + + ::taihe::string GetSqlLike() + { + auto stdstr = nativeQueryPtr_->ToString(); + return ::taihe::string(stdstr); + } + + std::shared_ptr GetNativePtr() + { + return nativeQueryPtr_; + } + +protected: + std::shared_ptr nativeQueryPtr_; +}; + +class SingleKVStoreImpl { +public: + SingleKVStoreImpl() + { + ZLOGE("SingleKVStoreImpl default constructor"); + } + + explicit SingleKVStoreImpl(std::shared_ptr kvStore) + { + ZLOGI("SingleKVStoreImpl constructor"); + nativeStore_ = kvStore; + } + ~SingleKVStoreImpl() + { + ZLOGI("SingleKVStoreImpl ~"); + UnRegisterAll(); + } + + virtual int64_t GetInner() + { + return reinterpret_cast(this); + } + + bool IsSystemApp() + { + return contextParam_.isSystemApp; + } + + bool IsSchemaStore() const + { + return isSchemaStore_; + } + + void SetSchemaInfo(bool isSchemaStore) + { + isSchemaStore_ = isSchemaStore; + } + + void SetContextParam(ContextParam const& param) + { + contextParam_ = param; + } + + void PutSync(::taihe::string_view key, distributedkvstore::ValueUnion const& value) + { + if (nativeStore_ == nullptr) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return; + } + ani_kvstoreutils::ValueVariant paramVariant; + ani_kvstoreutils::TaiheValueUnionToNativeVariant(value, paramVariant); + std::string stdkey(key); + DistributedKv::Key kvkey(stdkey); + bool isSchemaStore = IsSchemaStore(); + if (isSchemaStore && !std::holds_alternative(paramVariant)) { + ZLOGE("isSchemaStore, and value is not string"); + ThrowAniError(Status::INVALID_ARGUMENT, ""); + return; + } + DistributedKv::Value nativeValue = isSchemaStore ? DistributedKv::Blob(std::get(paramVariant)) + : ani_kvstoreutils::VariantValue2Blob(paramVariant); + Status status = nativeStore_->Put(kvkey, nativeValue); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + } + } + + void PutBatchSync(::taihe::array_view entries) + { + if (nativeStore_ == nullptr) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return; + } + bool isSchemaStore = IsSchemaStore(); + std::vector kvEntris; + if (false == ani_kvstoreutils::EntryArrayToNative(entries, kvEntris, isSchemaStore)) { + ZLOGE("isSchemaStore, and value is not string"); + ThrowAniError(Status::INVALID_ARGUMENT, ""); + return; + } + Status status = nativeStore_->PutBatch(kvEntris); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + } + } + + void PutValuesBucketsSync(::taihe::array_view< + ::taihe::map<::taihe::string, distributedkvstore::DataShareValueUnion>> value) + { + if (!IsSystemApp()) { + ThrowAniError(Status::PERMISSION_DENIED, ""); + return; + } + if (nativeStore_ == nullptr) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return; + } + bool isSchemaStore = IsSchemaStore(); + std::vector kvEntris; + for (auto& arrayItem : value) { + OHOS::DataShare::DataShareValuesBucket valuesBucket; + for (auto& [key, mapvalue] : arrayItem) { + std::string stdkey(key); + ani_kvstoreutils::DataShareValueVariant variant; + ani_kvstoreutils::TaiheDataShareValueToVariant(mapvalue, variant); + valuesBucket.valuesMap[stdkey] = variant; + } + auto entry = DistributedKv::KvUtils::ToEntry(valuesBucket); + entry.key = std::vector(entry.key.Data().begin(), entry.key.Data().end()); + if (isSchemaStore) { + entry.value = std::vector(entry.value.Data().begin() + 1, entry.value.Data().end()); + } + kvEntris.emplace_back(entry); + } + Status status = nativeStore_->PutBatch(kvEntris); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + } + } + + void DeleteSync(::taihe::string_view key) + { + if (nativeStore_ == nullptr) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return; + } + std::string stdkey(key); + DistributedKv::Key kvkey(stdkey); + Status status = nativeStore_->Delete(kvkey); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + } + } + + void DeleteByPredicatesSync(uintptr_t predicates) + { + if (!IsSystemApp()) { + ThrowAniError(Status::PERMISSION_DENIED, ""); + return; + } + if (nativeStore_ == nullptr) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return; + } + ani_env *env = taihe::get_env(); + ani_object object = reinterpret_cast(predicates); + OHOS::DataShare::DataShareAbsPredicates *holder = + ani_utils::AniObjectUtils::Unwrap(env, object); + if (holder == nullptr) { + ZLOGE("DeleteByPredicatesSync, holder is nullptr"); + return ; + } + std::vector kvkeys; + Status status = OHOS::DistributedKv::KvUtils::GetKeys(*holder, kvkeys); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + return; + } + status = nativeStore_->DeleteBatch(kvkeys); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + } + } + + void DeleteBatchSync(::taihe::array_view<::taihe::string> keys) + { + if (nativeStore_ == nullptr) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return; + } + std::vector kvKeys(keys.size()); + std::transform(keys.begin(), keys.end(), kvKeys.begin(), [](::taihe::string c) { + std::string stdkey(c); + DistributedKv::Key kvkey(stdkey); + return kvkey; + }); + Status status = nativeStore_->DeleteBatch(kvKeys); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + } + } + + void RemoveDeviceDataSync(::taihe::string_view deviceId) + { + if (nativeStore_ == nullptr) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return; + } + std::string stdDeviceId(deviceId); + if (stdDeviceId.empty()) { + ThrowAniError(Status::INVALID_ARGUMENT, "Parameter error:deviceId empty"); + return; + } + Status status = nativeStore_->RemoveDeviceData(stdDeviceId); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + } + } + + distributedkvstore::ValueUnion GetSync(::taihe::string_view key) + { + auto emptyResult = distributedkvstore::ValueUnion::make_STRING(std::string("")); + if (nativeStore_ == nullptr) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return emptyResult; + } + std::string stdkey(key); + if (stdkey.empty()) { + ThrowAniError(Status::INVALID_ARGUMENT, "Parameter error:params key must be string and not allow empty"); + return emptyResult; + } + bool isSchemaStore = IsSchemaStore(); + OHOS::DistributedKv::Key kvkey(stdkey); + OHOS::DistributedKv::Value kvblob; + Status status = nativeStore_->Get(kvkey, kvblob); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + return emptyResult; + } + if (isSchemaStore) { + return distributedkvstore::ValueUnion::make_STRING(kvblob.ToString()); + } else { + uint8_t resultType = 0; + return ani_kvstoreutils::Blob2TaiheValue(kvblob, resultType); + } + } + + ::taihe::array GetEntriesSync(::taihe::string_view keyPrefix) + { + if (keyPrefix.empty()) { + ThrowAniError(Status::INVALID_ARGUMENT, ""); + return {}; + } + if (nativeStore_ == nullptr) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return {}; + } + bool isSchemaStore = IsSchemaStore(); + std::vector kventries; + Status status = nativeStore_->GetEntries(std::string(keyPrefix), kventries); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + return {}; + } + return ani_kvstoreutils::KvEntryArrayToTaihe(kventries, isSchemaStore); + } + + ::taihe::array GetEntriesByQuerySync( + distributedkvstore::weak::Query query) + { + if (nativeStore_ == nullptr) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return {}; + } + bool isSchemaStore = IsSchemaStore(); + std::vector kventries; + auto queryImpl = reinterpret_cast(query->GetInner()); + auto nativeQueryPtr = queryImpl->GetNativePtr(); + Status status = nativeStore_->GetEntries(*nativeQueryPtr, kventries); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + return {}; + } + return ani_kvstoreutils::KvEntryArrayToTaihe(kventries, isSchemaStore); + } + + distributedkvstore::KVStoreResultSet GetResultSetSync(::taihe::string_view keyPrefix) + { + if (keyPrefix.empty()) { + ThrowAniError(Status::INVALID_ARGUMENT, ""); + return taihe::make_holder(); + } + if (nativeStore_ == nullptr) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return taihe::make_holder(); + } + std::shared_ptr kvResultSet; + Status status = nativeStore_->GetResultSet(std::string(keyPrefix), kvResultSet); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + return taihe::make_holder(); + } + return taihe::make_holder( + kvResultSet, isSchemaStore_); + } + + distributedkvstore::KVStoreResultSet GetResultSetByQuerySync( + distributedkvstore::weak::Query query) + { + if (nativeStore_ == nullptr) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return taihe::make_holder(); + } + auto queryImpl = reinterpret_cast(query->GetInner()); + auto nativeQueryPtr = queryImpl->GetNativePtr(); + std::shared_ptr kvResultSet; + Status status = nativeStore_->GetResultSet(*nativeQueryPtr, kvResultSet); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + return taihe::make_holder(); + } + return taihe::make_holder( + kvResultSet, isSchemaStore_); + } + + distributedkvstore::KVStoreResultSet GetResultSetByPredicatesSync(uintptr_t predicates) + { + if (!IsSystemApp()) { + ThrowAniError(Status::PERMISSION_DENIED, ""); + return taihe::make_holder(); + } + if (nativeStore_ == nullptr) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return taihe::make_holder(); + } + ani_env *env = taihe::get_env(); + ani_object object = reinterpret_cast(predicates); + OHOS::DataShare::DataShareAbsPredicates *holder = + ani_utils::AniObjectUtils::Unwrap(env, object); + if (holder == nullptr) { + ZLOGE("GetResultSetByPredicatesSync, holder is nullptr"); + return taihe::make_holder(); + } + DistributedKv::DataQuery kvquery; + Status status = OHOS::DistributedKv::KvUtils::ToQuery(*holder, kvquery); + if (status != Status::SUCCESS) { + ThrowAniError(Status::INVALID_ARGUMENT, ""); + return taihe::make_holder(); + } + std::shared_ptr kvResultSet; + status = nativeStore_->GetResultSet(kvquery, kvResultSet); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + return taihe::make_holder(); + } + return taihe::make_holder( + kvResultSet, isSchemaStore_); + } + + void CloseResultSetSync(distributedkvstore::weak::KVStoreResultSet resultSet) + { + if (nativeStore_ == nullptr) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return; + } + auto resultSetImpl = reinterpret_cast(resultSet->GetInner()); + auto nativeResultSetPtr = resultSetImpl->GetNativePtr(); + Status status = nativeStore_->CloseResultSet(nativeResultSetPtr); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + } + } + + int32_t GetResultSizeSync(distributedkvstore::weak::Query query) + { + if (nativeStore_ == nullptr) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return 0; + } + auto queryImpl = reinterpret_cast(query->GetInner()); + auto nativeQueryPtr = queryImpl->GetNativePtr(); + int resultSize = 0; + Status status = nativeStore_->GetCount(*nativeQueryPtr, resultSize); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + } + return resultSize; + } + + void BackupSync(::taihe::string_view file) + { + if (nativeStore_ == nullptr) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return; + } + Status status = nativeStore_->Backup(std::string(file), contextParam_.baseDir); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + } + } + + void RestoreSync(::taihe::string_view file) + { + if (nativeStore_ == nullptr) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return; + } + Status status = nativeStore_->Restore(std::string(file), contextParam_.baseDir); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + } + } + + ::taihe::array DeleteBackupSync(::taihe::array_view<::taihe::string> files) + { + ani_env *env = taihe::get_env(); + if (env == nullptr) { + return {}; + } + if (nativeStore_ == nullptr) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return {}; + } + std::vector stdfiles = ani_kvstoreutils::StringArrayToNative(files); + std::map results; + Status status = nativeStore_->DeleteBackup(stdfiles, contextParam_.baseDir, results); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + return {}; + } + return ani_kvstoreutils::KvStatusMapToTaiheArray(env, results); + } + + void StartTransactionSync() + { + if (nativeStore_ == nullptr) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return; + } + Status status = nativeStore_->StartTransaction(); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + } + } + + void CommitSync() + { + if (nativeStore_ == nullptr) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return; + } + Status status = nativeStore_->Commit(); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + } + } + + void RollbackSync() + { + if (nativeStore_ == nullptr) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return; + } + Status status = nativeStore_->Rollback(); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + } + } + + void EnableSyncSync(bool enabled) + { + if (nativeStore_ == nullptr) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return; + } + Status status = nativeStore_->SetCapabilityEnabled(enabled); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + } + } + + void SetSyncRangeSync(::taihe::array_view<::taihe::string> localLabels, + ::taihe::array_view<::taihe::string> remoteSupportLabels) + { + if (nativeStore_ == nullptr) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return; + } + std::vector stdLocalLabels = ani_kvstoreutils::StringArrayToNative(localLabels); + std::vector stdRemoteSupportLabels = ani_kvstoreutils::StringArrayToNative(remoteSupportLabels); + Status status = nativeStore_->SetCapabilityRange(stdLocalLabels, stdRemoteSupportLabels); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + } + } + + void SetSyncParamSync(int32_t defaultAllowedDelayMs) + { + if (nativeStore_ == nullptr) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return; + } + DistributedKv::KvSyncParam syncParam { defaultAllowedDelayMs }; + Status status = nativeStore_->SetSyncParam(syncParam); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + } + } + + void Sync(::taihe::array_view<::taihe::string> deviceIds, distributedkvstore::SyncMode mode, + ::taihe::optional_view delayMs) + { + if (nativeStore_ == nullptr) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return; + } + std::vector stdDeviceIds = ani_kvstoreutils::StringArrayToNative(deviceIds); + DistributedKv::SyncMode kvmode = static_cast(mode.get_value()); + uint32_t kvAllowedDelayMs = 0; + if (delayMs.has_value()) { + kvAllowedDelayMs = delayMs.value(); + } + Status status = nativeStore_->Sync(stdDeviceIds, kvmode, kvAllowedDelayMs); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + } + } + + void SyncByQuery(::taihe::array_view<::taihe::string> deviceIds, + distributedkvstore::weak::Query query, + distributedkvstore::SyncMode mode, ::taihe::optional_view delayMs) + { + if (nativeStore_ == nullptr) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return; + } + auto queryImpl = reinterpret_cast(query->GetInner()); + auto nativeQueryPtr = queryImpl->GetNativePtr(); + std::vector stdDeviceIds = ani_kvstoreutils::StringArrayToNative(deviceIds); + DistributedKv::SyncMode kvmode = static_cast(mode.get_value()); + uint32_t kvAllowedDelayMs = 0; + if (delayMs.has_value()) { + kvAllowedDelayMs = delayMs.value(); + } + Status status = nativeStore_->Sync(stdDeviceIds, kvmode, *nativeQueryPtr, + nullptr, kvAllowedDelayMs); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + } + } + + void OnDataChange(distributedkvstore::SubscribeType type, + ::taihe::callback_view f, uintptr_t opq) + { + ani_env *env = taihe::get_env(); + if (env == nullptr) { + return; + } + if (!ani_utils::AniIsInstanceOf(env, reinterpret_cast(opq), "std.core.Object")) { + ThrowAniError(Status::INVALID_ARGUMENT, ""); + return; + } + if (nativeStore_ == nullptr) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return; + } + auto kvsubscribeType = ani_kvstoreutils::SubscribeTypeToNative(type); + ani_observerutils::VarCallbackType varcb = f; + RegisterListener(DATA_CHANGE_EVENT, kvsubscribeType, varcb, opq); + } + + void OffDataChange(::taihe::optional_view opq) + { + ani_env *env = taihe::get_env(); + if (env == nullptr) { + return; + } + if (opq.has_value() && + !ani_utils::AniIsInstanceOf(env, reinterpret_cast(opq.value()), "std.core.Object")) { + ThrowAniError(Status::INVALID_ARGUMENT, ""); + return; + } + if (nativeStore_ == nullptr) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return; + } + bool isUpdated = false; + UnregisterListener(DATA_CHANGE_EVENT, opq, isUpdated); + } + + void OnSyncComplete(::taihe::callback_view info)> f, uintptr_t opq) + { + ani_env *env = taihe::get_env(); + if (env == nullptr) { + return; + } + if (!ani_utils::AniIsInstanceOf(env, reinterpret_cast(opq), "std.core.Object")) { + ThrowAniError(Status::INVALID_ARGUMENT, ""); + return; + } + if (nativeStore_ == nullptr) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return; + } + ani_observerutils::VarCallbackType varcb = f; + RegisterListener(SYNC_COMPLETE_EVENT, DistributedKv::SubscribeType::SUBSCRIBE_TYPE_ALL, varcb, opq); + } + + void OffSyncComplete(::taihe::optional_view opq) + { + ani_env *env = taihe::get_env(); + if (env == nullptr) { + return; + } + if (opq.has_value() && + !ani_utils::AniIsInstanceOf(env, reinterpret_cast(opq.value()), "std.core.Object")) { + ThrowAniError(Status::INVALID_ARGUMENT, ""); + return; + } + if (nativeStore_ == nullptr) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return; + } + bool isUpdated = false; + UnregisterListener(SYNC_COMPLETE_EVENT, opq, isUpdated); + } + + distributedkvstore::SecurityLevel GetSecurityLevelSync() + { + if (nativeStore_ == nullptr) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return distributedkvstore::SecurityLevel::from_value(-1); + } + DistributedKv::SecurityLevel secLevel; + Status status = nativeStore_->GetSecurityLevel(secLevel); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + return distributedkvstore::SecurityLevel::from_value(-1); + } + int32_t jslevel = -1; + bool result = ani_kvstoreutils::SecurityLevelToTaihe(secLevel, jslevel); + if (!result) { + ThrowAniError(Status::ILLEGAL_STATE, ""); + return distributedkvstore::SecurityLevel::from_value(-1); + } + return distributedkvstore::SecurityLevel::from_value(jslevel); + } + +protected: + void RegisterListener(std::string const& event, DistributedKv::SubscribeType type, + ani_observerutils::VarCallbackType &cb, uintptr_t opq) + { + if (nativeStore_ == nullptr) { + ZLOGW("UnRegisterObserver, nativeStore_ is nullptr"); + return; + } + std::lock_guard lock(cbMapMutex_); + auto &cbVec = jsCbMap_[event]; + ani_object callbackObj = reinterpret_cast(opq); + ani_ref callbackRef = CreateCallbackRefIfNotDuplicate(cbVec, callbackObj); + if (callbackRef == nullptr) { + ZLOGE("Failed to register %{public}s", event.c_str()); + return; + } + Status status = Status::SUCCESS; + if (event == DATA_CHANGE_EVENT) { + status = RegisterDataChangeObserver(type, cb, callbackRef); + } else if (event == SYNC_COMPLETE_EVENT) { + status = RegisterSyncCompleteObserver(cb, callbackRef); + } + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + return; + } + ZLOGI("RegisterListener success type: %{public}s", event.c_str()); + } + + void UnregisterListener(std::string const& event, ::taihe::optional_view opq, bool &isUpdateFlag) + { + if (nativeStore_ == nullptr) { + ZLOGW("UnRegisterObserver, nativeStore_ is nullptr"); + return; + } + std::lock_guard lock(cbMapMutex_); + const auto iter = jsCbMap_.find(event); + if (iter == jsCbMap_.end()) { + ZLOGE("%{public}s is not registered", event.c_str()); + return; + } + if (event == SYNC_COMPLETE_EVENT) { + DistributedKv::SubscribeType kvtype = DistributedKv::SubscribeType::SUBSCRIBE_TYPE_ALL; + Status status = UnRegisterObserver(event, kvtype, opq, isUpdateFlag); + if (status != Status::SUCCESS) { + ZLOGE("UnregisterListener syncComplete failed, status %{public}d", status); + ThrowAniError(status, ""); + } + return; + } + for (uint8_t type = ani_kvstoreutils::SUBSCRIBE_LOCAL; type < ani_kvstoreutils::SUBSCRIBE_COUNT; type++) { + bool updated = false; + DistributedKv::SubscribeType kvtype = ani_kvstoreutils::SubscribeTypeToNative(type); + ::taihe::optional empty; + Status status = UnRegisterObserver(event, kvtype, opq, updated); + isUpdateFlag |= updated; + if (status != Status::SUCCESS) { + ZLOGE("UnregisterListener failed, type = %{public}d, status %{public}d", type, status); + ThrowAniError(status, ""); + return; + } + } + ZLOGI("UnregisterListener success type:%{public}s", event.c_str()); + } + + Status RegisterDataChangeObserver(DistributedKv::SubscribeType type, + ani_observerutils::VarCallbackType &cb, ani_ref callbackRef) + { + if (nativeStore_ == nullptr) { + ZLOGW("UnRegisterObserver, nativeStore_ is nullptr"); + return Status::SUCCESS; + } + std::lock_guard lock(cbMapMutex_); + auto &cbVec = jsCbMap_[DATA_CHANGE_EVENT]; + auto observer = std::make_shared(cb, callbackRef); + observer->SetIsSchemaStore(isSchemaStore_); + Status status = nativeStore_->SubscribeKvStore(type, observer); + if (status != Status::SUCCESS) { + ZLOGE("RegisterDataChangeObserver, SubscribeKvStore failed, %{public}d", status); + observer->Release(); + return status; + } + cbVec.emplace_back(std::move(observer)); + return Status::SUCCESS; + } + + Status RegisterSyncCompleteObserver(ani_observerutils::VarCallbackType &cb, ani_ref callbackRef) + { + if (nativeStore_ == nullptr) { + ZLOGW("UnRegisterObserver, nativeStore_ is nullptr"); + return Status::SUCCESS; + } + std::lock_guard lock(cbMapMutex_); + auto &cbVec = jsCbMap_[SYNC_COMPLETE_EVENT]; + auto observer = std::make_shared(cb, callbackRef); + observer->SetIsSchemaStore(isSchemaStore_); + Status status = nativeStore_->RegisterSyncCallback(observer); + if (status != Status::SUCCESS) { + ZLOGE("RegisterSyncCompleteObserver, RegisterSyncCallback failed, %{public}d", status); + observer->Release(); + return status; + } + cbVec.emplace_back(std::move(observer)); + return Status::SUCCESS; + } + + Status UnRegisterObserver(std::string const& event, DistributedKv::SubscribeType type, + ::taihe::optional_view opq, bool &isUpdateFlag) + { + if (nativeStore_ == nullptr) { + ZLOGW("UnRegisterObserver, nativeStore_ is nullptr"); + return Status::SUCCESS; + } + std::lock_guard lock(cbMapMutex_); + Status result = Status::SUCCESS; + auto &callbackList = jsCbMap_[event]; + if (!opq.has_value()) { + for (auto iter = callbackList.begin(); iter != callbackList.end();) { + result = Status::SUCCESS; + if (event == DATA_CHANGE_EVENT) { + result = nativeStore_->UnSubscribeKvStore(type, *iter); + } + if (result == Status::SUCCESS || result == Status::ALREADY_CLOSED) { + isUpdateFlag = true; + (*iter)->Release(); + iter = callbackList.erase(iter); + } else { + ZLOGE("SingleKVStoreImpl UnRegisterObserver failed, status %{public}d", result); + break; + } + } + if (callbackList.empty()) { + if (event == SYNC_COMPLETE_EVENT) { + result = nativeStore_->UnRegisterSyncCallback(); + ZLOGI("UnRegisterObserver syncComplete, unregister native, %{public}d", result); + } + jsCbMap_.erase(event); + } + return result; + } + ani_env *env = taihe::get_env(); + ani_observerutils::GlobalRefGuard guard(env, reinterpret_cast(opq.value())); + if (!guard) { + ZLOGE("Failed to UnRegisterObserver, GlobalRefGuard is false!"); + return result; + } + return UnRegisterObserver(event, type, guard.get(), isUpdateFlag); + } + + Status UnRegisterObserver(std::string const& event, DistributedKv::SubscribeType type, + ani_ref jsCallbackRef, bool &isUpdateFlag) + { + if (nativeStore_ == nullptr) { + ZLOGW("UnRegisterObserver, nativeStore_ is nullptr"); + return Status::SUCCESS; + } + std::lock_guard lock(cbMapMutex_); + ani_env *env = taihe::get_env(); + if (env == nullptr) { + ZLOGE("Failed to UnRegisterObserver, env is nullptr"); + return Status::SUCCESS; + } + auto &callbackList = jsCbMap_[event]; + const auto pred = [env, jsCallbackRef](std::shared_ptr &obj) { + ani_boolean is_equal = false; + return (ANI_OK == env->Reference_StrictEquals(jsCallbackRef, obj->jsCallbackRef_, &is_equal)) && is_equal; + }; + const auto it = std::find_if(callbackList.begin(), callbackList.end(), pred); + Status result = Status::SUCCESS; + if (it != callbackList.end()) { + if (event == DATA_CHANGE_EVENT) { + result = nativeStore_->UnSubscribeKvStore(type, *it); + } + if (result == Status::SUCCESS || result == Status::ALREADY_CLOSED) { + isUpdateFlag = true; + (*it)->Release(); + callbackList.erase(it); + } else { + return result; + } + } + if (callbackList.empty()) { + if (event == SYNC_COMPLETE_EVENT) { + result = nativeStore_->UnRegisterSyncCallback(); + ZLOGI("UnRegisterObserver syncComplete, unregister native, %{public}d", result); + } + jsCbMap_.erase(event); + } + return result; + } + + void UnRegisterAll() + { + ZLOGI("SingleKVStoreImpl UnRegisterAll"); + std::lock_guard lock(cbMapMutex_); + bool isUpdated = false; + ::taihe::optional empty; + for (uint8_t type = ani_kvstoreutils::SUBSCRIBE_LOCAL; type < ani_kvstoreutils::SUBSCRIBE_COUNT; type++) { + DistributedKv::SubscribeType kvtype = ani_kvstoreutils::SubscribeTypeToNative(type); + UnRegisterObserver(DATA_CHANGE_EVENT, kvtype, empty, isUpdated); + } + UnRegisterObserver(SYNC_COMPLETE_EVENT, DistributedKv::SubscribeType::SUBSCRIBE_TYPE_ALL, empty, isUpdated); + } + +protected: + std::shared_ptr nativeStore_; + ContextParam contextParam_; + bool isSchemaStore_ = false; + std::recursive_mutex cbMapMutex_; + std::map>> jsCbMap_; +}; + +class DeviceKVStoreImpl : public SingleKVStoreImpl { +public: + DeviceKVStoreImpl() + { + ZLOGE("DeviceKVStoreImpl default constructor"); + } + + explicit DeviceKVStoreImpl(std::shared_ptr kvStore) + :SingleKVStoreImpl(kvStore) + { + ZLOGI("DeviceKVStoreImpl constructor"); + } + + int64_t GetInner() override + { + return reinterpret_cast(this); + } + + static std::string GetDeviceKey(const std::string& deviceId, const std::string& key) + { + std::ostringstream oss; + if (!deviceId.empty()) { + oss << std::setfill('0') << std::setw(DEVICEID_WIDTH) << deviceId.length() << deviceId; + } + oss << key; + return oss.str(); + } + + distributedkvstore::ValueUnion GetByDeviceIdSync(::taihe::string_view deviceId, + ::taihe::string_view key) + { + std::string stdkey(key); + if (stdkey.empty()) { + ThrowAniError(Status::INVALID_ARGUMENT, "Parameter error:params key must be string and not allow empty"); + return distributedkvstore::ValueUnion::make_STRING(std::string("")); + } + std::string stddeviceid(deviceId); + bool isSchemaStore = IsSchemaStore(); + std::string deviceKey = GetDeviceKey(stddeviceid, stdkey); + OHOS::DistributedKv::Key kvkey(deviceKey); + OHOS::DistributedKv::Value kvblob; + Status status = nativeStore_->Get(kvkey, kvblob); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + return distributedkvstore::ValueUnion::make_STRING(std::string("")); + } + if (isSchemaStore) { + return distributedkvstore::ValueUnion::make_STRING(kvblob.ToString()); + } else { + uint8_t resultType = 0; + return ani_kvstoreutils::Blob2TaiheValue(kvblob, resultType); + } + } + + ::taihe::array GetEntriesByDeviceIdSync(::taihe::string_view deviceId, + ::taihe::string_view keyPrefix) + { + if (keyPrefix.empty()) { + ThrowAniError(Status::INVALID_ARGUMENT, ""); + return {}; + } + std::string stdkeyprefix(keyPrefix); + std::string stddeviceid(deviceId); + bool isSchemaStore = IsSchemaStore(); + auto query = std::make_shared(); + query->KeyPrefix(stdkeyprefix); + query->DeviceId(stddeviceid); + std::vector kventries; + Status status = nativeStore_->GetEntries(*query, kventries); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + return {}; + } + return ani_kvstoreutils::KvEntryArrayToTaihe(kventries, isSchemaStore); + } + + ::taihe::array GetEntriesByDeviceIdAndQuerySync( + ::taihe::string_view deviceId, distributedkvstore::weak::Query query) + { + std::string stddeviceid(deviceId); + bool isSchemaStore = IsSchemaStore(); + auto queryImpl = reinterpret_cast(query->GetInner()); + auto nativeQueryPtr = queryImpl->GetNativePtr(); + nativeQueryPtr->DeviceId(stddeviceid); + std::vector kventries; + Status status = nativeStore_->GetEntries(*nativeQueryPtr, kventries); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + return {}; + } + return ani_kvstoreutils::KvEntryArrayToTaihe(kventries, isSchemaStore); + } + + distributedkvstore::KVStoreResultSet GetResultSetByDeviceIdAndPrefixSync( + ::taihe::string_view deviceId, ::taihe::string_view keyPrefix) + { + if (keyPrefix.empty()) { + ThrowAniError(Status::INVALID_ARGUMENT, ""); + return taihe::make_holder(); + } + DistributedKv::DataQuery query; + query.KeyPrefix(std::string(keyPrefix)); + query.DeviceId(std::string(deviceId)); + std::shared_ptr kvResultSet; + Status status = nativeStore_->GetResultSet(query, kvResultSet); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + return taihe::make_holder(); + } + return taihe::make_holder( + kvResultSet, isSchemaStore_); + } + + distributedkvstore::KVStoreResultSet GetResultSetByDeviceIdAndQuerySync(::taihe::string_view deviceId, + distributedkvstore::weak::Query query) + { + auto queryImpl = reinterpret_cast(query->GetInner()); + auto nativeQueryPtr = queryImpl->GetNativePtr(); + nativeQueryPtr->DeviceId(std::string(deviceId)); + std::shared_ptr kvResultSet; + Status status = nativeStore_->GetResultSet(*nativeQueryPtr, kvResultSet); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + return taihe::make_holder(); + } + return taihe::make_holder( + kvResultSet, isSchemaStore_); + } + + distributedkvstore::KVStoreResultSet GetResultSetByDeviceIdAndPredicateSync( + ::taihe::string_view deviceId, uintptr_t predicates) + { + if (!IsSystemApp()) { + ThrowAniError(Status::PERMISSION_DENIED, ""); + return taihe::make_holder(); + } + ani_env *env = taihe::get_env(); + ani_object object = reinterpret_cast(predicates); + OHOS::DataShare::DataShareAbsPredicates *holder = + ani_utils::AniObjectUtils::Unwrap(env, object); + if (holder == nullptr) { + ZLOGE("GetResultSetByDeviceIdAndPredicateSync, holder is nullptr"); + return taihe::make_holder(); + } + DistributedKv::DataQuery kvquery; + Status status = OHOS::DistributedKv::KvUtils::ToQuery(*holder, kvquery); + if (status != Status::SUCCESS) { + ThrowAniError(Status::INVALID_ARGUMENT, ""); + return taihe::make_holder(); + } + kvquery.DeviceId(std::string(deviceId)); + std::shared_ptr kvResultSet; + status = nativeStore_->GetResultSet(kvquery, kvResultSet); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + return taihe::make_holder(); + } + return taihe::make_holder( + kvResultSet, isSchemaStore_); + } + + int32_t GetResultSizeByDeviceIdSync(::taihe::string_view deviceId, + distributedkvstore::weak::Query query) + { + auto queryImpl = reinterpret_cast(query->GetInner()); + auto nativeQueryPtr = queryImpl->GetNativePtr(); + nativeQueryPtr->DeviceId(std::string(deviceId)); + int resultSize = 0; + Status status = nativeStore_->GetCount(*nativeQueryPtr, resultSize); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + } + return resultSize; + } +}; + +class KVManagerImpl { +public: + explicit KVManagerImpl(const distributedkvstore::KVManagerConfig &config) + { + bundleName_ = std::string(config.bundleName); + if (bundleName_.empty()) { + ThrowAniError(Status::INVALID_ARGUMENT, + "Parameter error:The type of bundleName must be string."); + return; + } + int32_t result = AniGetContext(reinterpret_cast(config.context), contextParam_); + if (result != ANI_OK) { + ThrowAniError(Status::INVALID_ARGUMENT, "Parameter error:get context failed"); + return; + } + kvDataManager_ = std::make_shared(); + } + + ~KVManagerImpl() + { + UnregisterAllObserver(); + } + + static bool ParseOptions(TaiheOptions const& taiheOptions, DistributedKv::Options& options) + { + if (taiheOptions.createIfMissing.has_value()) { + options.createIfMissing = taiheOptions.createIfMissing.value(); + } + if (taiheOptions.encrypt.has_value()) { + options.encrypt = taiheOptions.encrypt.value(); + } + if (taiheOptions.backup.has_value()) { + options.backup = taiheOptions.backup.value(); + } + if (taiheOptions.autoSync.has_value()) { + options.autoSync = taiheOptions.autoSync.value(); + } + if (taiheOptions.kvStoreType.has_value()) { + options.kvStoreType = static_cast(taiheOptions.kvStoreType.value().get_value()); + } + if (taiheOptions.schema.has_value()) { + distributedkvstore::Schema schema = taiheOptions.schema.value(); + options.schema = SchemaImpl::DumpSchema(schema); + } + if (taiheOptions.securityLevel.has_value()) { + auto taiheLevel = taiheOptions.securityLevel.value().get_value(); + bool result = ani_kvstoreutils::TaiheSecurityLevelToNative(taiheLevel, options.securityLevel); + if (!result) { + ThrowAniError(Status::INVALID_ARGUMENT, "Parameter error:The params type not matching option"); + return false; + } + } + if (options.securityLevel == DistributedKv::SecurityLevel::INVALID_LABEL) { + ThrowAniError(Status::INVALID_ARGUMENT, "Parameter error:unusable securityLevel"); + return false; + } + if (!ani_kvstoreutils::IsStoreTypeSupported(options)) { + ThrowAniError(Status::INVALID_ARGUMENT, + "Parameter error:only support DEVICE_COLLABORATION or SINGLE_VERSION"); + return false; + } + return true; + } + + distributedkvstore::KvStoreTypeUnion MakeEmptyKvStore() + { + auto emptyResult = taihe::make_holder(); + return distributedkvstore::KvStoreTypeUnion::make_singleKVStore(emptyResult); + } + + distributedkvstore::KvStoreTypeUnion GetKVStoreSync(::taihe::string_view storeId, + TaiheOptions const& options) + { + if (kvDataManager_ == nullptr) { + ZLOGE("KVManager is null, failed!"); + ThrowAniError(Status::INVALID_ARGUMENT, "KVManager is null, failed!"); + return MakeEmptyKvStore(); + } + DistributedKv::AppId appId = { bundleName_ }; + DistributedKv::StoreId kvStoreId = { std::string(storeId) }; + DistributedKv::Options kvOptions; + bool parseResult = ParseOptions(options, kvOptions); + if (!parseResult) { + return MakeEmptyKvStore(); + } + kvOptions.baseDir = contextParam_.baseDir; + kvOptions.area = contextParam_.area + 1; + kvOptions.hapName = contextParam_.hapName; + kvOptions.apiVersion = contextParam_.apiVersion; + + std::shared_ptr kvStore; + Status status = kvDataManager_->GetSingleKvStore(kvOptions, appId, kvStoreId, kvStore); + ZLOGE("GetSingleKvStore, securityLevel %{public}d, status %{public}d", kvOptions.securityLevel, status); + if (status == OHOS::DistributedKv::DATA_CORRUPTED) { + kvOptions.rebuild = true; + status = kvDataManager_->GetSingleKvStore(kvOptions, appId, kvStoreId, kvStore); + } + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + return MakeEmptyKvStore(); + } + if (options.kvStoreType.has_value() && + options.kvStoreType.value() == distributedkvstore::KVStoreType::key_t::SINGLE_VERSION) { + auto nativeKVStore = + taihe::make_holder(kvStore); + (reinterpret_cast(nativeKVStore->GetInner()))->SetContextParam(contextParam_); + (reinterpret_cast(nativeKVStore->GetInner()))->SetSchemaInfo(!kvOptions.schema.empty()); + return distributedkvstore::KvStoreTypeUnion::make_singleKVStore(nativeKVStore); + } + auto nativeKVStore = + taihe::make_holder(kvStore); + (reinterpret_cast(nativeKVStore->GetInner()))->SetContextParam(contextParam_); + (reinterpret_cast(nativeKVStore->GetInner()))->SetSchemaInfo(!kvOptions.schema.empty()); + return distributedkvstore::KvStoreTypeUnion::make_deviceKVStore(nativeKVStore); + } + + void CloseKVStoreSync(::taihe::string_view appId, ::taihe::string_view storeId) + { + if (kvDataManager_ == nullptr) { + ThrowAniError(Status::INVALID_ARGUMENT, "KVManager is null, failed!"); + return; + } + if (std::string(appId).empty()) { + ThrowAniError(Status::INVALID_ARGUMENT, "Parameter error:appId empty"); + return; + } + if (!ani_kvstoreutils::IsValidStoreId(std::string(storeId))) { + ThrowAniError(Status::INVALID_ARGUMENT, + "Parameter error:storeId must be string,consist of letters, digits,"\ + " underscores(_), limit 128 characters"); + return; + } + DistributedKv::AppId kvappId = { std::string(appId) }; + DistributedKv::StoreId kvStoreId = { std::string(storeId) }; + Status status = kvDataManager_->CloseKvStore(kvappId, kvStoreId); + if (status != Status::SUCCESS && status != Status::STORE_NOT_FOUND && status != Status::STORE_NOT_OPEN) { + ThrowAniError(status, ""); + } + } + + void DeleteKVStoreSync(::taihe::string_view appId, ::taihe::string_view storeId) + { + if (kvDataManager_ == nullptr) { + ThrowAniError(Status::INVALID_ARGUMENT, "KVManager is null, failed!"); + return; + } + if (std::string(appId).empty()) { + ThrowAniError(Status::INVALID_ARGUMENT, "Parameter error:appId empty"); + return; + } + if (!ani_kvstoreutils::IsValidStoreId(std::string(storeId))) { + ThrowAniError(Status::INVALID_ARGUMENT, + "Parameter error:storeId must be string,consist of letters, digits,"\ + " underscores(_), limit 128 characters"); + } + DistributedKv::AppId kvappId = { std::string(appId) }; + DistributedKv::StoreId kvStoreId = { std::string(storeId) }; + std::string databaseDir = contextParam_.baseDir; + Status status = kvDataManager_->DeleteKvStore(kvappId, kvStoreId, databaseDir); + ZLOGE("DeleteKVStoreSync 3, status %{public}d, DISTRIBUTEDDATAMGR_ERR_OFFSET %{public}d", status, + DistributedKv::DISTRIBUTEDDATAMGR_ERR_OFFSET); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + } + } + + ::taihe::array<::taihe::string> GetAllKVStoreIdSync(::taihe::string_view appId) + { + std::string stdappid(appId); + if (stdappid.empty()) { + ThrowAniError(Status::INVALID_ARGUMENT, "Parameter error:appId empty"); + return {}; + } + if (stdappid.size() >= MAX_APP_ID_LEN) { + ThrowAniError(Status::INVALID_ARGUMENT, "Parameter error:appId exceed 256 characters"); + return {}; + } + if (kvDataManager_ == nullptr) { + ZLOGE("KVManager is null, failed!"); + ThrowAniError(ANI_INVALID_ARGS, "KVManager is null, failed!"); + return {}; + } + DistributedKv::AppId kvappId { stdappid }; + std::vector storeIds; + DistributedKv::Status status = kvDataManager_->GetAllKvStoreId(kvappId, storeIds); + if (status != Status::SUCCESS) { + ThrowAniError(status, ""); + return {}; + } + std::vector stringArray(storeIds.size()); + std::transform(storeIds.begin(), storeIds.end(), stringArray.begin(), [](DistributedKv::StoreId c) { + return c.storeId; + }); + return ::taihe::array<::taihe::string>(::taihe::copy_data_t{}, stringArray.data(), stringArray.size()); + } + + void OnDistributedDataServiceDie(::taihe::callback_view f, + uintptr_t opq) + { + ani_env *env = taihe::get_env(); + if (env == nullptr) { + return; + } + if (!ani_utils::AniIsInstanceOf(env, reinterpret_cast(opq), "std.core.Object")) { + ThrowAniError(Status::INVALID_ARGUMENT, ""); + return; + } + std::lock_guard lock(cbDeathListMutex_); + ani_object callbackObj = reinterpret_cast(opq); + ani_ref callbackRef = CreateCallbackRefIfNotDuplicate(jsDeathCbList_, callbackObj); + if (callbackRef == nullptr) { + ZLOGE("failed to register"); + return; + } + auto observer = std::make_shared(f, callbackRef); + kvDataManager_->RegisterKvStoreServiceDeathRecipient(observer); + jsDeathCbList_.emplace_back(std::move(observer)); + } + + void OffDistributedDataServiceDie(::taihe::optional_view opq) + { + ani_env *env = taihe::get_env(); + if (env == nullptr) { + ZLOGE("failed to get_env"); + return; + } + if (opq.has_value() && + !ani_utils::AniIsInstanceOf(env, reinterpret_cast(opq.value()), "std.core.Object")) { + ThrowAniError(Status::INVALID_ARGUMENT, ""); + return; + } + std::lock_guard lock(cbDeathListMutex_); + ani_ref jsCallbackRef = nullptr; + ani_object callbackObj = nullptr; + if (opq.has_value()) { + callbackObj = reinterpret_cast(opq.value()); + } + ani_observerutils::GlobalRefGuard guard(env, callbackObj); + if (callbackObj != nullptr && !guard) { + ZLOGE("GlobalRefGuard is false!"); + return; + } + jsCallbackRef = guard.get(); + auto pred = [env, jsCallbackRef](std::shared_ptr &obj) { + ani_boolean is_equal = false; + if (jsCallbackRef == nullptr) { + return true; + } + return (ANI_OK == env->Reference_StrictEquals(jsCallbackRef, obj->jsCallbackRef_, &is_equal)) && is_equal; + }; + for (auto iter = jsDeathCbList_.begin(); iter != jsDeathCbList_.end();) { + if (pred(*iter) == true) { + ZLOGI("jsDeathCbList_ erase item"); + (*iter)->Release(); + kvDataManager_->UnRegisterKvStoreServiceDeathRecipient(*iter); + iter = jsDeathCbList_.erase(iter); + } else { + ++iter; + } + } + } + +protected: + void UnregisterAllObserver() + { + ::taihe::optional empty; + OffDistributedDataServiceDie(empty); + } + +protected: + std::shared_ptr kvDataManager_; + ContextParam contextParam_; + std::string bundleName_; + std::recursive_mutex cbDeathListMutex_; + std::vector> jsDeathCbList_; +}; + +distributedkvstore::Schema CreateSchema() +{ + return taihe::make_holder(); +} + +distributedkvstore::FieldNode CreateFieldNode(::taihe::string_view name) +{ + return taihe::make_holder(name); +} + +distributedkvstore::Query CreateQuery() +{ + return taihe::make_holder(); +} + +distributedkvstore::KVManager createKVManager(const distributedkvstore::KVManagerConfig &config) +{ + return taihe::make_holder(config); +} +} // namespace + +// Since these macros are auto-generate, lint will cause false positive. +// NOLINTBEGIN +TH_EXPORT_CPP_API_CreateSchema(CreateSchema); +TH_EXPORT_CPP_API_CreateFieldNode(CreateFieldNode); +TH_EXPORT_CPP_API_CreateQuery(CreateQuery); +TH_EXPORT_CPP_API_createKVManager(createKVManager); +// NOLINTEND diff --git a/frameworks/innerkitsimpl/distributeddatafwk/include/ikvstore_sync_callback.h b/frameworks/innerkitsimpl/distributeddatafwk/include/ikvdb_notifier.h similarity index 51% rename from frameworks/innerkitsimpl/distributeddatafwk/include/ikvstore_sync_callback.h rename to frameworks/innerkitsimpl/distributeddatafwk/include/ikvdb_notifier.h index 94742c1ee06fe0c8a0504c71545d9c1b1572d8b0..fcef94e727f76d11d6e49e7ec8a6fe673e6b26f8 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/include/ikvstore_sync_callback.h +++ b/frameworks/innerkitsimpl/distributeddatafwk/include/ikvdb_notifier.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021-2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -13,39 +13,28 @@ * limitations under the License. */ -#ifndef I_KVSTORE_SYNC_CALLBACK_H -#define I_KVSTORE_SYNC_CALLBACK_H +#ifndef I_KVDB_NOTIFIER_H +#define I_KVDB_NOTIFIER_H #include #include "iremote_broker.h" #include "iremote_proxy.h" #include "iremote_stub.h" +#include "kvstore_observer.h" #include "types.h" #include "visibility.h" namespace OHOS { namespace DistributedKv { -class IKvStoreSyncCallback : public IRemoteBroker { +class IKVDBNotifier : public IRemoteBroker { public: DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.DistributedKv.IKvStoreSyncCallback"); virtual void SyncCompleted(const std::map &results, uint64_t sequenceId) = 0; + virtual void SyncCompleted(uint64_t seqNum, ProgressDetail &&detail) = 0; + virtual void OnRemoteChange(const std::map &mask, int32_t dataType) = 0; + virtual void OnSwitchChange(const SwitchNotification ¬ification) = 0; }; +} // namespace DistributedKv +} // namespace OHOS -class KvStoreSyncCallbackStub : public IRemoteStub { -public: - int OnRemoteRequest(uint32_t code, MessageParcel &data, - MessageParcel &reply, MessageOption &option) override; -}; - -class API_EXPORT KvStoreSyncCallbackProxy : public IRemoteProxy { -public: - explicit KvStoreSyncCallbackProxy(const sptr &impl); - ~KvStoreSyncCallbackProxy() = default; - void SyncCompleted(const std::map &results, uint64_t sequenceId) override; -private: - static inline BrokerDelegator delegator_; -}; -} // namespace DistributedKv -} // namespace OHOS - -#endif // I_KVSTORE_SYNC_CALLBACK_H +#endif // I_KVDB_NOTIFIER_H diff --git a/frameworks/innerkitsimpl/distributeddatafwk/include/ikvstore_observer.h b/frameworks/innerkitsimpl/distributeddatafwk/include/ikvstore_observer.h index 4f18454afcedb4fc46237e6e22b9671ca8ecf55b..988b0d5cc7e5dddeb357fc198b5b1b892d8a38fd 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/include/ikvstore_observer.h +++ b/frameworks/innerkitsimpl/distributeddatafwk/include/ikvstore_observer.h @@ -21,15 +21,24 @@ #include "ikvstore_observer.h" #include "iremote_proxy.h" #include "iremote_stub.h" +#include "types.h" namespace OHOS { namespace DistributedKv { class IKvStoreObserver : public IRemoteBroker { public: DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.DistributedKv.IKvStoreObserver"); + enum ChangeOp : int32_t { + OP_INSERT, + OP_UPDATE, + OP_DELETE, + OP_BUTT, + }; + using Keys = std::vector[OP_BUTT]; virtual void OnChange(const ChangeNotification &changeNotification) = 0; + virtual void OnChange(const DataOrigin &origin, Keys &&keys) = 0; protected: - static constexpr int64_t SWITCH_RAW_DATA_SIZE = 700 * 1024; + static constexpr int64_t SWITCH_RAW_DATA_SIZE = 200 * 1024; static constexpr size_t MAX_IPC_CAPACITY = 800 * 1024; }; @@ -38,16 +47,7 @@ public: int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; }; - -class API_EXPORT KvStoreObserverProxy : public IRemoteProxy { -public: - explicit KvStoreObserverProxy(const sptr &impl); - ~KvStoreObserverProxy() = default; - void OnChange(const ChangeNotification &changeNotification) override; -private: - static inline BrokerDelegator delegator_; -}; } // namespace DistributedKv } // namespace OHOS -#endif // I_KVSTORE_OBSERVER_H +#endif // I_KVSTORE_OBSERVER_H \ No newline at end of file diff --git a/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_client_death_observer.h b/frameworks/innerkitsimpl/distributeddatafwk/include/kvstore_client_death_observer.h similarity index 100% rename from frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_client_death_observer.h rename to frameworks/innerkitsimpl/distributeddatafwk/include/kvstore_client_death_observer.h diff --git a/frameworks/innerkitsimpl/distributeddatafwk/include/kvstore_datashare_bridge.h b/frameworks/innerkitsimpl/distributeddatafwk/include/kvstore_datashare_bridge.h index 9c32623d3e4ee5711596a5660af15eee1fabae58..474c88d1da915146d528177b3d7a5a2318e1fe51 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/include/kvstore_datashare_bridge.h +++ b/frameworks/innerkitsimpl/distributeddatafwk/include/kvstore_datashare_bridge.h @@ -34,11 +34,11 @@ public: int GetAllColumnNames(std::vector &columnNames) override; int OnGo(int32_t startRowIndex, int32_t targetRowIndex, DataShare::ResultSetBridge::Writer &writer) override; - + private: int Count(); - bool FillBlock(int startRowIndex, DataShare::ResultSetBridge::Writer &writer); + bool FillBlock(int startRowIndex, DataShare::ResultSetBridge::Writer &writer) __attribute__((no_sanitize("cfi"))); static constexpr int32_t INVALID_COUNT = -1; diff --git a/frameworks/innerkitsimpl/distributeddatafwk/include/switch_observer_bridge.h b/frameworks/innerkitsimpl/distributeddatafwk/include/switch_observer_bridge.h new file mode 100644 index 0000000000000000000000000000000000000000..5ad1290ba63e97b7885c879d31904f01c47c8d48 --- /dev/null +++ b/frameworks/innerkitsimpl/distributeddatafwk/include/switch_observer_bridge.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_DATA_SWITCH_OBSERVER_BRIDGE_H +#define OHOS_DISTRIBUTED_DATA_SWITCH_OBSERVER_BRIDGE_H + +#include "concurrent_map.h" +#include "executor_pool.h" +#include "kvstore_death_recipient.h" +#include "kvstore_observer.h" + +namespace OHOS::DistributedKv { +class SwitchObserverBridge : public KvStoreDeathRecipient { +public: + SwitchObserverBridge(const AppId &appId); + virtual ~SwitchObserverBridge() = default; + + void AddSwitchCallback(std::shared_ptr observer); + void DeleteSwitchCallback(std::shared_ptr observer); + void OnRemoteDied() override; + +private: + void RegisterSwitchObserver(); + void RestartRegisterTimer(); + ExecutorPool::TaskId taskId_ = ExecutorPool::INVALID_TASK_ID; + AppId switchAppId_; + std::mutex switchMutex_; + ConcurrentMap> switchObservers_; + std::atomic registerRetryCount_ = 0; +}; +} // namespace OHOS::DistributedKv +#endif // OHOS_DISTRIBUTED_DATA_SWITCH_OBSERVER_BRIDGE_H \ No newline at end of file diff --git a/frameworks/innerkitsimpl/distributeddatafwk/src/data_query.cpp b/frameworks/innerkitsimpl/distributeddatafwk/src/data_query.cpp index 3923637f603abe4d3ef47458d33992ce7e8248fb..2247827b3429d22e34cec83e54a5a3c457decd3d 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/src/data_query.cpp +++ b/frameworks/innerkitsimpl/distributeddatafwk/src/data_query.cpp @@ -632,7 +632,7 @@ DataQuery& DataQuery::InKeys(const std::vector &keys) return *this; } if (hasKeys_) { - ZLOGE("cannot set inkeys more than once"); + ZLOGE("Cannot set inkeys more than once"); return *this; } hasKeys_ = true; @@ -792,8 +792,8 @@ void DataQuery::EscapeSpace(std::string &input) bool DataQuery::ValidateField(const std::string &field) { - if (field.empty() || field.find(DataQuery::SPECIAL) != std::string::npos) { - ZLOGE("invalid string argument"); + if (field.empty() || field.find(DataQuery::SPECIAL) != std::string::npos || query_ == nullptr) { + ZLOGE("Invalid string argument"); return false; } return true; diff --git a/frameworks/innerkitsimpl/distributeddatafwk/src/distributed_kv_data_manager.cpp b/frameworks/innerkitsimpl/distributeddatafwk/src/distributed_kv_data_manager.cpp index 85bfcd28846d3ba5bd8911eeb6b87a096fa397fd..15ae042c5e8f42080bbd6d7ecc948803a2b03b43 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/src/distributed_kv_data_manager.cpp +++ b/frameworks/innerkitsimpl/distributeddatafwk/src/distributed_kv_data_manager.cpp @@ -48,16 +48,20 @@ Status DistributedKvDataManager::GetSingleKvStore(const Options &options, const singleKvStore = nullptr; if (options.securityLevel == INVALID_LABEL) { - ZLOGE("invalid security level, appId = %{private}s, storeId = %{private}s, kvStoreType = %{private}d", - appId.appId.c_str(), storeId.storeId.c_str(), options.kvStoreType); + ZLOGE("Invalid security level, appId = %{public}s, storeId = %{public}s, kvStoreType = %{public}d", + appId.appId.c_str(), StoreUtil::Anonymous(storeId.storeId).c_str(), options.kvStoreType); + return Status::INVALID_ARGUMENT; + } + if (options.dataType == DataType::TYPE_STATICS && options.autoSync) { + ZLOGE("STATICS data do not support auto sync, type:%{public}d", options.dataType); return Status::INVALID_ARGUMENT; } if (!storeId.IsValid()) { - ZLOGE("invalid storeId."); + ZLOGE("Invalid storeId."); return Status::INVALID_ARGUMENT; } if (!options.IsPathValid()) { - ZLOGE("invalid path."); + ZLOGE("Invalid path."); return Status::INVALID_ARGUMENT; } KvStoreServiceDeathNotifier::SetAppId(appId); @@ -67,26 +71,26 @@ Status DistributedKvDataManager::GetSingleKvStore(const Options &options, const return status; } -Status DistributedKvDataManager::GetAllKvStoreId(const AppId &appId, std::vector &storeIds) +Status DistributedKvDataManager::GetAllKvStoreId(const AppId &appId, std::vector &storeIds, int32_t subUser) { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); KvStoreServiceDeathNotifier::SetAppId(appId); - return StoreManager::GetInstance().GetStoreIds(appId, storeIds); + return StoreManager::GetInstance().GetStoreIds(appId, storeIds, subUser); } -Status DistributedKvDataManager::CloseKvStore(const AppId &appId, const StoreId &storeId) +Status DistributedKvDataManager::CloseKvStore(const AppId &appId, const StoreId &storeId, int32_t subUser) { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__), TraceSwitch::BYTRACE_ON | TraceSwitch::TRACE_CHAIN_ON); KvStoreServiceDeathNotifier::SetAppId(appId); if (!storeId.IsValid()) { - ZLOGE("invalid storeId."); + ZLOGE("Invalid storeId."); return Status::INVALID_ARGUMENT; } - return StoreManager::GetInstance().CloseKVStore(appId, storeId); + return StoreManager::GetInstance().CloseKVStore(appId, storeId, subUser); } Status DistributedKvDataManager::CloseKvStore(const AppId &appId, std::shared_ptr &kvStorePtr) @@ -95,59 +99,61 @@ Status DistributedKvDataManager::CloseKvStore(const AppId &appId, std::shared_pt TraceSwitch::BYTRACE_ON | TraceSwitch::TRACE_CHAIN_ON); if (kvStorePtr == nullptr) { - ZLOGE("kvStorePtr is nullptr."); + ZLOGE("This kvStorePtr is nullptr."); return Status::INVALID_ARGUMENT; } KvStoreServiceDeathNotifier::SetAppId(appId); StoreId storeId = kvStorePtr->GetStoreId(); + int32_t subUser = kvStorePtr->GetSubUser(); kvStorePtr = nullptr; - return StoreManager::GetInstance().CloseKVStore(appId, storeId); + return StoreManager::GetInstance().CloseKVStore(appId, storeId, subUser); } -Status DistributedKvDataManager::CloseAllKvStore(const AppId &appId) +Status DistributedKvDataManager::CloseAllKvStore(const AppId &appId, int32_t subUser) { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__), TraceSwitch::BYTRACE_ON | TraceSwitch::TRACE_CHAIN_ON); KvStoreServiceDeathNotifier::SetAppId(appId); - return StoreManager::GetInstance().CloseAllKVStore(appId); + return StoreManager::GetInstance().CloseAllKVStore(appId, subUser); } -Status DistributedKvDataManager::DeleteKvStore(const AppId &appId, const StoreId &storeId, const std::string &path) +Status DistributedKvDataManager::DeleteKvStore(const AppId &appId, const StoreId &storeId, + const std::string &path, int32_t subUser) { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__), TraceSwitch::BYTRACE_ON | TraceSwitch::TRACE_CHAIN_ON); if (!storeId.IsValid()) { - ZLOGE("invalid storeId."); + ZLOGE("Invalid storeId."); return Status::INVALID_ARGUMENT; } if (path.empty()) { - ZLOGE("path empty"); + ZLOGE("This path is empty"); return Status::INVALID_ARGUMENT; } KvStoreServiceDeathNotifier::SetAppId(appId); - return StoreManager::GetInstance().Delete(appId, storeId, path); + return StoreManager::GetInstance().Delete(appId, storeId, path, subUser); } -Status DistributedKvDataManager::DeleteAllKvStore(const AppId &appId, const std::string &path) +Status DistributedKvDataManager::DeleteAllKvStore(const AppId &appId, const std::string &path, int32_t subUser) { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__), TraceSwitch::BYTRACE_ON | TraceSwitch::TRACE_CHAIN_ON); if (path.empty()) { - ZLOGE("path empty"); + ZLOGE("This path is empty"); return Status::INVALID_ARGUMENT; } KvStoreServiceDeathNotifier::SetAppId(appId); std::vector storeIds; - Status status = GetAllKvStoreId(appId, storeIds); + Status status = GetAllKvStoreId(appId, storeIds, subUser); if (status != SUCCESS) { return status; } for (auto &storeId : storeIds) { - status = StoreManager::GetInstance().Delete(appId, storeId, path); + status = StoreManager::GetInstance().Delete(appId, storeId, path, subUser); if (status != SUCCESS) { return status; } @@ -158,7 +164,7 @@ Status DistributedKvDataManager::DeleteAllKvStore(const AppId &appId, const std: void DistributedKvDataManager::RegisterKvStoreServiceDeathRecipient( std::shared_ptr kvStoreDeathRecipient) { - ZLOGD("begin"); + ZLOGD("Begin"); if (kvStoreDeathRecipient == nullptr) { ZLOGW("Register KvStoreService Death Recipient input is null."); return; @@ -169,7 +175,7 @@ void DistributedKvDataManager::RegisterKvStoreServiceDeathRecipient( void DistributedKvDataManager::UnRegisterKvStoreServiceDeathRecipient( std::shared_ptr kvStoreDeathRecipient) { - ZLOGD("begin"); + ZLOGD("Begin"); if (kvStoreDeathRecipient == nullptr) { ZLOGW("UnRegister KvStoreService Death Recipient input is null."); return; @@ -235,5 +241,27 @@ Status DistributedKvDataManager::SetEndpoint(std::shared_ptr endpoint) isAlreadySet_ = true; return status; } + +Status DistributedKvDataManager::PutSwitch(const AppId &appId, const SwitchData &data) +{ + return StoreManager::GetInstance().PutSwitch(appId, data); +} + +std::pair DistributedKvDataManager::GetSwitch(const AppId &appId, const std::string &networkId) +{ + return StoreManager::GetInstance().GetSwitch(appId, networkId); +} + +Status DistributedKvDataManager::SubscribeSwitchData(const AppId &appId, std::shared_ptr observer) +{ + KvStoreServiceDeathNotifier::SetAppId(appId); + return StoreManager::GetInstance().SubscribeSwitchData(appId, observer); +} + +Status DistributedKvDataManager::UnsubscribeSwitchData(const AppId &appId, std::shared_ptr observer) +{ + KvStoreServiceDeathNotifier::SetAppId(appId); + return StoreManager::GetInstance().UnsubscribeSwitchData(appId, observer); +} } // namespace DistributedKv } // namespace OHOS diff --git a/frameworks/innerkitsimpl/distributeddatafwk/src/ikvstore_observer.cpp b/frameworks/innerkitsimpl/distributeddatafwk/src/ikvstore_observer.cpp index 8923e66178854514c2e9a4443cc17e66b07d8862..471d5f8da54871184f386ec5a1420d117ceb8d6e 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/src/ikvstore_observer.cpp +++ b/frameworks/innerkitsimpl/distributeddatafwk/src/ikvstore_observer.cpp @@ -28,79 +28,25 @@ namespace DistributedKv { using namespace std::chrono; enum { + CLOUD_ONCHANGE, ONCHANGE, }; -KvStoreObserverProxy::KvStoreObserverProxy(const sptr &impl) : IRemoteProxy(impl) -{ -} - -int64_t GetBufferSize(const std::vector &entries) -{ - int64_t bufferSize = 0; - for (const auto &item : entries) { - bufferSize += item.key.RawSize() + item.value.RawSize(); - } - return bufferSize; -} - -void KvStoreObserverProxy::OnChange(const ChangeNotification &changeNotification) -{ - MessageParcel data; - MessageParcel reply; - if (!data.WriteInterfaceToken(KvStoreObserverProxy::GetDescriptor())) { - ZLOGE("write descriptor failed"); - return; - } - int64_t insertSize = ITypesUtil::GetTotalSize(changeNotification.GetInsertEntries()); - int64_t updateSize = ITypesUtil::GetTotalSize(changeNotification.GetUpdateEntries()); - int64_t deleteSize = ITypesUtil::GetTotalSize(changeNotification.GetDeleteEntries()); - int64_t totalSize = insertSize + updateSize + deleteSize + sizeof(uint32_t); - if (insertSize < 0 || updateSize < 0 || deleteSize < 0 || !data.WriteInt32(totalSize)) { - ZLOGE("Write ChangeNotification buffer size to parcel failed."); - return; - } - ZLOGD("I(%" PRId64 ") U(%" PRId64 ") D(%" PRId64 ") T(%" PRId64 ")", insertSize, updateSize, deleteSize, totalSize); - if (totalSize < SWITCH_RAW_DATA_SIZE) { - if (!ITypesUtil::Marshal(data, changeNotification)) { - ZLOGW("Write ChangeNotification to parcel failed."); - return; - } - } else { - if (!ITypesUtil::Marshal(data, changeNotification.GetDeviceId(), uint32_t(changeNotification.IsClear())) || - !ITypesUtil::MarshalToBuffer(changeNotification.GetInsertEntries(), insertSize, data) || - !ITypesUtil::MarshalToBuffer(changeNotification.GetUpdateEntries(), updateSize, data) || - !ITypesUtil::MarshalToBuffer(changeNotification.GetDeleteEntries(), deleteSize, data)) { - ZLOGE("WriteChangeList to Parcel by buffer failed"); - return; - } - } - - MessageOption mo{ MessageOption::TF_WAIT_TIME }; - int error = Remote()->SendRequest(ONCHANGE, data, reply, mo); - if (error != 0) { - ZLOGE("SendRequest failed, error %d", error); - } -} - int32_t KvStoreObserverStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) { ZLOGD("code:%{public}u, callingPid:%{public}d", code, IPCSkeleton::GetCallingPid()); - std::u16string descriptor = KvStoreObserverStub::GetDescriptor(); - std::u16string remoteDescriptor = data.ReadInterfaceToken(); - if (descriptor != remoteDescriptor) { - ZLOGE("local descriptor is not equal to remote"); - return -1; + const int errorResult = -1; + if (KvStoreObserverStub::GetDescriptor() != data.ReadInterfaceToken()) { + ZLOGE("Local descriptor is not equal to remote"); + return errorResult; } switch (code) { case ONCHANGE: { - const int errorResult = -1; - int totalSize = data.ReadInt32(); - if (totalSize < SWITCH_RAW_DATA_SIZE) { + if (data.ReadInt32() < SWITCH_RAW_DATA_SIZE) { ChangeNotification notification({}, {}, {}, "", false); if (!ITypesUtil::Unmarshal(data, notification)) { - ZLOGE("changeNotification is nullptr"); + ZLOGE("ChangeNotification is nullptr"); return errorResult; } OnChange(notification); @@ -110,8 +56,7 @@ int32_t KvStoreObserverStub::OnRemoteRequest(uint32_t code, MessageParcel &data, std::vector inserts; std::vector updates; std::vector deletes; - if (!ITypesUtil::Unmarshal(data, deviceId, clear) || - !ITypesUtil::UnmarshalFromBuffer(data, inserts) || + if (!ITypesUtil::Unmarshal(data, deviceId, clear) || !ITypesUtil::UnmarshalFromBuffer(data, inserts) || !ITypesUtil::UnmarshalFromBuffer(data, updates) || !ITypesUtil::UnmarshalFromBuffer(data, deletes)) { ZLOGE("WriteChangeList to Parcel by buffer failed"); @@ -123,6 +68,16 @@ int32_t KvStoreObserverStub::OnRemoteRequest(uint32_t code, MessageParcel &data, } return 0; } + case CLOUD_ONCHANGE: { + std::string store; + Keys keys; + if (!ITypesUtil::Unmarshal(data, store, keys[OP_INSERT], keys[OP_UPDATE], keys[OP_DELETE])) { + ZLOGE("ReadChangeList from Parcel failed"); + return errorResult; + } + OnChange({ .store = store }, std::move(keys)); + return 0; + } default: return IPCObjectStub::OnRemoteRequest(code, data, reply, option); } diff --git a/frameworks/innerkitsimpl/distributeddatafwk/src/ikvstore_sync_callback.cpp b/frameworks/innerkitsimpl/distributeddatafwk/src/ikvstore_sync_callback.cpp deleted file mode 100644 index aeda9df2d951ba01e8e287e3da68ffba4c58af51..0000000000000000000000000000000000000000 --- a/frameworks/innerkitsimpl/distributeddatafwk/src/ikvstore_sync_callback.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "KvStoreSyncCallbackProxy" - -#include "ikvstore_sync_callback.h" -#include -#include -#include -#include -#include "log_print.h" -#include "message_parcel.h" -#include "message_option.h" -#include "types.h" - -namespace OHOS { -namespace DistributedKv { -enum { - SYNCCOMPLETED, -}; -constexpr int32_t MAX_DEVICES = 4096; -KvStoreSyncCallbackProxy::KvStoreSyncCallbackProxy(const sptr &impl) - : IRemoteProxy(impl) -{} - -void KvStoreSyncCallbackProxy::SyncCompleted(const std::map &results, uint64_t sequenceId) -{ - MessageParcel data; - MessageParcel reply; - if (!data.WriteInterfaceToken(KvStoreSyncCallbackProxy::GetDescriptor())) { - ZLOGE("write descriptor failed"); - return; - } - if (!data.WriteInt32(static_cast(results.size()))) { - ZLOGW("write results size error."); - return; - } - for (auto const &[k, v] : results) { - if (!data.WriteString(k) || - !data.WriteInt32(static_cast(v))) { - ZLOGW("write results error."); - return; - } - } - if (!data.WriteUint64(sequenceId)) { - ZLOGW("write label error."); - return; - } - MessageOption mo { MessageOption::TF_SYNC }; - int error = Remote()->SendRequest(SYNCCOMPLETED, data, reply, mo); - if (error != 0) { - ZLOGW("SendRequest failed, error %d", error); - } -} - -int32_t KvStoreSyncCallbackStub::OnRemoteRequest(uint32_t code, MessageParcel &data, - MessageParcel &reply, MessageOption &option) -{ - ZLOGD("code:%{public}u, callingPid:%{public}d", code, IPCSkeleton::GetCallingPid()); - std::u16string descriptor = KvStoreSyncCallbackStub::GetDescriptor(); - std::u16string remoteDescriptor = data.ReadInterfaceToken(); - if (descriptor != remoteDescriptor) { - ZLOGE("local descriptor is not equal to remote"); - return -1; - } - switch (code) { - case SYNCCOMPLETED: { - std::map results; - int32_t size = data.ReadInt32(); - if (size < 0 || size > MAX_DEVICES) { - ZLOGW("size < 0(%d)", size); - return 0; - } - for (int32_t i = 0; i < size; i++) { - results.insert(std::pair(data.ReadString(), - static_cast(data.ReadInt32()))); - } - uint64_t sequenceId = data.ReadUint64(); - SyncCompleted(results, sequenceId); - return 0; - } - default: - return IPCObjectStub::OnRemoteRequest(code, data, reply, option); - } -} -} // namespace DistributedKv -} // namespace OHOS diff --git a/frameworks/innerkitsimpl/distributeddatafwk/src/kv_utils.cpp b/frameworks/innerkitsimpl/distributeddatafwk/src/kv_utils.cpp index 4960860c802400d1aebf9ded9f55c756b36f8025..d1669f1c5447690a584e8cf650477b4cc908d765 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/src/kv_utils.cpp +++ b/frameworks/innerkitsimpl/distributeddatafwk/src/kv_utils.cpp @@ -33,7 +33,7 @@ constexpr KvUtils::QueryHandler KvUtils::HANDLERS[LAST_TYPE]; std::shared_ptr KvUtils::ToResultSetBridge(std::shared_ptr resultSet) { if (resultSet == nullptr) { - ZLOGE("param error, kvResultSet nullptr"); + ZLOGE("This param is error, kvResultSet is nullptr"); return nullptr; } return std::make_shared(resultSet); @@ -44,7 +44,7 @@ Status KvUtils::ToQuery(const DataShareAbsPredicates &predicates, DataQuery &que const auto &operations = predicates.GetOperationList(); for (const auto &oper : operations) { if (oper.operation < 0 || oper.operation >= LAST_TYPE) { - ZLOGE("operation param error"); + ZLOGE("This operation param is error"); return Status::NOT_SUPPORT; } (*HANDLERS[oper.operation])(oper, query); @@ -66,7 +66,7 @@ Entry KvUtils::ToEntry(const DataShareValuesBucket &valueBucket) { const auto &values = valueBucket.valuesMap; if (values.empty()) { - ZLOGE("valuesMap is null"); + ZLOGE("This valuesMap is null"); return {}; } Entry entry; @@ -87,16 +87,20 @@ Status KvUtils::GetKeys(const DataShareAbsPredicates &predicates, std::vector myKeys; for (const auto &oper : operations) { if (oper.operation != IN_KEY) { - ZLOGE("find operation failed"); + ZLOGE("This find operation is failed"); return Status::NOT_SUPPORT; } + if (oper.multiParams.empty()) { + ZLOGE("operation multi params is empty"); + return Status::ERROR; + } auto *val = std::get_if>(&oper.multiParams[0]); if (val == nullptr) { continue; @@ -113,7 +117,7 @@ Status KvUtils::ToEntryKey(const std::map(&it->second)) { @@ -123,7 +127,7 @@ Status KvUtils::ToEntryKey(const std::map +#include +#include +#include "dds_trace.h" +#include "dev_manager.h" +#include "log_print.h" +#include "store_util.h" + +namespace OHOS { +namespace DistributedKv { +using namespace OHOS::DistributedDataDfx; +KVDBNotifierClient::~KVDBNotifierClient() +{ + syncCallbackInfo_.Clear(); +} + +void KVDBNotifierClient::SyncCompleted(const std::map &results, uint64_t sequenceId) +{ + DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__), TraceSwitch::BYTRACE_ON); + auto finded = syncCallbackInfo_.Find(sequenceId); + if (finded.first) { + finded.second->SyncCompleted(results); + finded.second->SyncCompleted(results, sequenceId); + DeleteSyncCallback(sequenceId); + } +} + +void KVDBNotifierClient::SyncCompleted(uint64_t seqNum, ProgressDetail &&detail) +{ + DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__), TraceSwitch::BYTRACE_ON); + cloudSyncCallbacks_.ComputeIfPresent(seqNum, [&detail](const auto &key, const AsyncDetail &callback) { + auto finished = (detail.progress == SYNC_FINISH); + ZLOGD("Sync complete, seqNum%{public}" PRIu64, key); + if (callback != nullptr) { + callback(std::move(detail)); + } + return !finished; + }); +} + +void KVDBNotifierClient::OnRemoteChange(const std::map &mask, int32_t dataType) +{ + ZLOGD("Remote changed mask:%{public}zu dataType:%{public}d", mask.size(), dataType); + DataType type = static_cast(dataType); + for (const auto &[device, changed] : mask) { + auto clientUuid = DevManager::GetInstance().ToUUID(device); + if (clientUuid.empty()) { + continue; + } + if (!remotes_.Contains(clientUuid)) { + remotes_.InsertOrAssign(clientUuid, std::make_pair(true, true)); + } + remotes_.Compute(clientUuid, [isChange = changed, type](const auto &key, auto &value) -> bool { + switch (type) { + case DataType::TYPE_STATICS: + value.first = isChange; + break; + case DataType::TYPE_DYNAMICAL: + value.second = isChange; + break; + default: + break; + } + return true; + }); + } +} + +void KVDBNotifierClient::OnSwitchChange(const SwitchNotification ¬ification) +{ + switchObservers_.ForEachCopies( + [¬ification](auto &, std::shared_ptr &observer) { + observer->OnSwitchChange(notification); + return false; + }); +} + +bool KVDBNotifierClient::IsChanged(const std::string &deviceId, DataType dataType) +{ + auto [exist, value] = remotes_.Find(deviceId); + ZLOGD("exist:%{public}d, statics:%{public}d dynamic:%{public}d", + exist, value.first, value.second); + if (!exist) { + return true; + } + switch (dataType) { + case DataType::TYPE_STATICS: + return value.first; + case DataType::TYPE_DYNAMICAL: + return value.second; + default: + break; + } + return true; +} + +void KVDBNotifierClient::AddSyncCallback( + const std::shared_ptr callback, uint64_t sequenceId) +{ + if (callback == nullptr) { + ZLOGE("This callback is nullptr"); + return; + } + auto inserted = syncCallbackInfo_.Insert(sequenceId, callback); + if (!inserted) { + ZLOGE("The sequenceId %{public}" PRIu64 "is repeat!", sequenceId); + } +} + +void KVDBNotifierClient::DeleteSyncCallback(uint64_t sequenceId) +{ + syncCallbackInfo_.Erase(sequenceId); +} + +void KVDBNotifierClient::AddCloudSyncCallback(uint64_t sequenceId, const AsyncDetail &async) +{ + if (async == nullptr) { + ZLOGE("Cloud sync callback is nullptr"); + return; + } + cloudSyncCallbacks_.Insert(sequenceId, async); +} + +void KVDBNotifierClient::DeleteCloudSyncCallback(uint64_t sequenceId) +{ + cloudSyncCallbacks_.Erase(sequenceId); +} + +void KVDBNotifierClient::AddSwitchCallback(const std::string &appId, std::shared_ptr observer) +{ + if (observer == nullptr) { + return; + } + if (switchObservers_.Contains(uintptr_t(observer.get()))) { + ZLOGI("Duplicate observer"); + return; + } + switchObservers_.Insert(uintptr_t(observer.get()), observer); +} + +void KVDBNotifierClient::DeleteSwitchCallback(const std::string &appId, std::shared_ptr observer) +{ + if (observer == nullptr) { + return; + } + switchObservers_.Erase(uintptr_t(observer.get())); +} +} // namespace DistributedKv +} // namespace OHOS diff --git a/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_sync_callback_client.h b/frameworks/innerkitsimpl/distributeddatafwk/src/kvdb_notifier_client.h similarity index 46% rename from frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_sync_callback_client.h rename to frameworks/innerkitsimpl/distributeddatafwk/src/kvdb_notifier_client.h index 301dda0a575945bf830f1367a6e33220d6eb7da6..9f55f4f84a5b2d91fd661e4eae58ee84d992654c 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_sync_callback_client.h +++ b/frameworks/innerkitsimpl/distributeddatafwk/src/kvdb_notifier_client.h @@ -13,30 +13,48 @@ * limitations under the License. */ -#ifndef KVSTORE_SYNC_CALLBACK_CLIENT_H -#define KVSTORE_SYNC_CALLBACK_CLIENT_H +#ifndef OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_NOTIFIER_CLIENT_H +#define OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_NOTIFIER_CLIENT_H #include #include "concurrent_map.h" -#include "ikvstore_sync_callback.h" +#include "kvdb_notifier_stub.h" #include "kvstore_sync_callback.h" namespace OHOS { namespace DistributedKv { -class KvStoreSyncCallbackClient : public KvStoreSyncCallbackStub { +class KVDBNotifierClient : public KVDBNotifierStub { public: - KvStoreSyncCallbackClient() = default; - virtual ~KvStoreSyncCallbackClient(); + KVDBNotifierClient() = default; + virtual ~KVDBNotifierClient(); void SyncCompleted(const std::map &results, uint64_t sequenceId) override; + void SyncCompleted(uint64_t seqNum, ProgressDetail &&detail) override; + + void OnRemoteChange(const std::map &mask, int32_t dataType) override; + + void OnSwitchChange(const SwitchNotification ¬ification) override; void AddSyncCallback(const std::shared_ptr callback, uint64_t sequenceId); void DeleteSyncCallback(uint64_t sequenceId); + + void AddSwitchCallback(const std::string &appId, std::shared_ptr observer); + + void DeleteSwitchCallback(const std::string &appId, std::shared_ptr observer); + + void AddCloudSyncCallback(uint64_t sequenceId, const AsyncDetail &async); + void DeleteCloudSyncCallback(uint64_t sequenceId); + + bool IsChanged(const std::string &deviceId, DataType dataType); + private: ConcurrentMap> syncCallbackInfo_; + ConcurrentMap> remotes_; + ConcurrentMap> switchObservers_; + ConcurrentMap cloudSyncCallbacks_; }; -} // namespace DistributedKv -} // namespace OHOS +} // namespace DistributedKv +} // namespace OHOS -#endif // KVSTORE_SYNC_CALLBACK_CLIENT_H +#endif // OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_NOTIFIER_CLIENT_H diff --git a/frameworks/innerkitsimpl/distributeddatafwk/src/kvdb_notifier_stub.cpp b/frameworks/innerkitsimpl/distributeddatafwk/src/kvdb_notifier_stub.cpp new file mode 100644 index 0000000000000000000000000000000000000000..14c11e25072a9f7c225d90929f259d82c76edc49 --- /dev/null +++ b/frameworks/innerkitsimpl/distributeddatafwk/src/kvdb_notifier_stub.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. + */ + +#define LOG_TAG "KVDBNotifierStub" + +#include "kvdb_notifier_stub.h" +#include +#include +#include +#include +#include +#include "itypes_util.h" +#include "log_print.h" +#include "message_parcel.h" +#include "message_option.h" +#include "store_util.h" +#include "types.h" + +namespace OHOS { +namespace DistributedKv { +const KVDBNotifierStub::Handler + KVDBNotifierStub::HANDLERS[static_cast(KVDBNotifierCode::TRANS_BUTT)] = { + &KVDBNotifierStub::OnSyncCompleted, + &KVDBNotifierStub::OnCloudSyncCompleted, + &KVDBNotifierStub::OnOnRemoteChange, + &KVDBNotifierStub::OnOnSwitchChange, +}; + +int32_t KVDBNotifierStub::OnRemoteRequest( + uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) +{ + ZLOGI("code:%{public}u, callingPid:%{public}d", code, IPCSkeleton::GetCallingPid()); + std::u16string local = KVDBNotifierStub::GetDescriptor(); + std::u16string remote = data.ReadInterfaceToken(); + if (local != remote) { + ZLOGE("Local descriptor is not equal to remote"); + return -1; + } + if (code >= static_cast(KVDBNotifierCode::TRANS_HEAD) && + code < static_cast(KVDBNotifierCode::TRANS_BUTT) && HANDLERS[code] != nullptr) { + return (this->*HANDLERS[code])(data, reply); + } + ZLOGE("Not support code:%{public}u, BUTT:%{public}d", + code, static_cast(KVDBNotifierCode::TRANS_BUTT)); + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); +} + +int32_t KVDBNotifierStub::OnSyncCompleted(MessageParcel& data, MessageParcel& reply) +{ + std::map results; + uint64_t sequenceId; + if (!ITypesUtil::Unmarshal(data, results, sequenceId)) { + ZLOGE("Unmarshal results size:%{public}zu, sequenceId:%{public}" PRIu64, results.size(), sequenceId); + return IPC_STUB_INVALID_DATA_ERR; + } + SyncCompleted(std::move(results), sequenceId); + return ERR_NONE; +} + +int32_t KVDBNotifierStub::OnCloudSyncCompleted(MessageParcel& data, MessageParcel& reply) +{ + ProgressDetail detail; + uint64_t sequenceId; + if (!ITypesUtil::Unmarshal(data, sequenceId, detail)) { + ZLOGE("Unmarshal sequenceId:%{public}" PRIu64, sequenceId); + return IPC_STUB_INVALID_DATA_ERR; + } + SyncCompleted(sequenceId, std::move(detail)); + return ERR_NONE; +} + +int32_t KVDBNotifierStub::OnOnRemoteChange(MessageParcel& data, MessageParcel& reply) +{ + std::map mask; + int32_t dataType; + if (!ITypesUtil::Unmarshal(data, mask, dataType)) { + ZLOGE("Unmarshal fail mask size:%{public}zu", mask.size()); + return IPC_STUB_INVALID_DATA_ERR; + } + if (dataType < static_cast(DataType::TYPE_STATICS) || dataType > static_cast(DataType::TYPE_DYNAMICAL)) { + ZLOGE("Invalid dataType:%{public}d", dataType); + return IPC_STUB_INVALID_DATA_ERR; + } + OnRemoteChange(std::move(mask), dataType); + return ERR_NONE; +} + +int32_t KVDBNotifierStub::OnOnSwitchChange(MessageParcel& data, MessageParcel& reply) +{ + SwitchNotification notification; + if (!ITypesUtil::Unmarshal(data, notification)) { + ZLOGE("Unmarshal fail"); + return IPC_STUB_INVALID_DATA_ERR; + } + OnSwitchChange(std::move(notification)); + return ERR_NONE; +} +} // namespace DistributedKv +} // namespace OHOS diff --git a/frameworks/innerkitsimpl/distributeddatafwk/src/kvdb_notifier_stub.h b/frameworks/innerkitsimpl/distributeddatafwk/src/kvdb_notifier_stub.h new file mode 100644 index 0000000000000000000000000000000000000000..c0912281b47c02e6022577c19a5a7557ab29681e --- /dev/null +++ b/frameworks/innerkitsimpl/distributeddatafwk/src/kvdb_notifier_stub.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_NOTIFIER_STUB_H +#define OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_NOTIFIER_STUB_H + +#include "distributeddata_kvdb_ipc_interface_code.h" +#include "ikvdb_notifier.h" +#include "iremote_broker.h" +#include "iremote_stub.h" + +namespace OHOS { +namespace DistributedKv { +class KVDBNotifierStub : public IRemoteStub { +public: + int OnRemoteRequest( + uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + +private: + using Handler = int32_t (KVDBNotifierStub::*)(MessageParcel &data, MessageParcel &reply); + int32_t OnSyncCompleted(MessageParcel& data, MessageParcel& reply); + int32_t OnCloudSyncCompleted(MessageParcel& data, MessageParcel& reply); + int32_t OnOnRemoteChange(MessageParcel& data, MessageParcel& reply); + int32_t OnOnSwitchChange(MessageParcel& data, MessageParcel& reply); + static const Handler HANDLERS[static_cast(KVDBNotifierCode::TRANS_BUTT)]; +}; +} // namespace DistributedKv +} // namespace OHOS + +#endif // OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_NOTIFIER_STUB_H \ No newline at end of file diff --git a/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_client_death_observer.cpp b/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_client_death_observer.cpp index 0d2706bc43690632d948dfab85c955f05d1fdce8..401f083f926dbf2b7fc72e29e8071deaa6055a22 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_client_death_observer.cpp +++ b/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_client_death_observer.cpp @@ -22,12 +22,12 @@ namespace OHOS { namespace DistributedKv { KvStoreClientDeathObserver::KvStoreClientDeathObserver() { - ZLOGI("this client death observer"); + ZLOGI("This client death observer"); } KvStoreClientDeathObserver::~KvStoreClientDeathObserver() { - ZLOGI("destructor this client death observer"); + ZLOGI("Destructor this client death observer"); } } // namespace DistributedKv } // namespace OHOS diff --git a/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_datashare_bridge.cpp b/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_datashare_bridge.cpp index a1e1e4e57582689abe7cf680e06f6081d13952fe..eeb679bc7ce6f2881e25cf3d273aebc12f6b3318 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_datashare_bridge.cpp +++ b/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_datashare_bridge.cpp @@ -38,7 +38,7 @@ int KvStoreDataShareBridge::GetAllColumnNames(std::vector &columnsN bool KvStoreDataShareBridge::FillBlock(int pos, ResultSetBridge::Writer &writer) { if (kvResultSet_ == nullptr) { - ZLOGE("kvResultSet_ nullptr"); + ZLOGE("This kvResultSet_ is nullptr"); return false; } bool isMoved = kvResultSet_->MoveToPosition(pos); @@ -73,7 +73,7 @@ bool KvStoreDataShareBridge::FillBlock(int pos, ResultSetBridge::Writer &writer) int KvStoreDataShareBridge::Count() { if (kvResultSet_ == nullptr) { - ZLOGE("kvResultSet_ nullptr"); + ZLOGE("This kvResultSet_ is nullptr"); return INVALID_COUNT; } if (resultRowCount != INVALID_COUNT) { @@ -81,7 +81,7 @@ int KvStoreDataShareBridge::Count() } int count = kvResultSet_->GetCount(); if (count < 0) { - ZLOGE("kvResultSet count invalid: %{public}d", count); + ZLOGE("This kvResultSet count is invalid: %{public}d", count); return INVALID_COUNT; } resultRowCount = count; @@ -90,13 +90,13 @@ int KvStoreDataShareBridge::Count() int KvStoreDataShareBridge::OnGo(int32_t start, int32_t target, ResultSetBridge::Writer &writer) { if ((start < 0) || (target < 0) || (start > target) || (target >= Count())) { - ZLOGE("nowRowIndex out of line: %{public}d", target); + ZLOGE("The nowRowIndex out of line: %{public}d", target); return -1; } for (int pos = start; pos <= target; pos++) { bool ret = FillBlock(pos, writer); if (!ret) { - ZLOGE("nowRowIndex out of line: %{public}d %{public}d", pos, target); + ZLOGE("The nowRowIndex out of line: %{public}d %{public}d", pos, target); return pos - 1; } } diff --git a/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_observer_client.cpp b/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_observer_client.cpp index 2996c209334335118fd7fcb1e5573e8aad43f315..2acce4fb147d3d6d936ff6fa03015169315d71a8 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_observer_client.cpp +++ b/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_observer_client.cpp @@ -23,21 +23,29 @@ namespace DistributedKv { KvStoreObserverClient::KvStoreObserverClient(std::shared_ptr kvStoreObserver) : kvStoreObserver_(kvStoreObserver) { - ZLOGI("start"); + ZLOGI("Start"); } KvStoreObserverClient::~KvStoreObserverClient() { - ZLOGI("end"); + ZLOGI("End"); } void KvStoreObserverClient::OnChange(const ChangeNotification &changeNotification) { - ZLOGI("start"); + ZLOGI("Start"); if (kvStoreObserver_ != nullptr) { ZLOGI("SINGLE_VERSION start"); kvStoreObserver_->OnChange(changeNotification); } } + +void KvStoreObserverClient::OnChange(const DataOrigin &origin, IKvStoreObserver::Keys &&keys) +{ + ZLOGI("Start"); + if (kvStoreObserver_ != nullptr) { + kvStoreObserver_->OnChange(origin, std::move(keys)); + } +} } // namespace DistributedKv } // namespace OHOS diff --git a/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_observer_client.h b/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_observer_client.h index da219a62f5bbd86dab7c91a98971ebee09e3c45f..f223b9f74bcfa83e72b0f8455ff4a79a082f0868 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_observer_client.h +++ b/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_observer_client.h @@ -31,6 +31,7 @@ public: ~KvStoreObserverClient(); void OnChange(const ChangeNotification &changeNotification) override; + void OnChange(const DataOrigin &origin, IKvStoreObserver::Keys &&keys) override; private: static const int MAX_TRY_COUNT = 10; diff --git a/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_observer_nb_impl.h b/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_observer_nb_impl.h index 0b66a828445f0bf31aa21382bcf64b15c2f34568..37ff16a9445617ba06a04424ece61416611c6974 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_observer_nb_impl.h +++ b/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_observer_nb_impl.h @@ -34,7 +34,7 @@ public: virtual void OnChange(const DistributedDB::KvStoreChangedData &data) { if (appKvStoreObserver_ == nullptr) { - ZLOGE("appKvStoreObserver_ is nullptr."); + ZLOGE("This appKvStoreObserver_ is nullptr."); return; } std::list insertList = data.GetEntriesInserted(); diff --git a/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_service_death_notifier.cpp b/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_service_death_notifier.cpp index 8c70fc821d7cc6dcb0b051cdcd204d5469ca7fa9..a9106260da6c9426595269309aaacede01038078 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_service_death_notifier.cpp +++ b/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_service_death_notifier.cpp @@ -30,83 +30,64 @@ namespace OHOS { namespace DistributedKv { std::mutex KvStoreServiceDeathNotifier::instanceMutex_; -KvStoreServiceDeathNotifier* KvStoreServiceDeathNotifier::instance_ = nullptr; - -KvStoreServiceDeathNotifier* KvStoreServiceDeathNotifier::GetInstance() +KvStoreServiceDeathNotifier& KvStoreServiceDeathNotifier::GetInstance() { - if (instance_ == nullptr) { - std::lock_guard lock(instanceMutex_); - if (instance_ == nullptr) { - instance_ = new (std::nothrow) KvStoreServiceDeathNotifier(); - if (instance_ == nullptr) { - ZLOGE("KvStoreServiceDeathNotifier nullptr"); - } - return instance_; - } - } - return instance_; + static KvStoreServiceDeathNotifier instance; + return instance; } void KvStoreServiceDeathNotifier::SetAppId(const AppId &appId) { - auto *instance = GetInstance(); - if (instance == nullptr) { - return; - } - std::lock_guard lg(instance->mutex_); - instance->appId_ = appId; + auto &instance = GetInstance(); + std::lock_guard lg(instance.mutex_); + instance.appId_ = appId; } AppId KvStoreServiceDeathNotifier::GetAppId() { - auto *instance = GetInstance(); - if (instance == nullptr) { - return {}; - } - std::lock_guard lg(instance->mutex_); - return instance->appId_; + auto &instance = GetInstance(); + std::lock_guard lg(instance.mutex_); + return instance.appId_; } sptr KvStoreServiceDeathNotifier::GetDistributedKvDataService() { - ZLOGD("begin."); - auto *instance = GetInstance(); - if (instance == nullptr) { - return nullptr; - } - std::lock_guard lg(instance->watchMutex_); - if (instance->kvDataServiceProxy_ != nullptr) { - return instance->kvDataServiceProxy_; + ZLOGD("Begin."); + auto &instance = GetInstance(); + std::lock_guard lg(instance.watchMutex_); + if (instance.kvDataServiceProxy_ != nullptr) { + return instance.kvDataServiceProxy_; } - ZLOGI("create remote proxy."); + ZLOGI("Create remote proxy."); auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); if (samgr == nullptr) { - ZLOGE("get samgr fail."); + ZLOGE("Get samgr fail."); return nullptr; } auto remote = samgr->CheckSystemAbility(DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID); - instance->kvDataServiceProxy_ = iface_cast(remote); - if (instance->kvDataServiceProxy_ == nullptr) { - ZLOGE("initialize proxy failed."); + instance.kvDataServiceProxy_ = iface_cast(remote); + if (instance.kvDataServiceProxy_ == nullptr) { + ZLOGE("Initialize proxy failed."); return nullptr; } - if (instance->deathRecipientPtr_ == nullptr) { - instance->deathRecipientPtr_ = new (std::nothrow) ServiceDeathRecipient(); - if (instance->deathRecipientPtr_ == nullptr) { - ZLOGW("new KvStoreDeathRecipient failed"); + if (instance.deathRecipientPtr_ == nullptr) { + instance.deathRecipientPtr_ = new (std::nothrow) ServiceDeathRecipient(); + if (instance.deathRecipientPtr_ == nullptr) { + ZLOGW("New KvStoreDeathRecipient failed"); + instance.kvDataServiceProxy_ = nullptr; return nullptr; } } - if ((remote->IsProxyObject()) && (!remote->AddDeathRecipient(instance->deathRecipientPtr_))) { - ZLOGE("failed to add death recipient."); + if ((remote->IsProxyObject()) && (!remote->AddDeathRecipient(instance.deathRecipientPtr_))) { + ZLOGE("Failed to add death recipient."); } - instance->RegisterClientDeathObserver(); + instance.RegisterClientDeathObserver(); - return instance->kvDataServiceProxy_; + return instance.kvDataServiceProxy_; } void KvStoreServiceDeathNotifier::RegisterClientDeathObserver() @@ -118,7 +99,7 @@ void KvStoreServiceDeathNotifier::RegisterClientDeathObserver() clientDeathObserverPtr_ = new (std::nothrow) KvStoreClientDeathObserver(); } if (clientDeathObserverPtr_ == nullptr) { - ZLOGW("new KvStoreClientDeathObserver failed"); + ZLOGW("New KvStoreClientDeathObserver failed"); return; } kvDataServiceProxy_->RegisterClientDeathObserver(GetAppId(), clientDeathObserverPtr_); @@ -126,49 +107,40 @@ void KvStoreServiceDeathNotifier::RegisterClientDeathObserver() void KvStoreServiceDeathNotifier::AddServiceDeathWatcher(std::shared_ptr watcher) { - auto *instance = GetInstance(); - if (instance == nullptr) { - return; - } - std::lock_guard lg(instance->watchMutex_); - auto ret = instance->serviceDeathWatchers_.insert(std::move(watcher)); + auto &instance = GetInstance(); + std::lock_guard lg(instance.watchMutex_); + auto ret = instance.serviceDeathWatchers_.insert(std::move(watcher)); if (ret.second) { - ZLOGI("success set size: %zu", instance->serviceDeathWatchers_.size()); + ZLOGI("Success set size: %zu", instance.serviceDeathWatchers_.size()); } else { - ZLOGE("failed set size: %zu", instance->serviceDeathWatchers_.size()); + ZLOGE("Failed set size: %zu", instance.serviceDeathWatchers_.size()); } } void KvStoreServiceDeathNotifier::RemoveServiceDeathWatcher(std::shared_ptr watcher) { - auto *instance = GetInstance(); - if (instance == nullptr) { - return; - } - std::lock_guard lg(instance->watchMutex_); - auto it = instance->serviceDeathWatchers_.find(std::move(watcher)); - if (it != instance->serviceDeathWatchers_.end()) { - instance->serviceDeathWatchers_.erase(it); - ZLOGI("find & erase set size: %zu", instance->serviceDeathWatchers_.size()); + auto &instance = GetInstance(); + std::lock_guard lg(instance.watchMutex_); + auto it = instance.serviceDeathWatchers_.find(std::move(watcher)); + if (it != instance.serviceDeathWatchers_.end()) { + instance.serviceDeathWatchers_.erase(it); + ZLOGI("Find & erase set size: %zu", instance.serviceDeathWatchers_.size()); } else { - ZLOGE("no found set size: %zu", instance->serviceDeathWatchers_.size()); + ZLOGE("No found set size: %zu", instance.serviceDeathWatchers_.size()); } } void KvStoreServiceDeathNotifier::ServiceDeathRecipient::OnRemoteDied(const wptr &remote) { ZLOGW("DistributedDataMgrService died."); - auto *instance = GetInstance(); - if (instance == nullptr) { - return; - } + auto &instance = GetInstance(); // Need to do this with the lock held - std::lock_guard lg(instance->watchMutex_); - instance->kvDataServiceProxy_ = nullptr; - ZLOGI("watcher set size: %zu", instance->serviceDeathWatchers_.size()); - for (const auto &watcher : instance->serviceDeathWatchers_) { + std::lock_guard lg(instance.watchMutex_); + instance.kvDataServiceProxy_ = nullptr; + ZLOGI("Watcher set size: %zu", instance.serviceDeathWatchers_.size()); + for (const auto &watcher : instance.serviceDeathWatchers_) { if (watcher == nullptr) { - ZLOGI("watcher is nullptr"); + ZLOGI("This watcher is nullptr"); continue; } TaskExecutor::GetInstance().Execute([watcher] { @@ -179,12 +151,12 @@ void KvStoreServiceDeathNotifier::ServiceDeathRecipient::OnRemoteDied(const wptr KvStoreServiceDeathNotifier::ServiceDeathRecipient::ServiceDeathRecipient() { - ZLOGI("constructor."); + ZLOGI("Constructor."); } KvStoreServiceDeathNotifier::ServiceDeathRecipient::~ServiceDeathRecipient() { - ZLOGI("destructor."); + ZLOGI("Destructor."); } } // namespace DistributedKv } // namespace OHOS diff --git a/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_service_death_notifier.h b/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_service_death_notifier.h index 0090d7364f56f9e34687b3ee6bf9c4e4969a7992..16d5c64ae4bf3f30f60dc01c9a941f0cded18df2 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_service_death_notifier.h +++ b/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_service_death_notifier.h @@ -49,7 +49,7 @@ private: void OnRemoteDied(const wptr &remote) override; }; - static KvStoreServiceDeathNotifier* GetInstance(); + static KvStoreServiceDeathNotifier& GetInstance(); static std::mutex instanceMutex_; static KvStoreServiceDeathNotifier *instance_; diff --git a/frameworks/innerkitsimpl/distributeddatafwk/src/switch_observer_bridge.cpp b/frameworks/innerkitsimpl/distributeddatafwk/src/switch_observer_bridge.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8ef432d5ccf7b2b8990e107d64e81eacee00db58 --- /dev/null +++ b/frameworks/innerkitsimpl/distributeddatafwk/src/switch_observer_bridge.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "SwitchObserverBridge" + +#include "kvdb_service_client.h" +#include "kvstore_service_death_notifier.h" +#include "log_print.h" +#include "switch_observer_bridge.h" + +namespace OHOS::DistributedKv { +static constexpr int32_t INTERVAL = 500; // ms +SwitchObserverBridge::SwitchObserverBridge(const AppId &appId) +{ + switchAppId_ = appId; +} + +void SwitchObserverBridge::AddSwitchCallback(std::shared_ptr observer) +{ + if (observer == nullptr) { + return; + } + switchObservers_.InsertOrAssign(uintptr_t(observer.get()), observer); +} + +void SwitchObserverBridge::DeleteSwitchCallback(std::shared_ptr observer) +{ + if (observer == nullptr) { + return; + } + switchObservers_.Erase(uintptr_t(observer.get())); +} + +void SwitchObserverBridge::OnRemoteDied() +{ + std::lock_guard lock(switchMutex_); + if (!switchAppId_.IsValid() || switchObservers_.Empty() || taskId_ != ExecutorPool::INVALID_TASK_ID) { + ZLOGI("appId is :%{public}s, observers size is %{public}zu", switchAppId_.appId.c_str(), + switchObservers_.Size()); + return; + } + RestartRegisterTimer(); +} + +void SwitchObserverBridge::RegisterSwitchObserver() +{ + std::lock_guard lock(switchMutex_); + auto service = KVDBServiceClient::GetInstance(); + if (service == nullptr) { + RestartRegisterTimer(); + return; + } + auto serviceAgent = service->GetServiceAgent(switchAppId_); + if (serviceAgent == nullptr) { + RestartRegisterTimer(); + return; + } + auto status = service->SubscribeSwitchData(switchAppId_); + if (status != SUCCESS) { + RestartRegisterTimer(); + return; + } + registerRetryCount_ = 0; + taskId_ = ExecutorPool::INVALID_TASK_ID; + switchObservers_.ForEach([&](auto &, auto &switchObserver) { + if (switchObserver != nullptr) { + serviceAgent->AddSwitchCallback(switchAppId_, switchObserver); + } + return true; + }); +} + +void SwitchObserverBridge::RestartRegisterTimer() +{ + registerRetryCount_ ++; + ZLOGI("restart register timer, appId is :%{public}s, observers size is %{public}zu, retry count_ is %{public}d", + switchAppId_.appId.c_str(), switchObservers_.Size(), registerRetryCount_.load()); + taskId_ = TaskExecutor::GetInstance().Schedule(std::chrono::milliseconds(INTERVAL), [this]() { + RegisterSwitchObserver(); + }); +} +} // namespace OHOS::DistributedKv \ No newline at end of file diff --git a/frameworks/innerkitsimpl/distributeddatafwk/test/BUILD.gn b/frameworks/innerkitsimpl/distributeddatafwk/test/BUILD.gn index dc43f1adaec3661e4aca8ee8ffeac88b88c058ba..ff6ea43c120c60fe9ab2d8b2e9d821110241038f 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/test/BUILD.gn +++ b/frameworks/innerkitsimpl/distributeddatafwk/test/BUILD.gn @@ -13,12 +13,14 @@ import("//build/test.gni") import("//foundation/distributeddatamgr/kv_store/kv_store.gni") -module_output_path = "kv_store/distributeddatafwk" +module_output_path = "kv_store/kv_store/distributeddatafwk" ############################################################################### config("module_private_config") { visibility = [ ":*" ] + cflags = [ "-Wno-c99-designator" ] + include_dirs = [ "../include/", "../src/", @@ -30,13 +32,7 @@ config("module_private_config") { "../../../../interfaces/innerkits/distributeddatamgr/include/", # for ipc_core interfaces. - "//commonlibrary/c_utils/base/include", - "//foundation/distributeddatamgr/data_share/interfaces/inner_api/common/include", - "//foundation/distributeddatamgr/data_share/interfaces/inner_api/provider/include", "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata/include", - "//foundation/distributeddatamgr/distributedfile/interfaces/kits/js/src/mod_securitylabel", - "//foundation/distributedhardware/device_manager/interfaces/inner_kits/native_cpp/include", - "//base/hiviewdfx/hitrace/interfaces/native/innerkits/include", ] } @@ -45,31 +41,34 @@ ohos_source_set("distributeddatafwk_src_file") { testonly = true old_sources = [ + "../../distributeddatasvc/src/datamgr_service_proxy.cpp", + "../../distributeddatasvc/src/distributed_data_mgr.cpp", + "../../distributeddatasvc/src/kvstore_data_service_mgr.cpp", "../src/blob.cpp", "../src/change_notification.cpp", "../src/data_query.cpp", "../src/distributed_kv_data_manager.cpp", "../src/ikvstore_client_death_observer.cpp", "../src/ikvstore_observer.cpp", - "../src/ikvstore_sync_callback.cpp", "../src/kv_utils.cpp", + "../src/kvdb_notifier_client.cpp", + "../src/kvdb_notifier_stub.cpp", "../src/kvstore_client_death_observer.cpp", "../src/kvstore_datashare_bridge.cpp", "../src/kvstore_observer_client.cpp", "../src/kvstore_service_death_notifier.cpp", - "../src/kvstore_sync_callback_client.cpp", + "../src/switch_observer_bridge.cpp", "../src/sync_observer.cpp", ] kvdb_sources = [ - "../../kvdb/src/auto_sync_timer.cpp", "../../kvdb/src/backup_manager.cpp", "../../kvdb/src/convertor.cpp", - "../../kvdb/src/dev_manager.cpp", - "../../kvdb/src/device_convertor.cpp", "../../kvdb/src/kv_types_util.cpp", "../../kvdb/src/kvdb_service_client.cpp", "../../kvdb/src/observer_bridge.cpp", + "../../kvdb/src/process_communication_impl.cpp", + "../../kvdb/src/process_system_api_adapter_impl.cpp", "../../kvdb/src/security_manager.cpp", "../../kvdb/src/single_store_impl.cpp", "../../kvdb/src/store_factory.cpp", @@ -85,12 +84,15 @@ ohos_source_set("distributeddatafwk_src_file") { configs = [ ":module_private_config" ] deps = [ + "../../../../databaseutils:database_utils", "../../../../interfaces/innerkits/distributeddatamgr:distributeddata_mgr", "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb:distributeddb", - "//foundation/distributedhardware/device_manager/interfaces/inner_kits/native_cpp:devicemanagersdk", ] external_deps = [ + "access_token:libaccesstoken_sdk", + "access_token:libtokenid_sdk", "c_utils:utils", + "file_api:securitylabel", "hilog:libhilog", "hisysevent:libhisysevent", "hitrace:hitrace_meter", @@ -100,18 +102,67 @@ ohos_source_set("distributeddatafwk_src_file") { "samgr:samgr_proxy", ] + if (dms_service_enable && qemu_disable) { + sources += [ "${kv_store_base_path}/frameworks/innerkitsimpl/kvdb/src/auto_sync_timer.cpp" ] + external_deps += [ "dmsfwk:distributed_sdk" ] + } else { + sources += [ "${kv_store_base_path}/frameworks/innerkitsimpl/kvdb/src/auto_sync_timer_mock.cpp" ] + } + if (dm_service_enable) { + sources += [ + "${kv_store_base_path}/frameworks/innerkitsimpl/kvdb/src/dev_manager.cpp", + "${kv_store_base_path}/frameworks/innerkitsimpl/kvdb/src/device_convertor.cpp", + ] + external_deps += [ "device_manager:devicemanagersdk" ] + } else { + sources += [ + "${kv_store_base_path}/frameworks/innerkitsimpl/kvdb/src/dev_manager_mock.cpp", + "${kv_store_base_path}/frameworks/innerkitsimpl/kvdb/src/device_convertor_mock.cpp", + ] + } + + public_external_deps = [ + "data_share:datashare_common", + "data_share:datashare_provider", + ] + subsystem_name = "distributeddatamgr" part_name = "kv_store" } +ohos_unittest("DistributedKvDataManagerMultiUserTest") { + module_out_path = module_output_path + + sources = [ + "../../kvdb/src/kv_hiview_reporter_mock.cpp", + "unittest/distributed_kv_data_manager_multi_user_test.cpp", + ] + + configs = [ ":module_private_config" ] + + external_deps = [ + "c_utils:utils", + "googletest:gtest_main", + "hilog:libhilog", + "ipc:ipc_single", + "samgr:samgr_proxy", + ] + + deps = [ ":distributeddatafwk_src_file" ] +} + ohos_unittest("DistributedKvDataManagerTest") { module_out_path = module_output_path - sources = [ "unittest/distributed_kv_data_manager_test.cpp" ] + sources = [ + "../../kvdb/src/kv_hiview_reporter_mock.cpp", + "unittest/distributed_kv_data_manager_test.cpp", + ] configs = [ ":module_private_config" ] external_deps = [ "c_utils:utils", + "googletest:gtest_main", "hilog:libhilog", "ipc:ipc_single", "samgr:samgr_proxy", @@ -119,19 +170,22 @@ ohos_unittest("DistributedKvDataManagerTest") { deps = [ ":distributeddatafwk_src_file", - "//third_party/googletest:gtest_main", ] } ohos_unittest("DistributedKvDataManagerEncryptTest") { module_out_path = module_output_path - sources = [ "unittest/distributed_kv_data_manager_encrypt_test.cpp" ] + sources = [ + "../../kvdb/src/kv_hiview_reporter_mock.cpp", + "unittest/distributed_kv_data_manager_encrypt_test.cpp", + ] configs = [ ":module_private_config" ] external_deps = [ "c_utils:utils", + "googletest:gtest", "hilog:libhilog", "ipc:ipc_single", "samgr:samgr_proxy", @@ -139,20 +193,22 @@ ohos_unittest("DistributedKvDataManagerEncryptTest") { deps = [ ":distributeddatafwk_src_file", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter:distributeddata_adapter", - "//third_party/googletest:gtest_main", ] } ohos_unittest("LocalSubscribeStoreTest") { module_out_path = module_output_path - sources = [ "unittest/local_subscribe_store_test.cpp" ] + sources = [ + "../../kvdb/src/kv_hiview_reporter_mock.cpp", + "unittest/local_subscribe_store_test.cpp", + ] configs = [ ":module_private_config" ] external_deps = [ "c_utils:utils", + "googletest:gtest", "hilog:libhilog", "ipc:ipc_single", "samgr:samgr_proxy", @@ -160,20 +216,22 @@ ohos_unittest("LocalSubscribeStoreTest") { deps = [ ":distributeddatafwk_src_file", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter:distributeddata_adapter", - "//third_party/googletest:gtest_main", ] } ohos_unittest("LocalSubscribeDeviceStoreTest") { module_out_path = module_output_path - sources = [ "unittest/local_subscribe_device_store_test.cpp" ] + sources = [ + "../../kvdb/src/kv_hiview_reporter_mock.cpp", + "unittest/local_subscribe_device_store_test.cpp", + ] configs = [ ":module_private_config" ] external_deps = [ "c_utils:utils", + "googletest:gtest", "hilog:libhilog", "ipc:ipc_single", "samgr:samgr_proxy", @@ -181,20 +239,22 @@ ohos_unittest("LocalSubscribeDeviceStoreTest") { deps = [ ":distributeddatafwk_src_file", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter:distributeddata_adapter", - "//third_party/googletest:gtest_main", ] } ohos_unittest("SingleKvStoreClientQueryTest") { module_out_path = module_output_path - sources = [ "unittest/single_kvstore_client_query_test.cpp" ] + sources = [ + "../../kvdb/src/kv_hiview_reporter_mock.cpp", + "unittest/single_kvstore_client_query_test.cpp", + ] configs = [ ":module_private_config" ] external_deps = [ "c_utils:utils", + "googletest:gtest", "hilog:libhilog", "ipc:ipc_single", "samgr:samgr_proxy", @@ -202,20 +262,45 @@ ohos_unittest("SingleKvStoreClientQueryTest") { deps = [ ":distributeddatafwk_src_file", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter:distributeddata_adapter", - "//third_party/googletest:gtest_main", ] } ohos_unittest("SingleKvStoreClientTest") { module_out_path = module_output_path - sources = [ "unittest/single_kvstore_client_test.cpp" ] + sources = [ + "../../kvdb/src/kv_hiview_reporter_mock.cpp", + "unittest/single_kvstore_client_test.cpp", + ] + + configs = [ ":module_private_config" ] + + external_deps = [ + "c_utils:utils", + "googletest:gtest", + "hilog:libhilog", + "ipc:ipc_single", + "samgr:samgr_proxy", + ] + + deps = [ + ":distributeddatafwk_src_file", + ] +} + +ohos_unittest("SingleKvStoreAsyncGetTest") { + module_out_path = module_output_path + + sources = [ + "../../kvdb/src/kv_hiview_reporter_mock.cpp", + "unittest/single_kvstore_async_get_test.cpp", + ] configs = [ ":module_private_config" ] external_deps = [ "c_utils:utils", + "googletest:gtest", "hilog:libhilog", "ipc:ipc_single", "samgr:samgr_proxy", @@ -223,20 +308,22 @@ ohos_unittest("SingleKvStoreClientTest") { deps = [ ":distributeddatafwk_src_file", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter:distributeddata_adapter", - "//third_party/googletest:gtest_main", ] } ohos_unittest("DeviceKvStoreTest") { module_out_path = module_output_path - sources = [ "unittest/device_kvstore_test.cpp" ] + sources = [ + "../../kvdb/src/kv_hiview_reporter_mock.cpp", + "unittest/device_kvstore_test.cpp", + ] configs = [ ":module_private_config" ] external_deps = [ "c_utils:utils", + "googletest:gtest", "hilog:libhilog", "ipc:ipc_single", "samgr:samgr_proxy", @@ -244,26 +331,27 @@ ohos_unittest("DeviceKvStoreTest") { deps = [ ":distributeddatafwk_src_file", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter:distributeddata_adapter", - "//third_party/googletest:gtest_main", ] } ohos_unittest("BlobTest") { module_out_path = module_output_path - sources = [ "unittest/blob_test.cpp" ] + sources = [ + "../../kvdb/src/kv_hiview_reporter_mock.cpp", + "unittest/blob_test.cpp", + ] configs = [ ":module_private_config" ] deps = [ ":distributeddatafwk_src_file", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter:distributeddata_adapter", - "//third_party/googletest:gtest_main", ] external_deps = [ "c_utils:utils", + "googletest:gtest", + "hilog:libhilog", "ipc:ipc_single", ] } @@ -271,18 +359,21 @@ ohos_unittest("BlobTest") { ohos_unittest("TypesUtilTest") { module_out_path = module_output_path - sources = [ "unittest/types_util_test.cpp" ] + sources = [ + "../../kvdb/src/kv_hiview_reporter_mock.cpp", + "unittest/types_util_test.cpp", + ] configs = [ ":module_private_config" ] deps = [ ":distributeddatafwk_src_file", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter:distributeddata_adapter", - "//third_party/googletest:gtest_main", ] external_deps = [ "c_utils:utils", + "googletest:gtest", + "hilog:libhilog", "ipc:ipc_single", ] } @@ -290,18 +381,21 @@ ohos_unittest("TypesUtilTest") { ohos_unittest("KvUtilTest") { module_out_path = module_output_path - sources = [ "unittest/kv_utils_test.cpp" ] + sources = [ + "../../kvdb/src/kv_hiview_reporter_mock.cpp", + "unittest/kv_utils_test.cpp", + ] configs = [ ":module_private_config" ] deps = [ ":distributeddatafwk_src_file", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter:distributeddata_adapter", - "//third_party/googletest:gtest_main", ] external_deps = [ "c_utils:utils", + "googletest:gtest", + "hilog:libhilog", "ipc:ipc_single", ] } @@ -309,22 +403,101 @@ ohos_unittest("KvUtilTest") { ohos_unittest("KvstoreDatashareBridgeTest") { module_out_path = module_output_path - sources = [ "unittest/kvstore_datashare_bridge_test.cpp" ] + sources = [ + "../../kvdb/src/kv_hiview_reporter_mock.cpp", + "unittest/kvstore_datashare_bridge_test.cpp", + ] configs = [ ":module_private_config" ] deps = [ ":distributeddatafwk_src_file", - "//foundation/distributeddatamgr/datamgr_service/services/distributeddataservice/adapter:distributeddata_adapter", - "//third_party/googletest:gtest_main", ] external_deps = [ "c_utils:utils", + "googletest:gtest", + "hilog:libhilog", "ipc:ipc_single", ] } +ohos_unittest("DistributedDataMgrTest") { + module_out_path = module_output_path + + sources = [ + "../../kvdb/src/kv_hiview_reporter_mock.cpp", + "unittest/distributed_data_mgr_test.cpp", + ] + + configs = [ ":module_private_config" ] + + external_deps = [ + "access_token:libaccesstoken_sdk", + "access_token:libnativetoken", + "access_token:libtoken_setproc", + "c_utils:utils", + "googletest:gtest", + "hilog:libhilog", + "ipc:ipc_single", + "samgr:samgr_proxy", + ] + + deps = [ + ":distributeddatafwk_src_file", + ] +} + +ohos_unittest("EndPointTest") { + module_out_path = module_output_path + + sources = [ + "../../kvdb/src/kv_hiview_reporter_mock.cpp", + "unittest/end_point_test.cpp", + ] + + configs = [ ":module_private_config" ] + + external_deps = [ + "c_utils:utils", + "googletest:gtest", + "hilog:libhilog", + "ipc:ipc_single", + "samgr:samgr_proxy", + ] + + deps = [ + ":distributeddatafwk_src_file", + ] +} + +ohos_unittest("SwitchObserverBridgeTest") { + module_out_path = module_output_path + + sources = [ + "../../kvdb/src/kv_hiview_reporter_mock.cpp", + "unittest/switch_observer_bridge_test.cpp", + ] + + configs = [ ":module_private_config" ] + + external_deps = [ + "c_utils:utils", + "googletest:gtest", + "hilog:libhilog", + "ipc:ipc_single", + "samgr:samgr_proxy", + ] + + cflags = [ + "-Dprivate=public", + ] + + deps = [ + ":distributeddatafwk_src_file", + ] +} + ############################################################################### group("unittest") { testonly = true @@ -333,15 +506,25 @@ group("unittest") { deps += [ ":BlobTest", - ":DeviceKvStoreTest", + ":DistributedDataMgrTest", ":DistributedKvDataManagerEncryptTest", - ":DistributedKvDataManagerTest", + ":DistributedKvDataManagerMultiUserTest", + ":EndPointTest", ":KvUtilTest", ":KvstoreDatashareBridgeTest", ":LocalSubscribeDeviceStoreTest", ":LocalSubscribeStoreTest", ":SingleKvStoreClientQueryTest", ":SingleKvStoreClientTest", + ":SwitchObserverBridgeTest", ":TypesUtilTest", ] + + if (dm_service_enable) { + deps += [ + ":DeviceKvStoreTest", + ":DistributedKvDataManagerTest", + ":SingleKvStoreAsyncGetTest" + ] + } } diff --git a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/blob_test.cpp b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/blob_test.cpp index f4bdaff333808624e067a641f34edf077be981de..df64ec8b5e8cb5156bd463865fee060493bef6b5 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/blob_test.cpp +++ b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/blob_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 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,11 +13,11 @@ * limitations under the License. */ -#include +#include "kv_types_util.h" +#include "types.h" #include +#include #include -#include "types.h" -#include "kv_types_util.h" using namespace testing::ext; using namespace OHOS::DistributedKv; using namespace OHOS; @@ -30,25 +30,21 @@ public: void TearDown(); }; -void BlobTest::SetUpTestCase(void) -{} +void BlobTest::SetUpTestCase(void) { } -void BlobTest::TearDownTestCase(void) -{} +void BlobTest::TearDownTestCase(void) { } -void BlobTest::SetUp(void) -{} +void BlobTest::SetUp(void) { } -void BlobTest::TearDown(void) -{} +void BlobTest::TearDown(void) { } /** -* @tc.name: Size001 -* @tc.desc: construct a Blob and check its size. -* @tc.type: FUNC -* @tc.require: AR000C6GBG -* @tc.author: liqiao -*/ + * @tc.name: Size001 + * @tc.desc: construct a Blob and check its size. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liqiao + */ HWTEST_F(BlobTest, Size001, TestSize.Level0) { Blob blob1; @@ -60,7 +56,7 @@ HWTEST_F(BlobTest, Size001, TestSize.Level0) std::string strTmp = "123"; Blob blob4(strTmp.c_str()); EXPECT_EQ(blob4.Size(), (size_t)3); - std::vector vec = {'1', '2', '3', '4'}; + std::vector vec = { '1', '2', '3', '4' }; Blob blob5(vec); EXPECT_EQ(blob5.Size(), (size_t)4); const char *chr1 = strTmp.c_str(); @@ -73,12 +69,12 @@ HWTEST_F(BlobTest, Size001, TestSize.Level0) } /** -* @tc.name: Empty001 -* @tc.desc: construct a Blob and check its empty. -* @tc.type: FUNC -* @tc.require: AR000C6GBG -* @tc.author: liqiao -*/ + * @tc.name: Empty001 + * @tc.desc: construct a Blob and check its empty. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liqiao + */ HWTEST_F(BlobTest, Empty001, TestSize.Level0) { Blob blob1; @@ -90,7 +86,7 @@ HWTEST_F(BlobTest, Empty001, TestSize.Level0) std::string strTmp = "123"; Blob blob4(strTmp.c_str()); EXPECT_EQ(blob4.Empty(), false); - std::vector vec = {'1', '2', '3', '4'}; + std::vector vec = { '1', '2', '3', '4' }; Blob blob5(vec); EXPECT_EQ(blob5.Empty(), false); const char *chr1 = strTmp.c_str(); @@ -99,12 +95,12 @@ HWTEST_F(BlobTest, Empty001, TestSize.Level0) } /** -* @tc.name: Clear001 -* @tc.desc: construct a Blob and check it clear function. -* @tc.type: FUNC -* @tc.require: AR000C6GBG -* @tc.author: liqiao -*/ + * @tc.name: Clear001 + * @tc.desc: construct a Blob and check it clear function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liqiao + */ HWTEST_F(BlobTest, Clear001, TestSize.Level0) { Blob blob1 = "1234567890"; @@ -118,19 +114,19 @@ HWTEST_F(BlobTest, Clear001, TestSize.Level0) Blob blob3(chr); blob3.Clear(); EXPECT_EQ(blob3.Empty(), true); - std::vector vec = {'1', '2', '3', '4'}; + std::vector vec = { '1', '2', '3', '4' }; Blob blob4(vec); blob4.Clear(); EXPECT_EQ(blob4.Empty(), true); } /** -* @tc.name: StartsWith001 -* @tc.desc: construct a Blob and check it StartsWith function. -* @tc.type: FUNC -* @tc.require: AR000C6GBG -* @tc.author: liqiao -*/ + * @tc.name: StartsWith001 + * @tc.desc: construct a Blob and check it StartsWith function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liqiao + */ HWTEST_F(BlobTest, StartsWith001, TestSize.Level0) { Blob blob1 = "1234567890"; @@ -143,12 +139,12 @@ HWTEST_F(BlobTest, StartsWith001, TestSize.Level0) } /** -* @tc.name: Compare001 -* @tc.desc: construct a Blob and check it compare function. -* @tc.type: FUNC -* @tc.require: AR000C6GBG -* @tc.author: liqiao -*/ + * @tc.name: Compare001 + * @tc.desc: construct a Blob and check it compare function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liqiao + */ HWTEST_F(BlobTest, Compare001, TestSize.Level0) { Blob blob1 = "1234567890"; @@ -160,29 +156,29 @@ HWTEST_F(BlobTest, Compare001, TestSize.Level0) } /** -* @tc.name: Data001 -* @tc.desc: construct a Blob and check it Data function. -* @tc.type: FUNC -* @tc.require: AR000C6GBG -* @tc.author: liqiao -*/ + * @tc.name: Data001 + * @tc.desc: construct a Blob and check it Data function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liqiao + */ HWTEST_F(BlobTest, Data001, TestSize.Level0) { - std::vector result = {'1', '2', '3', '4'}; + std::vector result = { '1', '2', '3', '4' }; Blob blob1("1234"); EXPECT_EQ(blob1.Data(), result); - std::vector result2 = {'1', '2', '3', '4', '5'}; + std::vector result2 = { '1', '2', '3', '4', '5' }; Blob blob2("12345"); EXPECT_EQ(blob2.Data(), result2); } /** -* @tc.name: ToString001 -* @tc.desc: construct a Blob and check it ToString function. -* @tc.type: FUNC -* @tc.require: AR000C6GBG -* @tc.author: liqiao -*/ + * @tc.name: ToString001 + * @tc.desc: construct a Blob and check it ToString function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liqiao + */ HWTEST_F(BlobTest, ToString001, TestSize.Level0) { Blob blob1("1234"); @@ -191,12 +187,12 @@ HWTEST_F(BlobTest, ToString001, TestSize.Level0) } /** -* @tc.name: OperatorEqual001 -* @tc.desc: construct a Blob and check it operator== function. -* @tc.type: FUNC -* @tc.require: AR000C6GBG -* @tc.author: liqiao -*/ + * @tc.name: OperatorEqual001 + * @tc.desc: construct a Blob and check it operator== function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liqiao + */ HWTEST_F(BlobTest, OperatorEqual001, TestSize.Level0) { Blob blob1("1234"); @@ -207,12 +203,12 @@ HWTEST_F(BlobTest, OperatorEqual001, TestSize.Level0) } /** -* @tc.name: Operator001 -* @tc.desc: construct a Blob and check it operator[] function. -* @tc.type: FUNC -* @tc.require: AR000C6GBG -* @tc.author: liqiao -*/ + * @tc.name: Operator001 + * @tc.desc: construct a Blob and check it operator[] function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liqiao + */ HWTEST_F(BlobTest, Operator001, TestSize.Level0) { Blob blob1("1234"); @@ -224,12 +220,12 @@ HWTEST_F(BlobTest, Operator001, TestSize.Level0) } /** -* @tc.name: Operator002 -* @tc.desc: construct a Blob and check it operator= function. -* @tc.type: FUNC -* @tc.require: AR000C6GBG -* @tc.author: liqiao -*/ + * @tc.name: Operator002 + * @tc.desc: construct a Blob and check it operator= function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liqiao + */ HWTEST_F(BlobTest, Operator002, TestSize.Level0) { Blob blob1("1234"); @@ -239,12 +235,12 @@ HWTEST_F(BlobTest, Operator002, TestSize.Level0) } /** -* @tc.name: Operator003 -* @tc.desc: construct a Blob and check it operator= function. -* @tc.type: FUNC -* @tc.require: AR000C6GBG -* @tc.author: liqiao -*/ + * @tc.name: Operator003 + * @tc.desc: construct a Blob and check it operator= function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: liqiao + */ HWTEST_F(BlobTest, Operator003, TestSize.Level0) { Blob blob1("1234"); @@ -255,12 +251,12 @@ HWTEST_F(BlobTest, Operator003, TestSize.Level0) } /** -* @tc.name: Operator004 -* @tc.desc: construct a Blob and check it operator std::vector && function. -* @tc.type: FUNC -* @tc.require: -* @tc.author: wangkai -*/ + * @tc.name: Operator004 + * @tc.desc: construct a Blob and check it operator std::vector && function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: wangkai + */ HWTEST_F(BlobTest, Operator004, TestSize.Level0) { std::vector blob = { 1, 2, 3, 4 }; @@ -271,12 +267,12 @@ HWTEST_F(BlobTest, Operator004, TestSize.Level0) } /** -* @tc.name: Operator005 -* @tc.desc: construct a Blob and check it operator std::vector & function. -* @tc.type: FUNC -* @tc.require: -* @tc.author: wangkai -*/ + * @tc.name: Operator005 + * @tc.desc: construct a Blob and check it operator std::vector & function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: wangkai + */ HWTEST_F(BlobTest, Operator005, TestSize.Level0) { const std::vector blob = { 1, 2, 3, 4 }; @@ -285,12 +281,12 @@ HWTEST_F(BlobTest, Operator005, TestSize.Level0) } /** -* @tc.name: RawSize001 -* @tc.desc: construct a Blob and check it RawSize function. -* @tc.type: FUNC -* @tc.require: -* @tc.author: wangkai -*/ + * @tc.name: RawSize001 + * @tc.desc: construct a Blob and check it RawSize function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: wangkai + */ HWTEST_F(BlobTest, RawSize001, TestSize.Level0) { Blob blob1("1234"); @@ -300,12 +296,12 @@ HWTEST_F(BlobTest, RawSize001, TestSize.Level0) } /** -* @tc.name: WriteToBuffer001 -* @tc.desc: construct a Blob and check it WriteToBuffer and ReadFromBuffer function. -* @tc.type: FUNC -* @tc.require: -* @tc.author: wangkai -*/ + * @tc.name: WriteToBuffer001 + * @tc.desc: construct a Blob and check it WriteToBuffer and ReadFromBuffer function. + * @tc.type: FUNC + * @tc.require: + * @tc.author: wangkai + */ HWTEST_F(BlobTest, WriteToBuffer001, TestSize.Level1) { Entry insert, update, del; diff --git a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/device_kvstore_test.cpp b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/device_kvstore_test.cpp index fede017944d30b0bb1972578532f357f238c0fee..310cc6735e5d06118b0374296354b5c4c56fed11 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/device_kvstore_test.cpp +++ b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/device_kvstore_test.cpp @@ -13,35 +13,31 @@ * limitations under the License. */ -#include -#include -#include -#include -#include #include "dev_manager.h" #include "distributed_kv_data_manager.h" #include "file_ex.h" #include "types.h" +#include +#include +#include +#include +#include using namespace testing::ext; using namespace OHOS::DistributedKv; - +namespace OHOS::Test { +static constexpr uint64_t MAX_VALUE_SIZE = 4 * 1024 * 1024; // max value size is 4M. class DeviceKvStoreTest : public testing::Test { public: - static void SetUpTestCase(void); - - static void TearDownTestCase(void); - - void SetUp(); - - void TearDown(); static std::string GetKey(const std::string &key); - static std::shared_ptr kvStore_; // declare kvstore instance. static Status status_; static std::string deviceId_; static Options options_; - static const int MAX_VALUE_SIZE = 4 * 1024 * 1024; // max value size is 4M.; + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); }; const std::string VALID_SCHEMA = "{\"SCHEMA_VERSION\":\"1.0\"," @@ -82,13 +78,11 @@ void DeviceKvStoreTest::TearDownTestCase(void) (void)remove("/data/service/el1/public/database/odmf"); } -void DeviceKvStoreTest::SetUp(void) -{} +void DeviceKvStoreTest::SetUp(void) { } -void DeviceKvStoreTest::TearDown(void) -{} +void DeviceKvStoreTest::TearDown(void) { } -std::string DeviceKvStoreTest::GetKey(const std::string& key) +std::string DeviceKvStoreTest::GetKey(const std::string &key) { std::ostringstream oss; oss << std::setfill('0') << std::setw(sizeof(uint32_t)) << deviceId_.length(); @@ -103,8 +97,7 @@ public: std::vector deleteEntries_; bool isClear_ = false; DeviceObserverTestImpl(); - ~DeviceObserverTestImpl() - {} + ~DeviceObserverTestImpl() { } DeviceObserverTestImpl(const DeviceObserverTestImpl &) = delete; DeviceObserverTestImpl &operator=(const DeviceObserverTestImpl &) = delete; @@ -131,9 +124,7 @@ void DeviceObserverTestImpl::OnChange(const ChangeNotification &changeNotificati isClear_ = changeNotification.IsClear(); } -DeviceObserverTestImpl::DeviceObserverTestImpl() -{ -} +DeviceObserverTestImpl::DeviceObserverTestImpl() { } void DeviceObserverTestImpl::ResetToZero() { @@ -150,16 +141,15 @@ public: void SyncCompleted(const std::map &results); }; -void DeviceSyncCallbackTestImpl::SyncCompleted(const std::map &results) -{} +void DeviceSyncCallbackTestImpl::SyncCompleted(const std::map &results) { } /** -* @tc.name: GetStoreId001 -* @tc.desc: Get a Device KvStore instance. -* @tc.type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang -*/ + * @tc.name: GetStoreId001 + * @tc.desc: Get a Device KvStore instance. + * @tc.type: FUNC + * @tc.require: I5DE2A + * @tc.author: Sven Wang + */ HWTEST_F(DeviceKvStoreTest, GetStoreId001, TestSize.Level1) { EXPECT_NE(kvStore_, nullptr) << "kvStore is null."; @@ -169,18 +159,18 @@ HWTEST_F(DeviceKvStoreTest, GetStoreId001, TestSize.Level1) } /** -* @tc.name: PutGetDelete001 -* @tc.desc: put value and delete value -* @tc.type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang -*/ + * @tc.name: PutGetDelete001 + * @tc.desc: put value and delete value + * @tc.type: FUNC + * @tc.require: I5DE2A + * @tc.author: Sven Wang + */ HWTEST_F(DeviceKvStoreTest, PutGetDelete001, TestSize.Level1) { EXPECT_NE(kvStore_, nullptr) << "kvStore is null."; - Key skey = {"single_001"}; - Value sval = {"value_001"}; + Key skey = { "single_001" }; + Value sval = { "value_001" }; auto status = kvStore_->Put(skey, sval); EXPECT_EQ(status, Status::SUCCESS) << "Put data failed"; @@ -190,28 +180,28 @@ HWTEST_F(DeviceKvStoreTest, PutGetDelete001, TestSize.Level1) auto notExistStatus = kvStore_->Delete(skey); EXPECT_EQ(notExistStatus, Status::SUCCESS) << "Delete non-existing data failed"; - auto spaceStatus = kvStore_->Put(skey, {""}); + auto spaceStatus = kvStore_->Put(skey, { "" }); EXPECT_EQ(spaceStatus, Status::SUCCESS) << "Put space failed"; - auto spaceKeyStatus = kvStore_->Put({""}, {""}); + auto spaceKeyStatus = kvStore_->Put({ "" }, { "" }); EXPECT_NE(spaceKeyStatus, Status::SUCCESS) << "Put space keys failed"; Status validStatus = kvStore_->Put(skey, sval); EXPECT_EQ(validStatus, Status::SUCCESS) << "Put valid keys and values failed"; Value rVal; - auto validPutStatus = kvStore_->Get({ GetKey("single_001")}, rVal); + auto validPutStatus = kvStore_->Get({ GetKey("single_001") }, rVal); EXPECT_EQ(validPutStatus, Status::SUCCESS) << "Get value failed"; EXPECT_EQ(sval, rVal) << "Got and put values not equal"; } /** -* @tc.name: GetDataQueryEntriesAndResultSet -* @tc.desc: get entries and result set by data query. -* @tc.type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang -*/ + * @tc.name: GetDataQueryEntriesAndResultSet + * @tc.desc: get entries and result set by data query. + * @tc.type: FUNC + * @tc.require: I5DE2A + * @tc.author: Sven Wang + */ HWTEST_F(DeviceKvStoreTest, GetDataQueryEntriesAndResultSet, TestSize.Level1) { EXPECT_NE(kvStore_, nullptr) << "kvStore is nullptr."; @@ -221,7 +211,7 @@ HWTEST_F(DeviceKvStoreTest, GetDataQueryEntriesAndResultSet, TestSize.Level1) int sumGet = 0; std::string prefix = "prefix_"; for (size_t i = 0; i < sum; i++) { - kvStore_->Put({prefix + std::to_string(i)}, {std::to_string(i)}); + kvStore_->Put({ prefix + std::to_string(i) }, { std::to_string(i) }); } DataQuery dataQuery; @@ -252,7 +242,7 @@ HWTEST_F(DeviceKvStoreTest, GetDataQueryEntriesAndResultSet, TestSize.Level1) resultSet->GetEntry(entry); for (size_t i = 0; i < sum; i++) { - kvStore_->Delete({GetKey(prefix + std::to_string(i))}); + kvStore_->Delete({ GetKey(prefix + std::to_string(i)) }); } status = kvStore_->CloseResultSet(resultSet); @@ -260,12 +250,12 @@ HWTEST_F(DeviceKvStoreTest, GetDataQueryEntriesAndResultSet, TestSize.Level1) } /** -* @tc.name: GetPrefixQueryEntriesAndResultSet -* @tc.desc: get entries and result set by prefix query. -* @tc.type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang -*/ + * @tc.name: GetPrefixQueryEntriesAndResultSet + * @tc.desc: get entries and result set by prefix query. + * @tc.type: FUNC + * @tc.require: I5DE2A + * @tc.author: Sven Wang + */ HWTEST_F(DeviceKvStoreTest, GetPrefixQueryEntriesAndResultSet, TestSize.Level1) { EXPECT_NE(kvStore_, nullptr) << "kvStore is nullptr."; @@ -277,7 +267,7 @@ HWTEST_F(DeviceKvStoreTest, GetPrefixQueryEntriesAndResultSet, TestSize.Level1) size_t sum = 10; std::string prefix = "prefix_"; for (size_t i = 0; i < sum; i++) { - kvStore_->Put({prefix + std::to_string(i)}, {std::to_string(i)}); + kvStore_->Put({ prefix + std::to_string(i) }, { std::to_string(i) }); } DataQuery dataQuery; @@ -308,7 +298,7 @@ HWTEST_F(DeviceKvStoreTest, GetPrefixQueryEntriesAndResultSet, TestSize.Level1) resultSet->GetEntry(entry); for (size_t i = 0; i < sum; i++) { - kvStore_->Delete({GetKey(prefix + std::to_string(i))}); + kvStore_->Delete({ GetKey(prefix + std::to_string(i)) }); } status = kvStore_->CloseResultSet(resultSet); @@ -316,12 +306,12 @@ HWTEST_F(DeviceKvStoreTest, GetPrefixQueryEntriesAndResultSet, TestSize.Level1) } /** -* @tc.name: GetInKeysQueryResultSet -* @tc.desc: get entries and result set by prefix query. -* @tc.type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang -*/ + * @tc.name: GetInKeysQueryResultSet + * @tc.desc: get entries and result set by prefix query. + * @tc.type: FUNC + * @tc.require: I5DE2A + * @tc.author: Sven Wang + */ HWTEST_F(DeviceKvStoreTest, GetInKeysQueryResultSet, TestSize.Level1) { EXPECT_NE(kvStore_, nullptr) << "kvStore is nullptr."; @@ -334,11 +324,11 @@ HWTEST_F(DeviceKvStoreTest, GetInKeysQueryResultSet, TestSize.Level1) std::string prefix = "prefix_"; for (size_t i = 0; i < sum; i++) { - kvStore_->Put({prefix + std::to_string(i)}, {std::to_string(i)}); + kvStore_->Put({ prefix + std::to_string(i) }, { std::to_string(i) }); } DataQuery dataQuery; - dataQuery.InKeys({"prefix_0", "prefix_1", "prefix_3", "prefix_9"}); + dataQuery.InKeys({ "prefix_0", "prefix_1", "prefix_3", "prefix_9" }); int sumGet = 0; kvStore_->GetCount(dataQuery, sumGet); EXPECT_EQ(sumGet, 4) << "count is not equal 4."; @@ -361,7 +351,7 @@ HWTEST_F(DeviceKvStoreTest, GetInKeysQueryResultSet, TestSize.Level1) resultSet->GetEntry(entry); for (size_t i = 0; i < sum; i++) { - kvStore_->Delete({GetKey(prefix + std::to_string(i))}); + kvStore_->Delete({ GetKey(prefix + std::to_string(i)) }); } status = kvStore_->CloseResultSet(resultSet); @@ -369,12 +359,12 @@ HWTEST_F(DeviceKvStoreTest, GetInKeysQueryResultSet, TestSize.Level1) } /** -* @tc.name: GetPrefixEntriesAndResultSet -* @tc.desc: get entries and result set by prefix. -* @tc.type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang -*/ + * @tc.name: GetPrefixEntriesAndResultSet + * @tc.desc: get entries and result set by prefix. + * @tc.type: FUNC + * @tc.require: I5DE2A + * @tc.author: Sven Wang + */ HWTEST_F(DeviceKvStoreTest, GetPrefixEntriesAndResultSet, TestSize.Level1) { EXPECT_NE(kvStore_, nullptr) << "kvStore is nullptr."; @@ -384,7 +374,7 @@ HWTEST_F(DeviceKvStoreTest, GetPrefixEntriesAndResultSet, TestSize.Level1) int sumGet = 10; std::string prefix = "prefix_"; for (size_t i = 0; i < sum; i++) { - kvStore_->Put({prefix + std::to_string(i)}, {std::to_string(i)}); + kvStore_->Put({ prefix + std::to_string(i) }, { std::to_string(i) }); } std::vector results; kvStore_->GetEntries(GetKey(prefix + " "), results); @@ -408,7 +398,7 @@ HWTEST_F(DeviceKvStoreTest, GetPrefixEntriesAndResultSet, TestSize.Level1) resultSet->GetEntry(entry); for (size_t i = 0; i < sum; i++) { - kvStore_->Delete({GetKey(prefix + std::to_string(i))}); + kvStore_->Delete({ GetKey(prefix + std::to_string(i)) }); } status = kvStore_->CloseResultSet(resultSet); @@ -416,12 +406,12 @@ HWTEST_F(DeviceKvStoreTest, GetPrefixEntriesAndResultSet, TestSize.Level1) } /** -* @tc.name: Subscribe001 -* @tc.desc: Put data and get callback. -* @tc.type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang -*/ + * @tc.name: Subscribe001 + * @tc.desc: Put data and get callback. + * @tc.type: FUNC + * @tc.require: I5DE2A + * @tc.author: Sven Wang + */ HWTEST_F(DeviceKvStoreTest, Subscribe001, TestSize.Level1) { auto observer = std::make_shared(); @@ -436,12 +426,12 @@ HWTEST_F(DeviceKvStoreTest, Subscribe001, TestSize.Level1) } /** -* @tc.name: SyncCallback001 -* @tc.desc: Register sync callback. -* @tc.type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang -*/ + * @tc.name: SyncCallback001 + * @tc.desc: Register sync callback. + * @tc.type: FUNC + * @tc.require: I5DE2A + * @tc.author: Sven Wang + */ HWTEST_F(DeviceKvStoreTest, SyncCallback001, TestSize.Level1) { EXPECT_NE(kvStore_, nullptr) << "kvStore is nullptr."; @@ -453,34 +443,34 @@ HWTEST_F(DeviceKvStoreTest, SyncCallback001, TestSize.Level1) auto unRegStatus = kvStore_->UnRegisterSyncCallback(); EXPECT_EQ(unRegStatus, Status::SUCCESS) << "Unregister sync callback failed."; - Key skey = {"single_001"}; - Value sval = {"value_001"}; + Key skey = { "single_001" }; + Value sval = { "value_001" }; kvStore_->Put(skey, sval); kvStore_->Delete(skey); std::map results; - results.insert({"aaa", Status::INVALID_ARGUMENT}); + results.insert({ "aaa", Status::INVALID_ARGUMENT }); syncCallback->SyncCompleted(results); } /** -* @tc.name: RemoveDeviceData001 -* @tc.desc: Remove device data. -* @tc.type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang -*/ + * @tc.name: RemoveDeviceData001 + * @tc.desc: Remove device data. + * @tc.type: FUNC + * @tc.require: I5DE2A + * @tc.author: Sven Wang + */ HWTEST_F(DeviceKvStoreTest, RemoveDeviceData001, TestSize.Level1) { EXPECT_NE(kvStore_, nullptr) << "kvStore is nullptr."; - Key skey = {"single_001"}; - Value sval = {"value_001"}; + Key skey = { "single_001" }; + Value sval = { "value_001" }; kvStore_->Put(skey, sval); std::string deviceId = "no_exist_device_id"; auto removeStatus = kvStore_->RemoveDeviceData(deviceId); - EXPECT_NE(removeStatus, Status::SUCCESS) << "Remove device should not return success"; + EXPECT_EQ(removeStatus, Status::SUCCESS) << "Remove device should return success"; Value retVal; auto getRet = kvStore_->Get(GetKey(skey.ToString()), retVal); @@ -489,12 +479,12 @@ HWTEST_F(DeviceKvStoreTest, RemoveDeviceData001, TestSize.Level1) } /** -* @tc.name: SyncData001 -* @tc.desc: Synchronize device data. -* @tc.type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang -*/ + * @tc.name: SyncData001 + * @tc.desc: Synchronize device data. + * @tc.type: FUNC + * @tc.require: I5DE2A + * @tc.author: Sven Wang + */ HWTEST_F(DeviceKvStoreTest, SyncData001, TestSize.Level1) { EXPECT_NE(kvStore_, nullptr) << "kvStore is nullptr."; @@ -505,12 +495,12 @@ HWTEST_F(DeviceKvStoreTest, SyncData001, TestSize.Level1) } /** -* @tc.name: TestSchemaStoreC001 -* @tc.desc: Test schema device store. -* @tc.type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang -*/ + * @tc.name: TestSchemaStoreC001 + * @tc.desc: Test schema device store. + * @tc.type: FUNC + * @tc.require: I5DE2A + * @tc.author: Sven Wang + */ HWTEST_F(DeviceKvStoreTest, TestSchemaStoreC001, TestSize.Level1) { std::shared_ptr deviceKvStore; @@ -528,8 +518,8 @@ HWTEST_F(DeviceKvStoreTest, TestSchemaStoreC001, TestSize.Level1) auto result = deviceKvStore->GetStoreId(); EXPECT_EQ(result.storeId, "schema_device_id"); - Key testKey = {"TestSchemaStoreC001_key"}; - Value testValue = {"{\"age\":10}"}; + Key testKey = { "TestSchemaStoreC001_key" }; + Value testValue = { "{\"age\":10}" }; auto testStatus = deviceKvStore->Put(testKey, testValue); EXPECT_EQ(testStatus, Status::SUCCESS) << "putting data failed"; Value resultValue; @@ -539,12 +529,12 @@ HWTEST_F(DeviceKvStoreTest, TestSchemaStoreC001, TestSize.Level1) } /** -* @tc.name: SyncData001 -* @tc.desc: Synchronize device data. -* @tc.type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang -*/ + * @tc.name: SyncData001 + * @tc.desc: Synchronize device data. + * @tc.type: FUNC + * @tc.require: I5DE2A + * @tc.author: Sven Wang + */ HWTEST_F(DeviceKvStoreTest, SyncData002, TestSize.Level1) { EXPECT_NE(kvStore_, nullptr) << "kvStorePtr is null."; @@ -556,16 +546,16 @@ HWTEST_F(DeviceKvStoreTest, SyncData002, TestSize.Level1) } /** -* @tc.name: SyncData002 -* @tc.desc: Set sync parameters - success. -* @tc.type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang -*/ + * @tc.name: SyncData002 + * @tc.desc: Set sync parameters - success. + * @tc.type: FUNC + * @tc.require: I5DE2A + * @tc.author: Sven Wang + */ HWTEST_F(DeviceKvStoreTest, SetSync001, TestSize.Level1) { EXPECT_NE(kvStore_, nullptr) << "kvStore is null."; - KvSyncParam syncParam{ 500 }; // 500ms + KvSyncParam syncParam { 500 }; // 500ms auto ret = kvStore_->SetSyncParam(syncParam); EXPECT_EQ(ret, Status::SUCCESS) << "set sync param should return success"; @@ -575,16 +565,16 @@ HWTEST_F(DeviceKvStoreTest, SetSync001, TestSize.Level1) } /** -* @tc.name: SyncData002 -* @tc.desc: Set sync parameters - failed. -* @tc.type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang -*/ + * @tc.name: SyncData002 + * @tc.desc: Set sync parameters - failed. + * @tc.type: FUNC + * @tc.require: I5DE2A + * @tc.author: Sven Wang + */ HWTEST_F(DeviceKvStoreTest, SetSync002, TestSize.Level1) { EXPECT_NE(kvStore_, nullptr) << "kvStore is null."; - KvSyncParam syncParam2{ 50 }; // 50ms + KvSyncParam syncParam2 { 50 }; // 50ms auto ret = kvStore_->SetSyncParam(syncParam2); EXPECT_NE(ret, Status::SUCCESS) << "set sync param should not return success"; @@ -594,12 +584,12 @@ HWTEST_F(DeviceKvStoreTest, SetSync002, TestSize.Level1) } /** -* @tc.name: SingleKvStoreDdmPutBatch001 -* @tc.desc: Batch put data. -* @tc.type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang -*/ + * @tc.name: SingleKvStoreDdmPutBatch001 + * @tc.desc: Batch put data. + * @tc.type: FUNC + * @tc.require: I5DE2A + * @tc.author: Sven Wang + */ HWTEST_F(DeviceKvStoreTest, SingleKvStoreDdmPutBatch001, TestSize.Level2) { EXPECT_NE(nullptr, kvStore_) << "kvStore is nullptr"; @@ -637,12 +627,12 @@ HWTEST_F(DeviceKvStoreTest, SingleKvStoreDdmPutBatch001, TestSize.Level2) } /** -* @tc.name: SingleKvStoreDdmPutBatch002 -* @tc.desc: Batch update data. -* @tc.type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang -*/ + * @tc.name: SingleKvStoreDdmPutBatch002 + * @tc.desc: Batch update data. + * @tc.type: FUNC + * @tc.require: I5DE2A + * @tc.author: Sven Wang + */ HWTEST_F(DeviceKvStoreTest, SingleKvStoreDdmPutBatch002, TestSize.Level2) { EXPECT_NE(nullptr, kvStore_) << "kvStore is nullptr"; @@ -697,12 +687,12 @@ HWTEST_F(DeviceKvStoreTest, SingleKvStoreDdmPutBatch002, TestSize.Level2) } /** -* @tc.name: DdmPutBatch003 -* @tc.desc: Batch put data that contains invalid data. -* @tc.type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang -*/ + * @tc.name: DdmPutBatch003 + * @tc.desc: Batch put data that contains invalid data. + * @tc.type: FUNC + * @tc.require: I5DE2A + * @tc.author: Sven Wang + */ HWTEST_F(DeviceKvStoreTest, DdmPutBatch003, TestSize.Level2) { EXPECT_NE(nullptr, kvStore_) << "kvStore is nullptr"; @@ -725,12 +715,12 @@ HWTEST_F(DeviceKvStoreTest, DdmPutBatch003, TestSize.Level2) } /** -* @tc.name: DdmPutBatch004 -* @tc.desc: Batch put data that contains invalid data. -* @tc.type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang -*/ + * @tc.name: DdmPutBatch004 + * @tc.desc: Batch put data that contains invalid data. + * @tc.type: FUNC + * @tc.require: I5DE2A + * @tc.author: Sven Wang + */ HWTEST_F(DeviceKvStoreTest, DdmPutBatch004, TestSize.Level2) { EXPECT_NE(nullptr, kvStore_) << "kvStore is nullptr"; @@ -762,12 +752,12 @@ static std::string SingleGenerate1025KeyLen() return str; } /** -* @tc.name: DdmPutBatch005 -* @tc.desc: Batch put data that contains invalid data. -* @tc.type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang -*/ + * @tc.name: DdmPutBatch005 + * @tc.desc: Batch put data that contains invalid data. + * @tc.type: FUNC + * @tc.require: I5DE2A + * @tc.author: Sven Wang + */ HWTEST_F(DeviceKvStoreTest, DdmPutBatch005, TestSize.Level2) { EXPECT_NE(nullptr, kvStore_) << "kvStore is nullptr"; @@ -788,12 +778,12 @@ HWTEST_F(DeviceKvStoreTest, DdmPutBatch005, TestSize.Level2) } /** -* @tc.name: DdmPutBatch006 -* @tc.desc: Batch put large data. -* @tc.type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang -*/ + * @tc.name: DdmPutBatch006 + * @tc.desc: Batch put large data. + * @tc.type: FUNC + * @tc.require: I5DE2A + * @tc.author: Sven Wang + */ HWTEST_F(DeviceKvStoreTest, DdmPutBatch006, TestSize.Level2) { EXPECT_NE(nullptr, kvStore_) << "kvStore is nullptr"; @@ -836,12 +826,12 @@ HWTEST_F(DeviceKvStoreTest, DdmPutBatch006, TestSize.Level2) } /** -* @tc.name: DdmDeleteBatch001 -* @tc.desc: Batch delete data. -* @tc.type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang -*/ + * @tc.name: DdmDeleteBatch001 + * @tc.desc: Batch delete data. + * @tc.type: FUNC + * @tc.require: I5DE2A + * @tc.author: Sven Wang + */ HWTEST_F(DeviceKvStoreTest, DdmDeleteBatch001, TestSize.Level2) { EXPECT_NE(nullptr, kvStore_) << "kvStore is nullptr"; @@ -876,12 +866,12 @@ HWTEST_F(DeviceKvStoreTest, DdmDeleteBatch001, TestSize.Level2) } /** -* @tc.name: DdmDeleteBatch002 -* @tc.desc: Batch delete data when some keys are not in KvStore. -* @tc.type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang -*/ + * @tc.name: DdmDeleteBatch002 + * @tc.desc: Batch delete data when some keys are not in KvStore. + * @tc.type: FUNC + * @tc.require: I5DE2A + * @tc.author: Sven Wang + */ HWTEST_F(DeviceKvStoreTest, DdmDeleteBatch002, TestSize.Level2) { EXPECT_NE(nullptr, kvStore_) << "kvStore is nullptr"; @@ -917,12 +907,12 @@ HWTEST_F(DeviceKvStoreTest, DdmDeleteBatch002, TestSize.Level2) } /** -* @tc.name: DdmDeleteBatch003 -* @tc.desc: Batch delete data when some keys are invalid. -* @tc.type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang -*/ + * @tc.name: DdmDeleteBatch003 + * @tc.desc: Batch delete data when some keys are invalid. + * @tc.type: FUNC + * @tc.require: I5DE2A + * @tc.author: Sven Wang + */ HWTEST_F(DeviceKvStoreTest, DdmDeleteBatch003, TestSize.Level2) { EXPECT_NE(nullptr, kvStore_) << "kvStore is nullptr"; @@ -958,12 +948,12 @@ HWTEST_F(DeviceKvStoreTest, DdmDeleteBatch003, TestSize.Level2) } /** -* @tc.name: DdmDeleteBatch004 -* @tc.desc: Batch delete data when some keys are invalid. -* @tc.type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang -*/ + * @tc.name: DdmDeleteBatch004 + * @tc.desc: Batch delete data when some keys are invalid. + * @tc.type: FUNC + * @tc.require: I5DE2A + * @tc.author: Sven Wang + */ HWTEST_F(DeviceKvStoreTest, DdmDeleteBatch004, TestSize.Level2) { EXPECT_NE(nullptr, kvStore_) << "kvStore is nullptr"; @@ -1004,12 +994,12 @@ HWTEST_F(DeviceKvStoreTest, DdmDeleteBatch004, TestSize.Level2) } /** -* @tc.name: DdmDeleteBatch005 -* @tc.desc: Batch delete data when some keys are invalid. -* @tc.type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang -*/ + * @tc.name: DdmDeleteBatch005 + * @tc.desc: Batch delete data when some keys are invalid. + * @tc.type: FUNC + * @tc.require: I5DE2A + * @tc.author: Sven Wang + */ HWTEST_F(DeviceKvStoreTest, DdmDeleteBatch005, TestSize.Level2) { EXPECT_NE(nullptr, kvStore_) << "kvStore is nullptr"; @@ -1050,12 +1040,12 @@ HWTEST_F(DeviceKvStoreTest, DdmDeleteBatch005, TestSize.Level2) } /** -* @tc.name: Transaction001 -* @tc.desc: Batch delete data when some keys are invalid. -* @tc.type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang -*/ + * @tc.name: Transaction001 + * @tc.desc: Batch delete data when some keys are invalid. + * @tc.type: FUNC + * @tc.require: I5DE2A + * @tc.author: Sven Wang + */ HWTEST_F(DeviceKvStoreTest, Transaction001, TestSize.Level2) { EXPECT_NE(nullptr, kvStore_) << "kvStore is nullptr"; @@ -1088,7 +1078,7 @@ HWTEST_F(DeviceKvStoreTest, Transaction001, TestSize.Level2) status = kvStore_->StartTransaction(); EXPECT_EQ(Status::SUCCESS, status) << "StartTransaction return wrong status"; - status = kvStore_->Put(key1, value1); // insert or update key-value + status = kvStore_->Put(key1, value1); // insert or update key-value EXPECT_EQ(Status::SUCCESS, status) << "Put data return wrong status"; status = kvStore_->PutBatch(entries); EXPECT_EQ(Status::SUCCESS, status) << "PutBatch data return wrong status"; @@ -1107,12 +1097,12 @@ HWTEST_F(DeviceKvStoreTest, Transaction001, TestSize.Level2) } /** -* @tc.name: Transaction002 -* @tc.desc: Batch delete data when some keys are invalid. -* @tc.type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang -*/ + * @tc.name: Transaction002 + * @tc.desc: Batch delete data when some keys are invalid. + * @tc.type: FUNC + * @tc.require: I5DE2A + * @tc.author: Sven Wang + */ HWTEST_F(DeviceKvStoreTest, Transaction002, TestSize.Level2) { EXPECT_NE(nullptr, kvStore_) << "kvStore is nullptr"; @@ -1145,7 +1135,7 @@ HWTEST_F(DeviceKvStoreTest, Transaction002, TestSize.Level2) status = kvStore_->StartTransaction(); EXPECT_EQ(Status::SUCCESS, status) << "StartTransaction return wrong status"; - status = kvStore_->Put(key1, value1); // insert or update key-value + status = kvStore_->Put(key1, value1); // insert or update key-value EXPECT_EQ(Status::SUCCESS, status) << "Put data return wrong status"; status = kvStore_->PutBatch(entries); EXPECT_EQ(Status::SUCCESS, status) << "PutBatch data return wrong status"; @@ -1168,12 +1158,12 @@ HWTEST_F(DeviceKvStoreTest, Transaction002, TestSize.Level2) } /** -* @tc.name: DeviceSync001 -* @tc.desc: Test sync enable. -* @tc.type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang -*/ + * @tc.name: DeviceSync001 + * @tc.desc: Test sync enable. + * @tc.type: FUNC + * @tc.require: I5DE2A + * @tc.author: Sven Wang + */ HWTEST_F(DeviceKvStoreTest, DeviceSync001, TestSize.Level1) { std::shared_ptr kvStore; @@ -1196,12 +1186,12 @@ HWTEST_F(DeviceKvStoreTest, DeviceSync001, TestSize.Level1) } /** -* @tc.name: DeviceSync002 -* @tc.desc: Test sync enable. -* @tc.type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang -*/ + * @tc.name: DeviceSync002 + * @tc.desc: Test sync enable. + * @tc.type: FUNC + * @tc.require: I5DE2A + * @tc.author: Sven Wang + */ HWTEST_F(DeviceKvStoreTest, DeviceSync002, TestSize.Level1) { std::shared_ptr kvStore; @@ -1218,41 +1208,59 @@ HWTEST_F(DeviceKvStoreTest, DeviceSync002, TestSize.Level1) auto result = kvStore->GetStoreId(); EXPECT_EQ(result.storeId, "schema_device_id002"); - std::vector local = {"A", "B"}; - std::vector remote = {"C", "D"}; + std::vector local = { "A", "B" }; + std::vector remote = { "C", "D" }; auto testStatus = kvStore->SetCapabilityRange(local, remote); EXPECT_EQ(testStatus, Status::SUCCESS) << "set range fail"; manager.DeleteKvStore(appId, storeId, options.baseDir); } /** -* @tc.name: SyncWithCondition001 -* @tc.desc: sync device data with condition; -* @tc.type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang -*/ + * @tc.name: SyncWithCondition001 + * @tc.desc: sync device data with condition; + * @tc.type: FUNC + * @tc.require: I5DE2A + * @tc.author: Sven Wang + */ HWTEST_F(DeviceKvStoreTest, SyncWithCondition001, TestSize.Level1) { EXPECT_NE(kvStore_, nullptr) << "kvStore is null."; - std::vector deviceIds = {"invalid_device_id1", "invalid_device_id2"}; + std::vector deviceIds = { "invalid_device_id1", "invalid_device_id2" }; DataQuery dataQuery; dataQuery.KeyPrefix("name"); auto syncStatus = kvStore_->Sync(deviceIds, SyncMode::PUSH, dataQuery, nullptr); EXPECT_NE(syncStatus, Status::SUCCESS) << "sync device should not return success"; } +/** + * @tc.name: SyncWithCondition002 + * @tc.desc: sync device data with condition; + * @tc.type: FUNC + * @tc.require: + * @tc.author: SQL + */ +HWTEST_F(DeviceKvStoreTest, SyncWithCondition002, TestSize.Level1) +{ + EXPECT_NE(kvStore_, nullptr) << "kvStore is null."; + std::vector deviceIds = { "invalid_device_id1", "invalid_device_id2" }; + DataQuery dataQuery; + dataQuery.KeyPrefix("name"); + uint32_t delay = 0; + auto syncStatus = kvStore_->Sync(deviceIds, SyncMode::PUSH, dataQuery, nullptr, delay); + EXPECT_NE(syncStatus, Status::SUCCESS) << "sync device should not return success"; +} + /** * @tc.name: SubscribeWithQuery001 * desc: subscribe and sync device data with query; * type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang + * @tc.require: I5DE2A + * @tc.author: Sven Wang */ HWTEST_F(DeviceKvStoreTest, SubscribeWithQuery001, TestSize.Level1) { EXPECT_NE(kvStore_, nullptr) << "kvStore is null."; - std::vector deviceIds = {"invalid_device_id1", "invalid_device_id2"}; + std::vector deviceIds = { "invalid_device_id1", "invalid_device_id2" }; DataQuery dataQuery; dataQuery.KeyPrefix("name"); auto syncStatus = kvStore_->SubscribeWithQuery(deviceIds, dataQuery); @@ -1263,15 +1271,16 @@ HWTEST_F(DeviceKvStoreTest, SubscribeWithQuery001, TestSize.Level1) * @tc.name: UnSubscribeWithQuery001 * desc: subscribe and sync device data with query; * type: FUNC -* @tc.require: I5DE2A -* @tc.author: Sven Wang + * @tc.require: I5DE2A + * @tc.author: Sven Wang */ HWTEST_F(DeviceKvStoreTest, UnSubscribeWithQuery001, TestSize.Level1) { EXPECT_NE(kvStore_, nullptr) << "kvStore is nullptr."; - std::vector deviceIds = {"invalid_device_id1", "invalid_device_id2"}; + std::vector deviceIds = { "invalid_device_id1", "invalid_device_id2" }; DataQuery dataQuery; dataQuery.KeyPrefix("name"); auto unSubscribeStatus = kvStore_->UnsubscribeWithQuery(deviceIds, dataQuery); EXPECT_NE(unSubscribeStatus, Status::SUCCESS) << "sync device should not return success"; -} \ No newline at end of file +} +} // namespace OHOS::Test \ No newline at end of file diff --git a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_data_mgr_test.cpp b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_data_mgr_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c22259de0d960953557f216f4dd9f8a2cb5dc8d5 --- /dev/null +++ b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_data_mgr_test.cpp @@ -0,0 +1,55 @@ +/* + * 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 "accesstoken_kit.h" +#include "distributed_data_mgr.h" +#include "ipc_skeleton.h" +#include "nativetoken_kit.h" +#include "token_setproc.h" +#include "types.h" +#include +#include + +using namespace testing::ext; +using namespace OHOS::DistributedKv; +using namespace OHOS::Security::AccessToken; +namespace OHOS::Test { +std::string BUNDLE_NAME = "ohos.distributeddatamgrtest.demo"; +static constexpr int32_t TEST_USERID = 100; +static constexpr int32_t APP_INDEX = 0; +class DistributedDataMgrTest : public testing::Test { +public: + static DistributedDataMgr manager; + static void SetUpTestCase(void){}; + static void TearDownTestCase(void){}; + void SetUp(){}; + void TearDown(){}; +}; +DistributedDataMgr DistributedDataMgrTest::manager; + +/** + * @tc.name: ClearAppStorage + * @tc.desc: + * @tc.type: FUNC + * @tc.require: + * @tc.author: SQL + */ +HWTEST_F(DistributedDataMgrTest, ClearAppStorage001, TestSize.Level1) +{ + auto tokenId = 0; + auto ret = manager.ClearAppStorage(BUNDLE_NAME, TEST_USERID, APP_INDEX, tokenId); + EXPECT_NE(ret, Status::SUCCESS); +} +} // namespace OHOS::Test \ No newline at end of file diff --git a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_kv_data_manager_encrypt_test.cpp b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_kv_data_manager_encrypt_test.cpp index 5fb49261cb5f467fc722d1fadf47092f461844b6..d2648359ffce6c9234e5133cce1da1056bfacab6 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_kv_data_manager_encrypt_test.cpp +++ b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_kv_data_manager_encrypt_test.cpp @@ -47,9 +47,9 @@ public: class MyDeathRecipient : public KvStoreDeathRecipient { public: - MyDeathRecipient() {} - virtual ~MyDeathRecipient() {} - void OnRemoteDied() override {} + MyDeathRecipient() { } + virtual ~MyDeathRecipient() { } + void OnRemoteDied() override { } }; DistributedKvDataManager DistributedKvDataManagerEncryptTest::manager; @@ -101,15 +101,15 @@ DistributedKvDataManagerEncryptTest::~DistributedKvDataManagerEncryptTest(void) {} void DistributedKvDataManagerEncryptTest::TearDown(void) -{} +{ + RemoveAllStore(manager); +} /** -* @tc.name: kvstore_ddm_createEncryptedStore_001 -* @tc.desc: Create an encrypted KvStore. -* @tc.type: FUNC -* @tc.require: SR000D08K4 AR000D08KQ -* @tc.author: liqiao -*/ + * @tc.name: kvstore_ddm_createEncryptedStore_001 + * @tc.desc: Create an encrypted KvStore. + * @tc.type: FUNC + */ HWTEST_F(DistributedKvDataManagerEncryptTest, kvstore_ddm_createEncryptedStore_001, TestSize.Level1) { ZLOGI("kvstore_ddm_createEncryptedStore_001 begin."); @@ -129,4 +129,70 @@ HWTEST_F(DistributedKvDataManagerEncryptTest, kvstore_ddm_createEncryptedStore_0 EXPECT_EQ(Status::SUCCESS, statusRet) << "get data return wrong status"; EXPECT_EQ(value, valueRet) << "value and valueRet are not equal"; +} + +/** + * @tc.name: GetEncryptStoreWithKeyFromService + * @tc.desc: Get encrypt store, delete key, get store again. + * @tc.type: FUNC + */ +HWTEST_F(DistributedKvDataManagerEncryptTest, GetEncryptStoreWithKeyFromService, TestSize.Level1) +{ + ZLOGI("GetEncryptStoreWithKeyFromService begin."); + std::shared_ptr kvStore; + Status status = manager.GetSingleKvStore(createEnc, appId, storeId, kvStore); + ASSERT_EQ(status, Status::SUCCESS); + ASSERT_NE(kvStore, nullptr); + + manager.CloseAllKvStore(appId); + std::string keyPath = createEnc.baseDir + "/key/" + storeId.storeId + ".key_v1"; + auto ret = remove(keyPath.c_str()); + ASSERT_EQ(ret, 0); + + kvStore = nullptr; + status = manager.GetSingleKvStore(createEnc, appId, storeId, kvStore); + ASSERT_EQ(status, Status::SUCCESS); + ASSERT_NE(kvStore, nullptr); +} + +/** + * @tc.name: DeleteEncryptedStore_001 + * @tc.desc: Failed to delete encrypted store, then open again. + * @tc.type: FUNC + */ +HWTEST_F(DistributedKvDataManagerEncryptTest, DeleteEncryptedStore_001, TestSize.Level1) +{ + ZLOGI("DeleteEncryptedStore_001 begin."); + std::shared_ptr kvStore; + Status status = manager.GetSingleKvStore(createEnc, appId, storeId, kvStore); + ASSERT_EQ(status, Status::SUCCESS); + ASSERT_NE(kvStore, nullptr); + + Key key = "age"; + Value value = "18"; + status = kvStore->Put(key, value); + EXPECT_EQ(Status::SUCCESS, status); + std::shared_ptr resultSet = nullptr; + kvStore->GetResultSet("", resultSet); + ASSERT_NE(resultSet, nullptr); + ASSERT_TRUE(resultSet->GetCount() == 1); + + // Database busy, delete failed + status = manager.DeleteKvStore(appId, storeId, createEnc.baseDir); + ASSERT_NE(status, Status::SUCCESS); + + kvStore->CloseResultSet(resultSet); + resultSet = nullptr; + manager.CloseAllKvStore(appId); + kvStore = nullptr; + // GetSingleKvStore successful, data still available + status = manager.GetSingleKvStore(createEnc, appId, storeId, kvStore); + ASSERT_EQ(status, Status::SUCCESS); + ASSERT_NE(kvStore, nullptr); + Value valueRet; + status = kvStore->Get(key, valueRet); + ASSERT_EQ(valueRet, value); + + status = manager.DeleteKvStore(appId, storeId, createEnc.baseDir); + ASSERT_EQ(status, Status::SUCCESS); } \ No newline at end of file diff --git a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_kv_data_manager_multi_user_test.cpp b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_kv_data_manager_multi_user_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..69791fe3b5417f43cbd8ee9097f978aa92919b2e --- /dev/null +++ b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_kv_data_manager_multi_user_test.cpp @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "distributed_kv_data_manager.h" + +using namespace testing::ext; +using namespace OHOS::DistributedKv; +namespace OHOS::Test { +static constexpr const char *APP_ID = "kv_multi_user_test"; +static constexpr const char *FIRST_STORE = "firstStoreId"; +static constexpr const char *SECOND_STORE = "secondStoreId"; +static constexpr int32_t USER_ID = 100; +static constexpr const char *DATA_DIR = "/data/service/el1/100/database"; +class DistributedKvDataManagerMultiUserTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + + static DistributedKvDataManager manager; + static Options normalOptions; + static Options encryptOptions; + static AppId appId; + static StoreId firstStoreId; + static StoreId secondStoreId; +}; + +DistributedKvDataManager DistributedKvDataManagerMultiUserTest::manager; +Options DistributedKvDataManagerMultiUserTest::normalOptions; +Options DistributedKvDataManagerMultiUserTest::encryptOptions; +AppId DistributedKvDataManagerMultiUserTest::appId; +StoreId DistributedKvDataManagerMultiUserTest::firstStoreId; +StoreId DistributedKvDataManagerMultiUserTest::secondStoreId; + +void DistributedKvDataManagerMultiUserTest::SetUpTestCase(void) +{ + appId.appId = APP_ID; + firstStoreId.storeId = FIRST_STORE; + secondStoreId.storeId = SECOND_STORE; + + std::string dataDir = DATA_DIR + appId.appId; + mkdir(dataDir.c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)); + + normalOptions.createIfMissing = true; + normalOptions.securityLevel = S1; + normalOptions.kvStoreType = SINGLE_VERSION; + normalOptions.area = EL1; + normalOptions.subUser = USER_ID; + normalOptions.baseDir = dataDir; + normalOptions.encrypt = false; + + encryptOptions.createIfMissing = true; + encryptOptions.securityLevel = S1; + encryptOptions.kvStoreType = SINGLE_VERSION; + encryptOptions.area = EL1; + encryptOptions.subUser = USER_ID; + encryptOptions.baseDir = dataDir; + encryptOptions.encrypt = true; +} + +void DistributedKvDataManagerMultiUserTest::TearDownTestCase(void) +{ + (void)remove(normalOptions.baseDir.c_str()); +} + +void DistributedKvDataManagerMultiUserTest::SetUp() +{ +} + +void DistributedKvDataManagerMultiUserTest::TearDown() +{ + manager.CloseAllKvStore(appId, USER_ID); + manager.DeleteAllKvStore(appId, normalOptions.baseDir, USER_ID); +} + +/** +* @tc.name: GetKvStoreTest001 +* @tc.desc: get normal kv store with sub user +* @tc.type: FUNC +*/ +HWTEST_F(DistributedKvDataManagerMultiUserTest, GetKvStoreTest001, TestSize.Level1) +{ + std::shared_ptr kvStore; + auto status = manager.GetSingleKvStore(normalOptions, appId, firstStoreId, kvStore); + ASSERT_EQ(status, Status::SUCCESS); + ASSERT_NE(kvStore, nullptr); +} + +/** +* @tc.name: GetKvStoreTest002 +* @tc.desc: get encrypt kv store with sub user +* @tc.type: FUNC +*/ +HWTEST_F(DistributedKvDataManagerMultiUserTest, GetKvStoreTest002, TestSize.Level1) +{ + std::shared_ptr kvStore; + auto status = manager.GetSingleKvStore(encryptOptions, appId, firstStoreId, kvStore); + ASSERT_EQ(status, Status::SUCCESS); + ASSERT_NE(kvStore, nullptr); +} + +/** +* @tc.name: GetAllKvStoreIdTest +* @tc.desc: get all store id with sub user +* @tc.type: FUNC +*/ +HWTEST_F(DistributedKvDataManagerMultiUserTest, GetAllKvStoreId001, TestSize.Level1) +{ + std::shared_ptr firstKvStore; + auto status = manager.GetSingleKvStore(normalOptions, appId, firstStoreId, firstKvStore); + ASSERT_EQ(status, Status::SUCCESS); + ASSERT_NE(firstKvStore, nullptr); + + std::shared_ptr secondKvStore; + status = manager.GetSingleKvStore(normalOptions, appId, secondStoreId, secondKvStore); + ASSERT_EQ(status, Status::SUCCESS); + ASSERT_NE(secondKvStore, nullptr); + + std::vector storeIds; + status = manager.GetAllKvStoreId(appId, storeIds, normalOptions.subUser); + ASSERT_EQ(status, Status::SUCCESS); + + ASSERT_EQ(storeIds.size(), static_cast(2)); + ASSERT_NE(storeIds[0].storeId, storeIds[1].storeId); + ASSERT_TRUE(storeIds[0].storeId == firstStoreId.storeId || storeIds[0].storeId == secondStoreId.storeId); + ASSERT_TRUE(storeIds[1].storeId == secondStoreId.storeId || storeIds[0].storeId == secondStoreId.storeId); +} + +/** +* @tc.name: CloseKvStoreTest001 +* @tc.desc: close kv store with sub user +* @tc.type: FUNC +*/ +HWTEST_F(DistributedKvDataManagerMultiUserTest, CloseKvStoreTest001, TestSize.Level1) +{ + std::shared_ptr kvStore; + auto status = manager.GetSingleKvStore(normalOptions, appId, firstStoreId, kvStore); + ASSERT_EQ(status, Status::SUCCESS); + ASSERT_NE(kvStore, nullptr); + + status = manager.CloseKvStore(appId, firstStoreId, normalOptions.subUser); + ASSERT_EQ(status, Status::SUCCESS); +} + +/** +* @tc.name: CloseKvStoreTest002 +* @tc.desc: close kv store with sub user +* @tc.type: FUNC +*/ +HWTEST_F(DistributedKvDataManagerMultiUserTest, CloseKvStoreTest002, TestSize.Level1) +{ + std::shared_ptr kvStore; + auto status = manager.GetSingleKvStore(normalOptions, appId, firstStoreId, kvStore); + ASSERT_EQ(status, Status::SUCCESS); + ASSERT_NE(kvStore, nullptr); + + status = manager.CloseKvStore(appId, kvStore); + ASSERT_EQ(status, Status::SUCCESS); +} + +/** +* @tc.name: CloseKvStoreTest003 +* @tc.desc: delete kv store with sub user +* @tc.type: FUNC +*/ +HWTEST_F(DistributedKvDataManagerMultiUserTest, CloseKvStoreTest003, TestSize.Level1) +{ + std::shared_ptr kvStore; + auto status = manager.GetSingleKvStore(normalOptions, appId, firstStoreId, kvStore); + ASSERT_EQ(status, Status::SUCCESS); + ASSERT_NE(kvStore, nullptr); + + status = manager.CloseKvStore(appId, firstStoreId, normalOptions.subUser); + ASSERT_EQ(status, Status::SUCCESS); + kvStore = nullptr; + + status = manager.DeleteKvStore(appId, firstStoreId, normalOptions.baseDir, normalOptions.subUser); + ASSERT_EQ(status, Status::SUCCESS); +} + +/** +* @tc.name: DeleteKvStoreTest002 +* @tc.desc: delete all kv store with sub user +* @tc.type: FUNC +*/ +HWTEST_F(DistributedKvDataManagerMultiUserTest, DeleteKvStoreTest002, TestSize.Level1) +{ + std::shared_ptr firstKvStore; + auto status = manager.GetSingleKvStore(normalOptions, appId, firstStoreId, firstKvStore); + ASSERT_EQ(status, Status::SUCCESS); + ASSERT_NE(firstKvStore, nullptr); + + std::shared_ptr secondKvStore; + status = manager.GetSingleKvStore(normalOptions, appId, secondStoreId, secondKvStore); + ASSERT_EQ(status, Status::SUCCESS); + ASSERT_NE(secondKvStore, nullptr); + + status = manager.CloseKvStore(appId, firstStoreId, normalOptions.subUser); + ASSERT_EQ(status, Status::SUCCESS); + firstKvStore = nullptr; + + status = manager.CloseKvStore(appId, secondStoreId, normalOptions.subUser); + ASSERT_EQ(status, Status::SUCCESS); + secondKvStore = nullptr; + + status = manager.DeleteAllKvStore(appId, normalOptions.baseDir, normalOptions.subUser); + ASSERT_EQ(status, Status::SUCCESS); +} +} // namespace OHOS::Test \ No newline at end of file diff --git a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_kv_data_manager_test.cpp b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_kv_data_manager_test.cpp index 1a2c9d8aeaf78708d7aa8a9a53b8c1da7ae05707..d88a0bfbc3e78f294a9f4c8051a1a6b1666e1a64 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_kv_data_manager_test.cpp +++ b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/distributed_kv_data_manager_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 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 @@ -17,45 +17,63 @@ #include #include +#include "block_data.h" +#include "dev_manager.h" #include "kvstore_death_recipient.h" #include "log_print.h" #include "types.h" + using namespace testing::ext; using namespace OHOS::DistributedKv; namespace OHOS::Test { +static constexpr size_t NUM_MIN = 5; +static constexpr size_t NUM_MAX = 12; class DistributedKvDataManagerTest : public testing::Test { public: + static std::shared_ptr executors; static DistributedKvDataManager manager; static Options create; static Options noCreate; - static UserId userId; - static AppId appId; static StoreId storeId64; static StoreId storeId65; static StoreId storeIdTest; static StoreId storeIdEmpty; - static Entry entryA; static Entry entryB; - static void SetUpTestCase(void); static void TearDownTestCase(void); - static void RemoveAllStore(DistributedKvDataManager &manager); - void SetUp(); void TearDown(); DistributedKvDataManagerTest(); }; +class SwitchDataObserver : public KvStoreObserver { +public: + void OnSwitchChange(const SwitchNotification ¬ification) override + { + blockData_.SetValue(notification); + } + + SwitchNotification Get() + { + return blockData_.GetValue(); + } + +private: + BlockData blockData_ { 1, SwitchNotification() }; +}; + class MyDeathRecipient : public KvStoreDeathRecipient { public: MyDeathRecipient() {} virtual ~MyDeathRecipient() {} void OnRemoteDied() override {} }; +std::shared_ptr DistributedKvDataManagerTest::executors = + std::make_shared(NUM_MAX, NUM_MIN); DistributedKvDataManager DistributedKvDataManagerTest::manager; Options DistributedKvDataManagerTest::create; @@ -79,6 +97,8 @@ void DistributedKvDataManagerTest::RemoveAllStore(DistributedKvDataManager &mana } void DistributedKvDataManagerTest::SetUpTestCase(void) { + manager.SetExecutors(executors); + userId.userId = "account0"; appId.appId = "ohos.kvdatamanager.test"; create.createIfMissing = true; @@ -133,7 +153,7 @@ void DistributedKvDataManagerTest::TearDown(void) * @tc.name: GetKvStore001 * @tc.desc: Get an exist SingleKvStore * @tc.type: FUNC -* @tc.require: SR000CQDU0 AR000BVTDM +* @tc.require: * @tc.author: liqiao */ HWTEST_F(DistributedKvDataManagerTest, GetKvStore001, TestSize.Level1) @@ -154,7 +174,7 @@ HWTEST_F(DistributedKvDataManagerTest, GetKvStore001, TestSize.Level1) * @tc.name: GetKvStore002 * @tc.desc: Create and get a new SingleKvStore * @tc.type: FUNC -* @tc.require: SR000CQDU0 AR000BVTDM +* @tc.require: * @tc.author: liqiao */ HWTEST_F(DistributedKvDataManagerTest, GetKvStore002, TestSize.Level1) @@ -173,7 +193,7 @@ HWTEST_F(DistributedKvDataManagerTest, GetKvStore002, TestSize.Level1) * @tc.desc: Get a non-existing SingleKvStore, and the callback function should receive STORE_NOT_FOUND and * get a nullptr. * @tc.type: FUNC -* @tc.require: SR000CQDU0 AR000BVTDM +* @tc.require: * @tc.author: liqiao */ HWTEST_F(DistributedKvDataManagerTest, GetKvStore003, TestSize.Level1) @@ -188,7 +208,7 @@ HWTEST_F(DistributedKvDataManagerTest, GetKvStore003, TestSize.Level1) * @tc.name: GetKvStore004 * @tc.desc: Create a SingleKvStore with an empty storeId, and the callback function should receive * @tc.type: FUNC -* @tc.require: SR000CQDU0 AR000BVTDM +* @tc.require: * @tc.author: liqiao */ HWTEST_F(DistributedKvDataManagerTest, GetKvStore004, TestSize.Level1) @@ -204,7 +224,7 @@ HWTEST_F(DistributedKvDataManagerTest, GetKvStore004, TestSize.Level1) * @tc.name: GetKvStore005 * @tc.desc: Get a SingleKvStore with an empty storeId, and the callback function should receive INVALID_ARGUMENT * @tc.type: FUNC -* @tc.require: SR000CQDU0 AR000BVTDM +* @tc.require: * @tc.author: liqiao */ HWTEST_F(DistributedKvDataManagerTest, GetKvStore005, TestSize.Level1) @@ -220,7 +240,7 @@ HWTEST_F(DistributedKvDataManagerTest, GetKvStore005, TestSize.Level1) * @tc.name: GetKvStore006 * @tc.desc: Create a SingleKvStore with a 65-byte storeId, and the callback function should receive INVALID_ARGUMENT * @tc.type: FUNC -* @tc.require: SR000CQDU0 AR000BVTDM +* @tc.require: * @tc.author: liqiao */ HWTEST_F(DistributedKvDataManagerTest, GetKvStore006, TestSize.Level1) @@ -236,7 +256,7 @@ HWTEST_F(DistributedKvDataManagerTest, GetKvStore006, TestSize.Level1) * @tc.name: GetKvStore007 * @tc.desc: Get a SingleKvStore with a 65-byte storeId, the callback function should receive INVALID_ARGUMENT * @tc.type: FUNC -* @tc.require: SR000CQDU0 AR000BVTDM +* @tc.require: * @tc.author: liqiao */ HWTEST_F(DistributedKvDataManagerTest, GetKvStore007, TestSize.Level1) @@ -248,12 +268,89 @@ HWTEST_F(DistributedKvDataManagerTest, GetKvStore007, TestSize.Level1) EXPECT_EQ(notExistKvStore, nullptr); } +/** + * @tc.name: GetKvStore008 + * @tc.desc: Get a SingleKvStore which supports cloud sync. + * @tc.type: FUNC + * @tc.require: + * @tc.author: Hollokin + */ +HWTEST_F(DistributedKvDataManagerTest, GetKvStore008, TestSize.Level1) +{ + ZLOGI("GetKvStore008 begin."); + std::shared_ptr cloudKvStore = nullptr; + Options options = create; + options.isPublic = true; + options.cloudConfig = { + .enableCloud = true, + .autoSync = true + }; + Status status = manager.GetSingleKvStore(options, appId, storeId64, cloudKvStore); + ASSERT_EQ(status, Status::SUCCESS); + EXPECT_NE(cloudKvStore, nullptr); +} + +/** + * @tc.name: GetKvStore009 + * @tc.desc: Get a SingleKvStore which security level upgrade. + * @tc.type: FUNC + * @tc.require: + * @tc.author: yanhui + */ +HWTEST_F(DistributedKvDataManagerTest, GetKvStore009, TestSize.Level1) +{ + ZLOGI("GetKvStore009 begin."); + std::shared_ptr kvStore = nullptr; + Options options = create; + options.securityLevel = S1; + Status status = manager.GetSingleKvStore(options, appId, storeId64, kvStore); + + manager.CloseKvStore(appId, storeId64); + options.securityLevel = S2; + status = manager.GetSingleKvStore(options, appId, storeId64, kvStore); + ASSERT_EQ(status, Status::SUCCESS); + EXPECT_NE(kvStore, nullptr); + + manager.CloseKvStore(appId, storeId64); + options.securityLevel = S1; + status = manager.GetSingleKvStore(options, appId, storeId64, kvStore); + ASSERT_EQ(status, Status::STORE_META_CHANGED); + EXPECT_EQ(kvStore, nullptr); +} + +/** + * @tc.name: GetKvStore010 + * @tc.desc: After remove database path and mkdir and get kv store. + * @tc.type: FUNC + */ +HWTEST_F(DistributedKvDataManagerTest, GetKvStore010, TestSize.Level1) +{ + ZLOGI("GetKvStore010 begin."); + std::shared_ptr kvStore = nullptr; + auto status = manager.GetSingleKvStore(create, appId, storeId64, kvStore); + ASSERT_EQ(status, Status::SUCCESS); + EXPECT_NE(kvStore, nullptr); + + status = manager.CloseKvStore(appId, storeId64); + EXPECT_EQ(status, Status::SUCCESS); + kvStore = nullptr; + EXPECT_EQ(kvStore, nullptr); + + (void)remove((create.baseDir + "/kvdb").c_str()); + (void)remove(create.baseDir.c_str()); + (void)mkdir(create.baseDir.c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)); + + status = manager.GetSingleKvStore(create, appId, storeId64, kvStore); + ASSERT_EQ(status, Status::SUCCESS); + EXPECT_NE(kvStore, nullptr); +} + /** * @tc.name: GetKvStoreInvalidSecurityLevel * @tc.desc: Get a SingleKvStore with a 64 * -byte storeId, the callback function should receive INVALID_ARGUMENT * @tc.type: FUNC -* @tc.require: SR000IIM2J AR000IIMLL +* @tc.require: * @tc.author: wangkai */ HWTEST_F(DistributedKvDataManagerTest, GetKvStoreInvalidSecurityLevel, TestSize.Level1) @@ -271,7 +368,7 @@ HWTEST_F(DistributedKvDataManagerTest, GetKvStoreInvalidSecurityLevel, TestSize. * @tc.name: GetAllKvStore001 * @tc.desc: Get all KvStore IDs when no KvStore exists, and the callback function should receive a 0-length vector. * @tc.type: FUNC -* @tc.require: SR000CQDU0 AR000BVTDM +* @tc.require: * @tc.author: liqiao */ HWTEST_F(DistributedKvDataManagerTest, GetAllKvStore001, TestSize.Level1) @@ -287,7 +384,7 @@ HWTEST_F(DistributedKvDataManagerTest, GetAllKvStore001, TestSize.Level1) * @tc.name: GetAllKvStore002 * @tc.desc: Get all SingleKvStore IDs when no KvStore exists, and the callback function should receive a empty vector. * @tc.type: FUNC -* @tc.require: SR000CQDU0 AR000BVTDM +* @tc.require: * @tc.author: liqiao */ HWTEST_F(DistributedKvDataManagerTest, GetAllKvStore002, TestSize.Level1) @@ -337,7 +434,7 @@ HWTEST_F(DistributedKvDataManagerTest, GetAllKvStore002, TestSize.Level1) * @tc.name: CloseKvStore001 * @tc.desc: Close an opened KVStore, and the callback function should return SUCCESS. * @tc.type: FUNC -* @tc.require: SR000CQDU0 AR000BVTDM +* @tc.require: * @tc.author: liqiao */ HWTEST_F(DistributedKvDataManagerTest, CloseKvStore001, TestSize.Level1) @@ -356,7 +453,7 @@ HWTEST_F(DistributedKvDataManagerTest, CloseKvStore001, TestSize.Level1) * @tc.name: CloseKvStore002 * @tc.desc: Close a closed SingleKvStore, and the callback function should return SUCCESS. * @tc.type: FUNC -* @tc.require: SR000CQDU0 AR000BVTDM +* @tc.require: * @tc.author: liqiao */ HWTEST_F(DistributedKvDataManagerTest, CloseKvStore002, TestSize.Level1) @@ -376,7 +473,7 @@ HWTEST_F(DistributedKvDataManagerTest, CloseKvStore002, TestSize.Level1) * @tc.name: CloseKvStore003 * @tc.desc: Close a SingleKvStore with an empty storeId, and the callback function should return INVALID_ARGUMENT. * @tc.type: FUNC -* @tc.require: SR000CQDU0 AR000BVTDM +* @tc.require: * @tc.author: liqiao */ HWTEST_F(DistributedKvDataManagerTest, CloseKvStore003, TestSize.Level1) @@ -390,7 +487,7 @@ HWTEST_F(DistributedKvDataManagerTest, CloseKvStore003, TestSize.Level1) * @tc.name: CloseKvStore004 * @tc.desc: Close a SingleKvStore with a 65-byte storeId, and the callback function should return INVALID_ARGUMENT. * @tc.type: FUNC -* @tc.require: SR000CQDU0 AR000BVTDM +* @tc.require: * @tc.author: liqiao */ HWTEST_F(DistributedKvDataManagerTest, CloseKvStore004, TestSize.Level1) @@ -404,7 +501,7 @@ HWTEST_F(DistributedKvDataManagerTest, CloseKvStore004, TestSize.Level1) * @tc.name: CloseKvStore005 * @tc.desc: Close a non-existing SingleKvStore, and the callback function should return STORE_NOT_OPEN. * @tc.type: FUNC -* @tc.require: SR000CQDU0 AR000BVTDM +* @tc.require: * @tc.author: liqiao */ HWTEST_F(DistributedKvDataManagerTest, CloseKvStore005, TestSize.Level1) @@ -418,7 +515,7 @@ HWTEST_F(DistributedKvDataManagerTest, CloseKvStore005, TestSize.Level1) * @tc.name: CloseKvStoreMulti001 * @tc.desc: Open a SingleKvStore several times and close them one by one. * @tc.type: FUNC -* @tc.require: SR000CQDU0 AR000CSKRU +* @tc.require: * @tc.author: liqiao */ HWTEST_F(DistributedKvDataManagerTest, CloseKvStoreMulti001, TestSize.Level1) @@ -445,7 +542,7 @@ HWTEST_F(DistributedKvDataManagerTest, CloseKvStoreMulti001, TestSize.Level1) * @tc.name: CloseKvStoreMulti002 * @tc.desc: Open a SingleKvStore several times and close them one by one. * @tc.type: FUNC -* @tc.require: SR000CQDU0 AR000CSKRU +* @tc.require: * @tc.author: liqiao */ HWTEST_F(DistributedKvDataManagerTest, CloseKvStoreMulti002, TestSize.Level1) @@ -483,7 +580,7 @@ HWTEST_F(DistributedKvDataManagerTest, CloseKvStoreMulti002, TestSize.Level1) * @tc.name: CloseAllKvStore001 * @tc.desc: Close all opened KvStores, and the callback function should return SUCCESS. * @tc.type: FUNC -* @tc.require: SR000CQDU0 AR000BVTDM +* @tc.require: * @tc.author: liqiao */ HWTEST_F(DistributedKvDataManagerTest, CloseAllKvStore001, TestSize.Level1) @@ -507,7 +604,7 @@ HWTEST_F(DistributedKvDataManagerTest, CloseAllKvStore001, TestSize.Level1) * @tc.name: CloseAllKvStore002 * @tc.desc: Close all KvStores which exist but are not opened, and the callback function should return STORE_NOT_OPEN. * @tc.type: FUNC -* @tc.require: SR000CQDU0 AR000BVTDM +* @tc.require: * @tc.author: liqiao */ HWTEST_F(DistributedKvDataManagerTest, CloseAllKvStore002, TestSize.Level1) @@ -534,7 +631,7 @@ HWTEST_F(DistributedKvDataManagerTest, CloseAllKvStore002, TestSize.Level1) * @tc.name: DeleteKvStore001 * @tc.desc: Delete a closed KvStore, and the callback function should return SUCCESS. * @tc.type: FUNC -* @tc.require: SR000CQDU0 AR000BVTDM +* @tc.require: * @tc.author: liqiao */ HWTEST_F(DistributedKvDataManagerTest, DeleteKvStore001, TestSize.Level1) @@ -556,7 +653,7 @@ HWTEST_F(DistributedKvDataManagerTest, DeleteKvStore001, TestSize.Level1) * @tc.name: DeleteKvStore002 * @tc.desc: Delete an opened SingleKvStore, and the callback function should return SUCCESS. * @tc.type: FUNC -* @tc.require: SR000CQDU0 AR000BVTDM +* @tc.require: * @tc.author: liqiao */ HWTEST_F(DistributedKvDataManagerTest, DeleteKvStore002, TestSize.Level1) @@ -576,7 +673,7 @@ HWTEST_F(DistributedKvDataManagerTest, DeleteKvStore002, TestSize.Level1) * @tc.name: DeleteKvStore003 * @tc.desc: Delete a non-existing KvStore, and the callback function should return DB_ERROR. * @tc.type: FUNC -* @tc.require: SR000CQDU0 AR000BVTDM +* @tc.require: * @tc.author: liqiao */ HWTEST_F(DistributedKvDataManagerTest, DeleteKvStore003, TestSize.Level1) @@ -590,7 +687,7 @@ HWTEST_F(DistributedKvDataManagerTest, DeleteKvStore003, TestSize.Level1) * @tc.name: DeleteKvStore004 * @tc.desc: Delete a KvStore with an empty storeId, and the callback function should return INVALID_ARGUMENT. * @tc.type: FUNC -* @tc.require: SR000CQDU0 AR000BVTDM +* @tc.require: * @tc.author: liqiao */ HWTEST_F(DistributedKvDataManagerTest, DeleteKvStore004, TestSize.Level1) @@ -605,7 +702,7 @@ HWTEST_F(DistributedKvDataManagerTest, DeleteKvStore004, TestSize.Level1) * @tc.desc: Delete a KvStore with 65 bytes long storeId (which exceed storeId length limit). Should * return INVALID_ARGUMENT. * @tc.type: FUNC -* @tc.require: SR000CQDU0 AR000BVTDM +* @tc.require: * @tc.author: liqiao */ HWTEST_F(DistributedKvDataManagerTest, DeleteKvStore005, TestSize.Level1) @@ -619,7 +716,7 @@ HWTEST_F(DistributedKvDataManagerTest, DeleteKvStore005, TestSize.Level1) * @tc.name: DeleteAllKvStore001 * @tc.desc: Delete all KvStores after closing all of them, and the callback function should return SUCCESS. * @tc.type: FUNC -* @tc.require: SR000CQDU0 AR000BVTDM +* @tc.require: * @tc.author: liqiao */ HWTEST_F(DistributedKvDataManagerTest, DeleteAllKvStore001, TestSize.Level1) @@ -651,7 +748,7 @@ HWTEST_F(DistributedKvDataManagerTest, DeleteAllKvStore001, TestSize.Level1) * @tc.name: DeleteAllKvStore002 * @tc.desc: Delete all kvstore fail when any kvstore in the appId is not closed * @tc.type: FUNC -* @tc.require: SR000CQDU0 AR000BVTDM +* @tc.require: * @tc.author: liqiao */ HWTEST_F(DistributedKvDataManagerTest, DeleteAllKvStore002, TestSize.Level1) @@ -676,7 +773,7 @@ HWTEST_F(DistributedKvDataManagerTest, DeleteAllKvStore002, TestSize.Level1) * @tc.name: DeleteAllKvStore003 * @tc.desc: Delete all KvStores even if no KvStore exists in the appId. * @tc.type: FUNC -* @tc.require: SR000CQDU0 AR000BVTDM +* @tc.require: * @tc.author: liqiao */ HWTEST_F(DistributedKvDataManagerTest, DeleteAllKvStore003, TestSize.Level1) @@ -713,4 +810,100 @@ HWTEST_F(DistributedKvDataManagerTest, DeleteAllKvStore004, TestSize.Level1) stat = manager.DeleteAllKvStore(appId, create.baseDir); EXPECT_EQ(stat, Status::SUCCESS); } + +/** +* @tc.name: PutSwitchWithEmptyAppId +* @tc.desc: put switch data, but appId is empty. +* @tc.type: FUNC +* @tc.require: +* @tc.author: zuojiangjiang +*/ +HWTEST_F(DistributedKvDataManagerTest, PutSwitchWithEmptyAppId, TestSize.Level1) +{ + ZLOGI("PutSwitchWithEmptyAppId begin."); + SwitchData data; + Status status = manager.PutSwitch({ "" }, data); + ASSERT_EQ(status, Status::INVALID_ARGUMENT); +} + +/** +* @tc.name: PutSwitchWithInvalidAppId +* @tc.desc: put switch data, but appId is not 'distributed_device_profile_service'. +* @tc.type: FUNC +* @tc.require: +* @tc.author: zuojiangjiang +*/ +HWTEST_F(DistributedKvDataManagerTest, PutSwitchWithInvalidAppId, TestSize.Level1) +{ + ZLOGI("PutSwitchWithInvalidAppId begin."); + SwitchData data; + Status status = manager.PutSwitch({ "swicthes_test_appId" }, data); + ASSERT_EQ(status, Status::PERMISSION_DENIED); +} + +/** +* @tc.name: GetSwitchWithInvalidArg +* @tc.desc: get switch data, but appId is empty, networkId is invalid. +* @tc.type: FUNC +* @tc.require: +* @tc.author: zuojiangjiang +*/ +HWTEST_F(DistributedKvDataManagerTest, GetSwitchWithInvalidArg, TestSize.Level1) +{ + ZLOGI("GetSwitchWithInvalidArg begin."); + auto [status1, data1] = manager.GetSwitch({ "" }, "networkId_test"); + ASSERT_EQ(status1, Status::INVALID_ARGUMENT); + auto [status2, data2] = manager.GetSwitch({ "switches_test_appId" }, ""); + ASSERT_EQ(status2, Status::INVALID_ARGUMENT); + auto [status3, data3] = manager.GetSwitch({ "switches_test_appId" }, "networkId_test"); + ASSERT_EQ(status3, Status::PERMISSION_DENIED); +} + +/** +* @tc.name: GetSwitchWithInvalidAppId +* @tc.desc: get switch data, but appId is not 'distributed_device_profile_service'. +* @tc.type: FUNC +* @tc.require: +* @tc.author: zuojiangjiang +*/ +HWTEST_F(DistributedKvDataManagerTest, GetSwitchWithInvalidAppId, TestSize.Level1) +{ + ZLOGI("GetSwitchWithInvalidAppId begin."); + auto devInfo = DevManager::GetInstance().GetLocalDevice(); + EXPECT_NE(devInfo.networkId, ""); + auto [status, data] = manager.GetSwitch({ "switches_test_appId" }, devInfo.networkId); + ASSERT_EQ(status, Status::PERMISSION_DENIED); +} + +/** +* @tc.name: SubscribeSwitchesData +* @tc.desc: subscribe switch data. +* @tc.type: FUNC +* @tc.require: +* @tc.author: zuojiangjiang +*/ +HWTEST_F(DistributedKvDataManagerTest, SubscribeSwitchesData, TestSize.Level1) +{ + ZLOGI("SubscribeSwitchesData begin."); + std::shared_ptr observer = std::make_shared(); + auto status = manager.SubscribeSwitchData({ "switches_test_appId" }, observer); + ASSERT_EQ(status, Status::PERMISSION_DENIED); +} + +/** +* @tc.name: UnsubscribeSwitchesData +* @tc.desc: unsubscribe switch data. +* @tc.type: FUNC +* @tc.require: +* @tc.author: zuojiangjiang +*/ +HWTEST_F(DistributedKvDataManagerTest, UnsubscribeSwitchesData, TestSize.Level1) +{ + ZLOGI("UnsubscribeSwitchesData begin."); + std::shared_ptr observer = std::make_shared(); + auto status = manager.SubscribeSwitchData({ "switches_test_appId" }, observer); + ASSERT_EQ(status, Status::PERMISSION_DENIED); + status = manager.UnsubscribeSwitchData({ "switches_test_appId" }, observer); + ASSERT_EQ(status, Status::PERMISSION_DENIED); +} } // namespace OHOS::Test \ No newline at end of file diff --git a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/end_point_test.cpp b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/end_point_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4236aa4b0ca5fbdb584f620887f2029901401951 --- /dev/null +++ b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/end_point_test.cpp @@ -0,0 +1,214 @@ +/* + * 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 "dev_manager.h" +#include "distributed_kv_data_manager.h" +#include "file_ex.h" +#include "types.h" +#include +#include +#include +#include +#include + +using namespace testing::ext; +using namespace OHOS::DistributedKv; +namespace OHOS::Test { +class EndPointTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + static std::string GetKey(const std::string &key); + static std::shared_ptr kvStore_; // declare kvstore instance. + static Status status_; + static std::string deviceId_; + static Options options_; +}; + +const std::string VALID_SCHEMA = "{\"SCHEMA_VERSION\":\"1.0\"," + "\"SCHEMA_MODE\":\"STRICT\"," + "\"SCHEMA_SKIPSIZE\":0," + "\"SCHEMA_DEFINE\":{" + "\"age\":\"INTEGER, NOT NULL\"" + "}," + "\"SCHEMA_INDEXES\":[\"$.age\"]}"; + +std::shared_ptr EndPointTest::kvStore_ = nullptr; +Status EndPointTest::status_ = Status::ERROR; +std::string EndPointTest::deviceId_; +Options EndPointTest::options_; + +void EndPointTest::SetUpTestCase(void) +{ + DistributedKvDataManager manager; + options_.area = EL1; + options_.baseDir = std::string("/data/service/el1/public/database/odmf"); + options_.securityLevel = S1; + options_.isClientSync = true; + mkdir(options_.baseDir.c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)); + AppId appId = { "odmf" }; + StoreId storeId = { "student_device" }; // define kvstore(database) name. + // [create and] open and initialize kvstore instance. + status_ = manager.GetSingleKvStore(options_, appId, storeId, kvStore_); + auto deviceInfo = DevManager::GetInstance().GetLocalDevice(); + deviceId_ = deviceInfo.networkId; +} + +void EndPointTest::TearDownTestCase(void) +{ + DistributedKvDataManager manager; + AppId appId = { "odmf" }; + manager.DeleteAllKvStore(appId, options_.baseDir); + (void)remove("/data/service/el1/public/database/odmf/key"); + (void)remove("/data/service/el1/public/database/odmf/kvdb"); + (void)remove("/data/service/el1/public/database/odmf"); +} + +void EndPointTest::SetUp(void) { } + +void EndPointTest::TearDown(void) { } + +std::string EndPointTest::GetKey(const std::string &key) +{ + std::ostringstream oss; + oss << std::setfill('0') << std::setw(sizeof(uint32_t)) << deviceId_.length(); + oss << deviceId_ << std::string(key.begin(), key.end()); + return oss.str(); +} + +class EndpointMock : public Endpoint { +public: + EndpointMock() { } + virtual ~EndpointMock() { } + + Status Start() override + { + return Status::SUCCESS; + } + + Status Stop() override + { + return Status::SUCCESS; + } + + Status RegOnDataReceive(const RecvHandler &callback) override + { + return Status::SUCCESS; + } + + Status SendData(const std::string &dtsIdentifier, const uint8_t *data, uint32_t length) override + { + return Status::SUCCESS; + } + + uint32_t GetMtuSize(const std::string &identifier) override + { + return 1 * 1024 * 1024; // 1 * 1024 * 1024 Byte. + } + + std::string GetLocalDeviceInfos() override + { + return "Mock Device"; + } + + bool IsSaferThanDevice(int securityLevel, const std::string &devId) override + { + return true; + } + + bool HasDataSyncPermission(const StoreBriefInfo ¶m, uint8_t flag) override + { + return true; + } +}; + +/** + * @tc.name: SetEndpoint001 + * @tc.desc: test the SetEndpoint(std::shared_ptr endpoint) + * @tc.type: FUNC + * @tc.require: + * @tc.author: SQL + */ +HWTEST_F(EndPointTest, SetEndpoint001, TestSize.Level1) +{ + DistributedKvDataManager manager; + std::shared_ptr endpoint = nullptr; + Status status = manager.SetEndpoint(endpoint); + ASSERT_EQ(status, Status::INVALID_ARGUMENT); +} + +/** + * @tc.name: SetEndpoint002 + * @tc.desc: test the SetEndpoint(std::shared_ptr endpoint) + * @tc.type: FUNC + * @tc.require: + * @tc.author: SQL + */ +HWTEST_F(EndPointTest, SetEndpoint002, TestSize.Level1) +{ + DistributedKvDataManager manager; + std::shared_ptr endpoint = std::make_shared(); + Status status = manager.SetEndpoint(endpoint); + EXPECT_EQ(status, Status::SUCCESS); + status = manager.SetEndpoint(endpoint); + EXPECT_EQ(status, Status::SUCCESS); +} + +/** + * @tc.name: SetIdentifier001 + * desc: test the Status set identifier function. + * type: FUNC + * require: + * author:SQL + */ +HWTEST_F(EndPointTest, SetIdentifier001, TestSize.Level1) +{ + DistributedKvDataManager manager; + EXPECT_NE(kvStore_, nullptr) << "kvStorePtr is null."; + AppId appId = { "odmf" }; + StoreId storeId = { "test_storeid" }; + std::vector targetDev = { "devicid1", "devicid2" }; + std::string accountId = "testAccount"; + std::shared_ptr endpoint = std::make_shared(); + Status status = manager.SetEndpoint(endpoint); + EXPECT_EQ(status, Status::SUCCESS); + auto testStatus = kvStore_->SetIdentifier(accountId, appId, storeId, targetDev); + EXPECT_EQ(testStatus, Status::SUCCESS); +} + +/** + * @tc.name: SetIdentifier002 + * desc: test the Status set identifier function. + * type: FUNC + * require: + * author:SQL + */ +HWTEST_F(EndPointTest, SetIdentifier002, TestSize.Level1) +{ + DistributedKvDataManager manager; + EXPECT_NE(kvStore_, nullptr) << "kvStorePtr is null."; + AppId appId = { "" }; + StoreId storeId = { "" }; + std::vector targetDev = { "devicid1", "devicid2" }; + std::string accountId = "testAccount"; + std::shared_ptr endpoint = std::make_shared(); + Status status = manager.SetEndpoint(endpoint); + EXPECT_EQ(status, Status::SUCCESS); + auto testStatus = kvStore_->SetIdentifier(accountId, appId, storeId, targetDev); + EXPECT_NE(testStatus, Status::SUCCESS); +} +} // namespace OHOS::Test \ No newline at end of file diff --git a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/kv_utils_test.cpp b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/kv_utils_test.cpp index bee8cb970e9dbcb9d989b6db14a372e870f8dd73..deb64e369b18ce77886fd446d364106a1646e58a 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/kv_utils_test.cpp +++ b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/kv_utils_test.cpp @@ -13,19 +13,19 @@ * limitations under the License. */ -#include -#include -#include #include "datashare_predicates.h" #include "datashare_values_bucket.h" #include "distributed_kv_data_manager.h" -#include "gtest/gtest.h" #include "kv_utils.h" #include "kvstore_datashare_bridge.h" #include "kvstore_result_set.h" #include "result_set_bridge.h" #include "store_errno.h" #include "types.h" +#include "gtest/gtest.h" +#include +#include +#include namespace { using namespace testing::ext; @@ -36,8 +36,8 @@ class KvUtilTest : public testing::Test { public: static void SetUpTestCase(void); static void TearDownTestCase(void); - void SetUp() {} - void TearDown() {} + void SetUp() { } + void TearDown() { } protected: static DistributedKvDataManager manager; @@ -98,16 +98,16 @@ Blob KvUtilTest::VariantValue2Blob(const var_t &value) auto dblValue = std::get_if(&value); if (dblValue != nullptr) { double tmp4dbl = *dblValue; - uint64_t tmp64 = htobe64(*reinterpret_cast(&tmp4dbl)); - tmp = reinterpret_cast(&tmp64); + uint64_t tmp64 = htobe64(*reinterpret_cast(&tmp4dbl)); + tmp = reinterpret_cast(&tmp64); data.push_back(KvUtils::DOUBLE); data.insert(data.end(), tmp, tmp + sizeof(double) / sizeof(uint8_t)); } auto intValue = std::get_if(&value); if (intValue != nullptr) { int64_t tmp4int = *intValue; - uint64_t tmp64 = htobe64(*reinterpret_cast(&tmp4int)); - tmp = reinterpret_cast(&tmp64); + uint64_t tmp64 = htobe64(*reinterpret_cast(&tmp4int)); + tmp = reinterpret_cast(&tmp64); data.push_back(KvUtils::INTEGER); data.insert(data.end(), tmp, tmp + sizeof(int64_t) / sizeof(uint8_t)); } @@ -121,8 +121,11 @@ Blob KvUtilTest::VariantValue2Blob(const var_t &value) void KvUtilTest::SetUpTestCase(void) { - Options options = {.createIfMissing = true, .encrypt = false, .autoSync = false, - .kvStoreType = KvStoreType::SINGLE_VERSION, .schema = VALID_SCHEMA_STRICT_DEFINE}; + Options options = { .createIfMissing = true, + .encrypt = false, + .autoSync = false, + .kvStoreType = KvStoreType::SINGLE_VERSION, + .schema = VALID_SCHEMA_STRICT_DEFINE }; options.area = EL1; options.securityLevel = S1; options.baseDir = std::string("/data/service/el1/public/database/kvUtilTest"); @@ -140,20 +143,19 @@ void KvUtilTest::SetUpTestCase(void) void KvUtilTest::TearDownTestCase(void) { - manager.DeleteKvStore( - {"kvUtilTest"}, {"test_single"}, "/data/service/el1/public/database/kvUtilTest"); - (void) remove("/data/service/el1/public/database/kvUtilTest/key"); - (void) remove("/data/service/el1/public/database/kvUtilTest/kvdb"); - (void) remove("/data/service/el1/public/database/kvUtilTest"); + manager.DeleteKvStore({ "kvUtilTest" }, { "test_single" }, "/data/service/el1/public/database/kvUtilTest"); + (void)remove("/data/service/el1/public/database/kvUtilTest/key"); + (void)remove("/data/service/el1/public/database/kvUtilTest/kvdb"); + (void)remove("/data/service/el1/public/database/kvUtilTest"); } /** -* @tc.name: KvStoreResultSetToResultSetBridge -* @tc.desc: kvStore resultSet to resultSet bridge, the former is nullptr -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: KvStoreResultSetToResultSetBridge + * @tc.desc: kvStore resultSet to resultSet bridge, the former is nullptr + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(KvUtilTest, KvStoreResultSetToResultSetBridgeAbnormal, TestSize.Level0) { std::shared_ptr resultSet = nullptr; @@ -162,12 +164,12 @@ HWTEST_F(KvUtilTest, KvStoreResultSetToResultSetBridgeAbnormal, TestSize.Level0) } /** -* @tc.name: KvStoreResultSetToResultSetBridge -* @tc.desc: kvStore resultSet to resultSet bridge -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: KvStoreResultSetToResultSetBridge + * @tc.desc: kvStore resultSet to resultSet bridge + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(KvUtilTest, KvStoreResultSetToResultSetBridge, TestSize.Level0) { DataSharePredicates predicates; @@ -185,12 +187,12 @@ HWTEST_F(KvUtilTest, KvStoreResultSetToResultSetBridge, TestSize.Level0) } /** -* @tc.name: PredicatesToQuery -* @tc.desc: to query equalTo -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: PredicatesToQuery + * @tc.desc: to query equalTo + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(KvUtilTest, PredicatesToQueryEqualTo, TestSize.Level0) { DataSharePredicates predicates; @@ -204,12 +206,12 @@ HWTEST_F(KvUtilTest, PredicatesToQueryEqualTo, TestSize.Level0) } /** -* @tc.name: PredicatesToQuery -* @tc.desc: to query not equalTo -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: PredicatesToQuery + * @tc.desc: to query not equalTo + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(KvUtilTest, PredicatesToQueryNotEqualTo, TestSize.Level0) { DataSharePredicates predicates; @@ -223,12 +225,12 @@ HWTEST_F(KvUtilTest, PredicatesToQueryNotEqualTo, TestSize.Level0) } /** -* @tc.name: PredicatesToQuery -* @tc.desc: to query greater than -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: PredicatesToQuery + * @tc.desc: to query greater than + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(KvUtilTest, PredicatesToQueryGreaterThan, TestSize.Level0) { DataSharePredicates predicates; @@ -242,12 +244,12 @@ HWTEST_F(KvUtilTest, PredicatesToQueryGreaterThan, TestSize.Level0) } /** -* @tc.name: PredicatesToQuery -* @tc.desc: to query less than -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: PredicatesToQuery + * @tc.desc: to query less than + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(KvUtilTest, PredicatesToQueryLessThan, TestSize.Level0) { DataSharePredicates predicates; @@ -261,12 +263,12 @@ HWTEST_F(KvUtilTest, PredicatesToQueryLessThan, TestSize.Level0) } /** -* @tc.name: PredicatesToQuery -* @tc.desc: to query greater than or equalTo -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: PredicatesToQuery + * @tc.desc: to query greater than or equalTo + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(KvUtilTest, PredicatesToQueryGreaterThanOrEqualTo, TestSize.Level0) { DataSharePredicates predicates; @@ -280,12 +282,12 @@ HWTEST_F(KvUtilTest, PredicatesToQueryGreaterThanOrEqualTo, TestSize.Level0) } /** -* @tc.name: PredicatesToQuery -* @tc.desc: to query less than or equalTo -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: PredicatesToQuery + * @tc.desc: to query less than or equalTo + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(KvUtilTest, PredicatesToQueryLessThanOrEqualTo, TestSize.Level0) { DataSharePredicates predicates; @@ -299,15 +301,15 @@ HWTEST_F(KvUtilTest, PredicatesToQueryLessThanOrEqualTo, TestSize.Level0) } /** -* @tc.name: PredicatesToQuery -* @tc.desc: to query in -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: PredicatesToQuery + * @tc.desc: to query in + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(KvUtilTest, PredicatesToQueryIn, TestSize.Level0) { - std::vector vectInt{ 1, 2 }; + std::vector vectInt { 1, 2 }; DataSharePredicates predicates; predicates.In("$.age", vectInt); DataQuery query; @@ -319,15 +321,15 @@ HWTEST_F(KvUtilTest, PredicatesToQueryIn, TestSize.Level0) } /** -* @tc.name: PredicatesToQuery -* @tc.desc: to query not in -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: PredicatesToQuery + * @tc.desc: to query not in + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(KvUtilTest, PredicatesToQueryNotIn, TestSize.Level0) { - std::vector vectInt{ 1, 2 }; + std::vector vectInt { 1, 2 }; DataSharePredicates predicates; predicates.NotIn("$.age", vectInt); DataQuery query; @@ -339,12 +341,12 @@ HWTEST_F(KvUtilTest, PredicatesToQueryNotIn, TestSize.Level0) } /** -* @tc.name: PredicatesToQuery -* @tc.desc: to query or, like -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: PredicatesToQuery + * @tc.desc: to query or, like + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(KvUtilTest, PredicatesToQueryLike, TestSize.Level0) { DataSharePredicates predicates; @@ -362,12 +364,12 @@ HWTEST_F(KvUtilTest, PredicatesToQueryLike, TestSize.Level0) } /** -* @tc.name: PredicatesToQuery -* @tc.desc: to query and, unlike -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: PredicatesToQuery + * @tc.desc: to query and, unlike + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(KvUtilTest, PredicatesToQueryUnlike, TestSize.Level0) { DataSharePredicates predicates; @@ -385,12 +387,12 @@ HWTEST_F(KvUtilTest, PredicatesToQueryUnlike, TestSize.Level0) } /** -* @tc.name: PredicatesToQuery -* @tc.desc: to query is null -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: PredicatesToQuery + * @tc.desc: to query is null + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(KvUtilTest, PredicatesToQueryIsNull, TestSize.Level0) { DataSharePredicates predicates; @@ -404,12 +406,12 @@ HWTEST_F(KvUtilTest, PredicatesToQueryIsNull, TestSize.Level0) } /** -* @tc.name: PredicatesToQuery -* @tc.desc: to query is not null -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: PredicatesToQuery + * @tc.desc: to query is not null + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(KvUtilTest, PredicatesToQueryIsNotNull, TestSize.Level0) { DataSharePredicates predicates; @@ -423,12 +425,12 @@ HWTEST_F(KvUtilTest, PredicatesToQueryIsNotNull, TestSize.Level0) } /** -* @tc.name: PredicatesToQuery -* @tc.desc: to query is order by asc -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: PredicatesToQuery + * @tc.desc: to query is order by asc + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(KvUtilTest, PredicatesToQueryOrderByAsc, TestSize.Level0) { DataSharePredicates predicates; @@ -442,12 +444,12 @@ HWTEST_F(KvUtilTest, PredicatesToQueryOrderByAsc, TestSize.Level0) } /** -* @tc.name: PredicatesToQuery -* @tc.desc: to query is order by desc -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: PredicatesToQuery + * @tc.desc: to query is order by desc + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(KvUtilTest, PredicatesToQueryOrderByDesc, TestSize.Level0) { DataSharePredicates predicates; @@ -461,12 +463,12 @@ HWTEST_F(KvUtilTest, PredicatesToQueryOrderByDesc, TestSize.Level0) } /** -* @tc.name: PredicatesToQuery -* @tc.desc: to query is limit -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: PredicatesToQuery + * @tc.desc: to query is limit + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(KvUtilTest, PredicatesToQueryLimit, TestSize.Level0) { DataSharePredicates predicates; @@ -480,12 +482,12 @@ HWTEST_F(KvUtilTest, PredicatesToQueryLimit, TestSize.Level0) } /** -* @tc.name: PredicatesToQuery -* @tc.desc: to query is in keys -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: PredicatesToQuery + * @tc.desc: to query is in keys + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(KvUtilTest, PredicatesToQueryInKeys, TestSize.Level0) { std::vector keys { "test_field", "", "^test_field", "^", "test_field_name" }; @@ -500,12 +502,12 @@ HWTEST_F(KvUtilTest, PredicatesToQueryInKeys, TestSize.Level0) } /** -* @tc.name: ToEntry -* @tc.desc: dataShare values bucket to entry, the bucket is invalid -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: ToEntry + * @tc.desc: dataShare values bucket to entry, the bucket is invalid + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(KvUtilTest, DataShareValuesBucketToEntryAbnormal, TestSize.Level0) { DataShareValuesBucket bucket {}; @@ -522,12 +524,12 @@ HWTEST_F(KvUtilTest, DataShareValuesBucketToEntryAbnormal, TestSize.Level0) } /** -* @tc.name: ToEntry -* @tc.desc: dataShare values bucket to entry, the bucket value is null -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: ToEntry + * @tc.desc: dataShare values bucket to entry, the bucket value is null + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(KvUtilTest, DataShareValuesBucketToEntryNull, TestSize.Level0) { DataShareValuesBucket bucket {}; @@ -539,12 +541,12 @@ HWTEST_F(KvUtilTest, DataShareValuesBucketToEntryNull, TestSize.Level0) } /** -* @tc.name: ToEntry -* @tc.desc: dataShare values bucket to entry, the bucket value type is int64_t -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: ToEntry + * @tc.desc: dataShare values bucket to entry, the bucket value type is int64_t + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(KvUtilTest, DataShareValuesBucketToEntryInt64_t, TestSize.Level0) { DataShareValuesBucket bucket {}; @@ -562,12 +564,12 @@ HWTEST_F(KvUtilTest, DataShareValuesBucketToEntryInt64_t, TestSize.Level0) } /** -* @tc.name: ToEntry -* @tc.desc: dataShare values bucket to entry, the bucket value type is double -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: ToEntry + * @tc.desc: dataShare values bucket to entry, the bucket value type is double + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(KvUtilTest, DataShareValuesBucketToEntryDouble, TestSize.Level0) { DataShareValuesBucket bucket {}; @@ -585,12 +587,12 @@ HWTEST_F(KvUtilTest, DataShareValuesBucketToEntryDouble, TestSize.Level0) } /** -* @tc.name: ToEntry -* @tc.desc: dataShare values bucket to entry, the bucket value type is string -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: ToEntry + * @tc.desc: dataShare values bucket to entry, the bucket value type is string + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(KvUtilTest, DataShareValuesBucketToEntryString, TestSize.Level0) { DataShareValuesBucket bucket {}; @@ -608,12 +610,12 @@ HWTEST_F(KvUtilTest, DataShareValuesBucketToEntryString, TestSize.Level0) } /** -* @tc.name: ToEntry -* @tc.desc: dataShare values bucket to entry, the bucket value type is bool -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: ToEntry + * @tc.desc: dataShare values bucket to entry, the bucket value type is bool + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(KvUtilTest, DataShareValuesBucketToEntryBool, TestSize.Level0) { DataShareValuesBucket bucket {}; @@ -631,12 +633,12 @@ HWTEST_F(KvUtilTest, DataShareValuesBucketToEntryBool, TestSize.Level0) } /** -* @tc.name: ToEntry -* @tc.desc: dataShare values bucket to entry, the bucket value type is uint8array -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: ToEntry + * @tc.desc: dataShare values bucket to entry, the bucket value type is uint8array + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(KvUtilTest, DataShareValuesBucketToEntryUint8Array, TestSize.Level0) { DataShareValuesBucket bucket {}; @@ -655,12 +657,12 @@ HWTEST_F(KvUtilTest, DataShareValuesBucketToEntryUint8Array, TestSize.Level0) } /** -* @tc.name: ToEntry -* @tc.desc: dataShare values bucket to entry, the bucket key type is not string -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: ToEntry + * @tc.desc: dataShare values bucket to entry, the bucket key type is not string + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(KvUtilTest, DataShareValuesBucketToEntryInvalidKey, TestSize.Level0) { DataShareValuesBucket bucket {}; @@ -678,12 +680,12 @@ HWTEST_F(KvUtilTest, DataShareValuesBucketToEntryInvalidKey, TestSize.Level0) } /** -* @tc.name: ToEntry -* @tc.desc: dataShare values bucket to entries, the buckets is invalid -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: ToEntry + * @tc.desc: dataShare values bucket to entries, the buckets is invalid + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(KvUtilTest, DataShareValuesBucketToEntriesAbnormal, TestSize.Level0) { std::vector buckets {}; @@ -692,12 +694,12 @@ HWTEST_F(KvUtilTest, DataShareValuesBucketToEntriesAbnormal, TestSize.Level0) } /** -* @tc.name: ToEntry -* @tc.desc: dataShare values bucket to entries, the buckets has valid value -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: ToEntry + * @tc.desc: dataShare values bucket to entries, the buckets has valid value + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(KvUtilTest, DataShareValuesBucketToEntriesNormal, TestSize.Level0) { std::vector buckets {}; @@ -728,12 +730,12 @@ HWTEST_F(KvUtilTest, DataShareValuesBucketToEntriesNormal, TestSize.Level0) } /** -* @tc.name: GetKeys -* @tc.desc: get keys from data share predicates, the predicates is invalid -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: GetKeys + * @tc.desc: get keys from data share predicates, the predicates is invalid + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(KvUtilTest, GetKeysFromDataSharePredicatesAbnormal, TestSize.Level0) { DataSharePredicates predicates; @@ -746,12 +748,12 @@ HWTEST_F(KvUtilTest, GetKeysFromDataSharePredicatesAbnormal, TestSize.Level0) } /** -* @tc.name: GetKeys -* @tc.desc: get keys from data share predicates, the predicates has valid value -* @tc.type: FUNC -* @tc.require: -* @tc.author: zuojiangjiang -*/ + * @tc.name: GetKeys + * @tc.desc: get keys from data share predicates, the predicates has valid value + * @tc.type: FUNC + * @tc.require: + * @tc.author: zuojiangjiang + */ HWTEST_F(KvUtilTest, GetKeysFromDataSharePredicatesNormal, TestSize.Level0) { std::vector keys { "test_field", "", "^test_field", "^", "test_field_name" }; diff --git a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/kvstore_datashare_bridge_test.cpp b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/kvstore_datashare_bridge_test.cpp index f04742b77a3afffa73ad4e64fb42c6eddd3d4bd6..c7ac38b0675efacc0173e7bd93e01333854625de 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/kvstore_datashare_bridge_test.cpp +++ b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/kvstore_datashare_bridge_test.cpp @@ -29,6 +29,7 @@ using namespace OHOS::DataShare; class BridgeWriter final : public ResultSetBridge::Writer { public: int AllocRow() override; + int FreeLastRow() override; int Write(uint32_t column) override; int Write(uint32_t column, int64_t value) override; int Write(uint32_t column, double value) override; @@ -64,6 +65,11 @@ int BridgeWriter::AllocRow() return allocStatus_; } +int BridgeWriter::FreeLastRow() +{ + return E_OK; +} + int BridgeWriter::Write(uint32_t column) { return E_OK; @@ -141,9 +147,8 @@ void KvstoreDatashareBridgeTest::SetUpTestCase(void) void KvstoreDatashareBridgeTest::TearDownTestCase(void) { - manager.DeleteKvStore( - {"KvstoreDatashareBridgeTest"}, {"test_single"}, - "/data/service/el1/public/database/KvstoreDatashareBridgeTest"); + manager.DeleteKvStore({"KvstoreDatashareBridgeTest"}, {"test_single"}, + "/data/service/el1/public/database/KvstoreDatashareBridgeTest"); (void) remove("/data/service/el1/public/database/KvstoreDatashareBridgeTest/key"); (void) remove("/data/service/el1/public/database/KvstoreDatashareBridgeTest/kvdb"); (void) remove("/data/service/el1/public/database/KvstoreDatashareBridgeTest"); diff --git a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/local_subscribe_device_store_test.cpp b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/local_subscribe_device_store_test.cpp index 1da928321ae061be42f97a120bf30b4ea0fd31ea..e28207fbcab9ad77b1a817b1001c55781b7e1ad9 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/local_subscribe_device_store_test.cpp +++ b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/local_subscribe_device_store_test.cpp @@ -172,7 +172,7 @@ HWTEST_F(LocalSubscribeDeviceStoreTest, KvStoreDdmSubscribeKvStore001, TestSize. * @tc.name: KvStoreDdmSubscribeKvStore002 * @tc.desc: Subscribe fail, observer is null * @tc.type: FUNC -* @tc.require: AR000CQDU9 AR000CQS37 +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeDeviceStoreTest, KvStoreDdmSubscribeKvStore002, TestSize.Level1) diff --git a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/local_subscribe_store_test.cpp b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/local_subscribe_store_test.cpp index 517324f2f10f22bd2f2866c9a11d60c1bfbb3f98..f837d74bfc5100a7b8801438b49863ceae2b431d 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/local_subscribe_store_test.cpp +++ b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/local_subscribe_store_test.cpp @@ -161,7 +161,7 @@ uint32_t KvStoreObserverUnitTest::GetCallCount(uint32_t value) * @tc.name: KvStoreDdmSubscribeKvStore001 * @tc.desc: Subscribe success * @tc.type: FUNC -* @tc.require: AR000CQDU9 AR000CQS37 +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore001, TestSize.Level1) @@ -184,7 +184,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore001, TestSize.Level1 * @tc.name: KvStoreDdmSubscribeKvStore002 * @tc.desc: Subscribe fail, observer is null * @tc.type: FUNC -* @tc.require: AR000CQDU9 AR000CQS37 +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore002, TestSize.Level1) @@ -200,7 +200,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore002, TestSize.Level1 * @tc.name: KvStoreDdmSubscribeKvStore003 * @tc.desc: Subscribe success and OnChange callback after put * @tc.type: FUNC -* @tc.require: AR000CQDU9 AR000CQS37 +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore003, TestSize.Level1) @@ -227,7 +227,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore003, TestSize.Level1 * @tc.name: KvStoreDdmSubscribeKvStore004 * @tc.desc: The same observer subscribe three times and OnChange callback after put * @tc.type: FUNC -* @tc.require: AR000CQDU9 AR000CQS37 +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore004, TestSize.Level2) @@ -256,7 +256,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore004, TestSize.Level2 * @tc.name: KvStoreDdmSubscribeKvStore005 * @tc.desc: The different observer subscribe three times and OnChange callback after put * @tc.type: FUNC -* @tc.require: AR000CQDU9 AR000CQS37 +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore005, TestSize.Level2) @@ -293,7 +293,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore005, TestSize.Level2 * @tc.name: KvStoreDdmSubscribeKvStore006 * @tc.desc: Unsubscribe an observer and subscribe again - the map should be cleared after unsubscription. * @tc.type: FUNC -* @tc.require: AR000CQDU9 AR000CQS37 +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore006, TestSize.Level2) @@ -336,7 +336,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore006, TestSize.Level2 * @tc.name: KvStoreDdmSubscribeKvStore007 * @tc.desc: Subscribe to an observer - OnChange callback is called multiple times after the put operation. * @tc.type: FUNC -* @tc.require: AR000CQDU9 AR000CQS37 +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore007, TestSize.Level2) @@ -371,7 +371,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore007, TestSize.Level2 * @tc.name: KvStoreDdmSubscribeKvStore008 * @tc.desc: Subscribe to an observer - OnChange callback is called multiple times after the put&update operations. * @tc.type: FUNC -* @tc.require: AR000CQDU9 AR000CQS37 +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore008, TestSize.Level2) @@ -405,7 +405,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore008, TestSize.Level2 * @tc.name: KvStoreDdmSubscribeKvStore009 * @tc.desc: Subscribe to an observer - OnChange callback is called multiple times after the putBatch operation. * @tc.type: FUNC -* @tc.require: AR000CQDU9 AR000CQS37 +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore009, TestSize.Level2) @@ -452,7 +452,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore009, TestSize.Level2 * @tc.name: KvStoreDdmSubscribeKvStore010 * @tc.desc: Subscribe to an observer - OnChange callback is called multiple times after the putBatch update operation. * @tc.type: FUNC -* @tc.require: AR000CQDU9 AR000CQS37 +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore010, TestSize.Level2) @@ -499,7 +499,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore010, TestSize.Level2 * @tc.name: KvStoreDdmSubscribeKvStore011 * @tc.desc: Subscribe to an observer - OnChange callback is called after successful deletion. * @tc.type: FUNC -* @tc.require: AR000CQDU9 AR000CQS37 +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore011, TestSize.Level2) @@ -536,7 +536,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore011, TestSize.Level2 * @tc.name: KvStoreDdmSubscribeKvStore012 * @tc.desc: Subscribe to an observer - OnChange callback is not called after deletion of non-existing keys. * @tc.type: FUNC -* @tc.require: AR000CQDU9 AR000CQS37 +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore012, TestSize.Level2) @@ -573,7 +573,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore012, TestSize.Level2 * @tc.name: KvStoreDdmSubscribeKvStore013 * @tc.desc: Subscribe to an observer - OnChange callback is called after KvStore is cleared. * @tc.type: FUNC -* @tc.require: AR000CQDU9 AR000CQS37 +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore013, TestSize.Level2) @@ -608,7 +608,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore013, TestSize.Level2 * @tc.name: KvStoreDdmSubscribeKvStore014 * @tc.desc: Subscribe to an observer - OnChange callback is not called after non-existing data in KvStore is cleared. * @tc.type: FUNC -* @tc.require: AR000CQDU9 AR000CQS37 +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore014, TestSize.Level2) @@ -628,7 +628,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore014, TestSize.Level2 * @tc.name: KvStoreDdmSubscribeKvStore015 * @tc.desc: Subscribe to an observer - OnChange callback is called after the deleteBatch operation. * @tc.type: FUNC -* @tc.require: AR000CQDU9 AR000CQS37 +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore015, TestSize.Level2) @@ -670,7 +670,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore015, TestSize.Level2 * @tc.name: KvStoreDdmSubscribeKvStore016 * @tc.desc: Subscribe to an observer - OnChange callback is called after deleteBatch of non-existing keys. * @tc.type: FUNC -* @tc.require: AR000CQDU9 AR000CQS37 +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore016, TestSize.Level2) @@ -712,7 +712,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore016, TestSize.Level2 * @tc.name: KvStoreDdmSubscribeKvStore020 * @tc.desc: Unsubscribe an observer two times. * @tc.type: FUNC -* @tc.require: AR000CQDU9 AR000CQS37 +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore020, TestSize.Level2) @@ -733,7 +733,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStore020, TestSize.Level2 * @tc.name: KvStoreDdmSubscribeKvStoreNotification001 * @tc.desc: Subscribe to an observer successfully - callback is called with a notification after the put operation. * @tc.type: FUNC -* @tc.require: AR000CIFGM +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification001, TestSize.Level1) @@ -763,7 +763,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification001, Tes * @tc.name: KvStoreDdmSubscribeKvStoreNotification002 * @tc.desc: Subscribe to the same observer three times - callback is called with a notification after the put operation. * @tc.type: FUNC -* @tc.require: AR000CIFGM +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification002, TestSize.Level2) @@ -795,7 +795,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification002, Tes * @tc.name: KvStoreDdmSubscribeKvStoreNotification003 * @tc.desc: The different observer subscribe three times and callback with notification after put * @tc.type: FUNC -* @tc.require: AR000CIFGM +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification003, TestSize.Level2) @@ -843,7 +843,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification003, Tes * @tc.name: KvStoreDdmSubscribeKvStoreNotification004 * @tc.desc: Verify notification after an observer is unsubscribed and then subscribed again. * @tc.type: FUNC -* @tc.require: AR000CIFGM +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification004, TestSize.Level2) @@ -895,7 +895,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification004, Tes * @tc.name: KvStoreDdmSubscribeKvStoreNotification005 * @tc.desc: Subscribe to an observer, callback with notification many times after put the different data * @tc.type: FUNC -* @tc.require: AR000CIFGM +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification005, TestSize.Level2) @@ -941,7 +941,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification005, Tes * @tc.name: KvStoreDdmSubscribeKvStoreNotification006 * @tc.desc: Subscribe to an observer, callback with notification many times after put the same data * @tc.type: FUNC -* @tc.require: AR000CIFGM +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification006, TestSize.Level2) @@ -987,7 +987,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification006, Tes * @tc.name: KvStoreDdmSubscribeKvStoreNotification007 * @tc.desc: Subscribe to an observer, callback with notification many times after put&update * @tc.type: FUNC -* @tc.require: AR000CIFGM +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification007, TestSize.Level2) @@ -1026,7 +1026,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification007, Tes * @tc.name: KvStoreDdmSubscribeKvStoreNotification008 * @tc.desc: Subscribe to an observer, callback with notification one times after putbatch&update * @tc.type: FUNC -* @tc.require: AR000CIFGM +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification008, TestSize.Level2) @@ -1077,7 +1077,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification008, Tes * @tc.name: KvStoreDdmSubscribeKvStoreNotification009 * @tc.desc: Subscribe to an observer, callback with notification one times after putbatch all different data * @tc.type: FUNC -* @tc.require: AR000CIFGM +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification009, TestSize.Level2) @@ -1120,7 +1120,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification009, Tes * @tc.name: KvStoreDdmSubscribeKvStoreNotification010 * @tc.desc: Subscribe to an observer, callback with notification one times after putbatch both different and same data * @tc.type: FUNC -* @tc.require: AR000CIFGM +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification010, TestSize.Level2) @@ -1163,7 +1163,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification010, Tes * @tc.name: KvStoreDdmSubscribeKvStoreNotification011 * @tc.desc: Subscribe to an observer, callback with notification one times after putbatch all same data * @tc.type: FUNC -* @tc.require: AR000CIFGM +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification011, TestSize.Level2) @@ -1204,7 +1204,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification011, Tes * @tc.name: KvStoreDdmSubscribeKvStoreNotification012 * @tc.desc: Subscribe to an observer, callback with notification many times after putbatch all different data * @tc.type: FUNC -* @tc.require: AR000CIFGM +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification012, TestSize.Level2) @@ -1265,7 +1265,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification012, Tes * @tc.name: KvStoreDdmSubscribeKvStoreNotification013 * @tc.desc: Subscribe to an observer, callback with notification many times after putbatch both different and same data * @tc.type: FUNC -* @tc.require: AR000CIFGM +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification013, TestSize.Level2) @@ -1327,7 +1327,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification013, Tes * @tc.name: KvStoreDdmSubscribeKvStoreNotification014 * @tc.desc: Subscribe to an observer, callback with notification many times after putbatch all same data * @tc.type: FUNC -* @tc.require: AR000CIFGM +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification014, TestSize.Level2) @@ -1388,7 +1388,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification014, Tes * @tc.name: KvStoreDdmSubscribeKvStoreNotification015 * @tc.desc: Subscribe to an observer, callback with notification many times after putbatch complex data * @tc.type: FUNC -* @tc.require: AR000CIFGM +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification015, TestSize.Level2) @@ -1450,7 +1450,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification015, Tes * @tc.name: KvStoreDdmSubscribeKvStoreNotification016 * @tc.desc: Pressure test subscribe, callback with notification many times after putbatch * @tc.type: FUNC -* @tc.require: AR000CIFGM +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification016, TestSize.Level2) @@ -1483,7 +1483,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification016, Tes * @tc.name: KvStoreDdmSubscribeKvStoreNotification017 * @tc.desc: Subscribe to an observer, callback with notification after delete success * @tc.type: FUNC -* @tc.require: AR000CIFGM +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification017, TestSize.Level2) @@ -1523,7 +1523,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification017, Tes * @tc.name: KvStoreDdmSubscribeKvStoreNotification018 * @tc.desc: Subscribe to an observer, not callback after delete which key not exist * @tc.type: FUNC -* @tc.require: AR000CIFGM +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification018, TestSize.Level2) @@ -1561,7 +1561,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification018, Tes * @tc.name: KvStoreDdmSubscribeKvStoreNotification019 * @tc.desc: Subscribe to an observer, delete the same data many times and only first delete callback with notification * @tc.type: FUNC -* @tc.require: AR000CIFGM +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification019, TestSize.Level2) @@ -1606,7 +1606,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification019, Tes * @tc.name: KvStoreDdmSubscribeKvStoreNotification020 * @tc.desc: Subscribe to an observer, callback with notification after deleteBatch * @tc.type: FUNC -* @tc.require: AR000CIFGM +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification020, TestSize.Level2) @@ -1653,7 +1653,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification020, Tes * @tc.name: KvStoreDdmSubscribeKvStoreNotification021 * @tc.desc: Subscribe to an observer, not callback after deleteBatch which all keys not exist * @tc.type: FUNC -* @tc.require: AR000CIFGM +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification021, TestSize.Level2) @@ -1697,7 +1697,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification021, Tes * @tc.desc: Subscribe to an observer, deletebatch the same data many times and only first deletebatch callback with * notification * @tc.type: FUNC -* @tc.require: AR000CIFGM +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification022, TestSize.Level2) @@ -1749,7 +1749,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification022, Tes * @tc.name: KvStoreDdmSubscribeKvStoreNotification023 * @tc.desc: Subscribe to an observer, include Clear Put PutBatch Delete DeleteBatch * @tc.type: FUNC -* @tc.require: AR000CIFGM +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification023, TestSize.Level2) @@ -1805,7 +1805,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification023, Tes * @tc.name: KvStoreDdmSubscribeKvStoreNotification024 * @tc.desc: Subscribe to an observer[use transaction], include Clear Put PutBatch Delete DeleteBatch * @tc.type: FUNC -* @tc.require: AR000CIFGM +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification024, TestSize.Level2) @@ -1857,7 +1857,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification024, Tes * @tc.name: KvStoreDdmSubscribeKvStoreNotification025 * @tc.desc: Subscribe to an observer[use transaction], include Clear Put PutBatch Delete DeleteBatch * @tc.type: FUNC -* @tc.require: AR000CIFGM +* @tc.require: * @tc.author: liuyuhui */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification025, TestSize.Level2) @@ -1913,7 +1913,7 @@ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification025, Tes * @tc.name: KvStoreDdmSubscribeKvStoreNotification026 * @tc.desc: Subscribe to an observer[use transaction], include bigData PutBatch update insert delete * @tc.type: FUNC -* @tc.require: AR000CIFGM +* @tc.require: * @tc.author: dukaizhan */ HWTEST_F(LocalSubscribeStoreTest, KvStoreDdmSubscribeKvStoreNotification026, TestSize.Level2) diff --git a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/single_kvstore_async_get_test.cpp b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/single_kvstore_async_get_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0ede44c23fc8c4e6d8e55f16052eb5f32e9d20f8 --- /dev/null +++ b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/single_kvstore_async_get_test.cpp @@ -0,0 +1,318 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include "block_data.h" +#include "dev_manager.h" +#include "distributed_kv_data_manager.h" +#include "file_ex.h" +#include "types.h" + +using namespace testing::ext; +using namespace OHOS::DistributedKv; +namespace OHOS::Test { +class SingleKvStoreAsyncGetTest : public testing::Test { +public: + static void SetUpTestCase(void); + + static void TearDownTestCase(void); + + void SetUp(); + + void TearDown(); + + static std::shared_ptr singleKvStore; + static Status status_; +}; + +std::shared_ptr SingleKvStoreAsyncGetTest::singleKvStore = nullptr; +Status SingleKvStoreAsyncGetTest::status_ = Status::ERROR; + +void SingleKvStoreAsyncGetTest::SetUpTestCase(void) +{ + DistributedKvDataManager manager; + Options options = { .createIfMissing = true, .encrypt = false, .autoSync = true, + .kvStoreType = KvStoreType::SINGLE_VERSION, .dataType = DataType::TYPE_DYNAMICAL }; + options.area = EL1; + options.securityLevel = S1; + options.baseDir = std::string("/data/service/el1/public/database/asyncgettest"); + AppId appId = { "asyncgettest" }; + StoreId storeId = { "asyncgettest_store_0" }; + mkdir(options.baseDir.c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)); + status_ = manager.GetSingleKvStore(options, appId, storeId, singleKvStore); +} + +void SingleKvStoreAsyncGetTest::TearDownTestCase(void) +{ + (void)remove("/data/service/el1/public/database/asyncgettest/key"); + (void)remove("/data/service/el1/public/database/asyncgettest/kvdb"); + (void)remove("/data/service/el1/public/database/asyncgettest"); +} + +void SingleKvStoreAsyncGetTest::SetUp(void) +{} + +void SingleKvStoreAsyncGetTest::TearDown(void) +{} + +/** +* @tc.name: CreateDefaultKvStore +* @tc.desc: get a single KvStore instance, default is dynamic. +* @tc.type: FUNC +* @tc.require: +* @tc.author: zuojiangjiang +*/ +HWTEST_F(SingleKvStoreAsyncGetTest, CreateDefaultKvStore, TestSize.Level1) +{ + DistributedKvDataManager manager; + Options options = { .createIfMissing = true, .kvStoreType = KvStoreType::SINGLE_VERSION}; + EXPECT_EQ(options.autoSync, false); + EXPECT_EQ(options.dataType, DataType::TYPE_DYNAMICAL); + options.area = EL1; + options.securityLevel = S1; + options.baseDir = std::string("/data/service/el1/public/database/asyncgettest"); + AppId appId = { "asyncgettest" }; + StoreId storeId = { "asyncgettest_store_1" }; + + std::shared_ptr store = nullptr; + auto status = manager.GetSingleKvStore(options, appId, storeId, store); + EXPECT_EQ(status, Status::SUCCESS); + EXPECT_NE(store, nullptr); + status = manager.CloseKvStore(appId, storeId); + EXPECT_EQ(status, Status::SUCCESS); + status = manager.DeleteKvStore(appId, storeId, options.baseDir); + EXPECT_EQ(status, Status::SUCCESS); +} + +/** +* @tc.name: CreateStaticKvStore +* @tc.desc: get a single KvStore instance, data type is STATICS. +* @tc.type: FUNC +* @tc.require: +* @tc.author: zuojiangjiang +*/ +HWTEST_F(SingleKvStoreAsyncGetTest, CreateStaticKvStore, TestSize.Level1) +{ + DistributedKvDataManager manager; + Options options = { .createIfMissing = true, .autoSync = true, .dataType = DataType::TYPE_STATICS }; + options.area = EL1; + options.securityLevel = S1; + options.baseDir = std::string("/data/service/el1/public/database/asyncgettest"); + AppId appId = { "asyncgettest" }; + StoreId storeId = { "asyncgettest_store" }; + + std::shared_ptr store = nullptr; + auto status = manager.GetSingleKvStore(options, appId, storeId, store); + EXPECT_EQ(status, Status::INVALID_ARGUMENT); +} + +/** +* @tc.name: GetKvStoreWithDiffDataType +* @tc.desc: get a single KvStore instance 2 times, data type is different. +* @tc.type: FUNC +* @tc.require: +* @tc.author: zuojiangjiang +*/ +HWTEST_F(SingleKvStoreAsyncGetTest, GetKvStoreWithDiffDataType, TestSize.Level1) +{ + DistributedKvDataManager manager; + Options options = { .createIfMissing = true, .dataType = DataType::TYPE_STATICS }; + options.area = EL1; + options.securityLevel = S1; + options.baseDir = std::string("/data/service/el1/public/database/asyncgettest"); + AppId appId = { "asyncgettest" }; + StoreId storeId = { "asyncgettest_store_2" }; + + std::shared_ptr store = nullptr; + auto status = manager.GetSingleKvStore(options, appId, storeId, store); + EXPECT_EQ(status, Status::SUCCESS); + EXPECT_NE(store, nullptr); + status = manager.CloseKvStore(appId, storeId); + EXPECT_EQ(status, Status::SUCCESS); + options.dataType = DataType::TYPE_DYNAMICAL; + status = manager.GetSingleKvStore(options, appId, storeId, store); + EXPECT_EQ(status, Status::SUCCESS); + status = manager.DeleteKvStore(appId, storeId, options.baseDir); + EXPECT_EQ(status, Status::SUCCESS); +} + +/** +* @tc.name: AsyncGetValue +* @tc.desc: async get value, data type is TYPE_STATICS. +* @tc.type: FUNC +* @tc.require: +* @tc.author: zuojiangjiang +*/ +HWTEST_F(SingleKvStoreAsyncGetTest, AsyncGetValue, TestSize.Level1) +{ + DistributedKvDataManager manager; + Options options = { .createIfMissing = true, .dataType = DataType::TYPE_STATICS }; + options.area = EL1; + options.securityLevel = S1; + options.baseDir = std::string("/data/service/el1/public/database/asyncgettest"); + AppId appId = { "asyncgettest" }; + StoreId storeId = { "asyncgettest_store_3" }; + + std::shared_ptr store = nullptr; + auto status = manager.GetSingleKvStore(options, appId, storeId, store); + EXPECT_EQ(status, Status::SUCCESS); + EXPECT_NE(store, nullptr); + status = store->Put({ "test_key" }, { "test_value" }); + EXPECT_EQ(status, Status::SUCCESS); + Value value; + status = store->Get({ "test_key" }, value); + EXPECT_EQ(status, Status::SUCCESS); + EXPECT_EQ(value.ToString(), "test_value"); + auto blockData = std::make_shared>(1, false); + std::function call = [blockData, value](Status status, Value &&out) { + EXPECT_EQ(status, Status::SUCCESS); + EXPECT_EQ(out.ToString(), value.ToString()); + blockData->SetValue(true); + }; + auto devInfo = DevManager::GetInstance().GetLocalDevice(); + store->Get({ "test_key" }, devInfo.networkId, call); + EXPECT_EQ(blockData->GetValue(), true); + status = manager.CloseKvStore(appId, storeId); + EXPECT_EQ(status, Status::SUCCESS); + status = manager.DeleteKvStore(appId, storeId, options.baseDir); + EXPECT_EQ(status, Status::SUCCESS); +} + +/** +* @tc.name: AsyncGetValueWithInvalidNetworkId +* @tc.desc: async get value, networkId is invalid. +* @tc.type: FUNC +* @tc.require: +* @tc.author: zuojiangjiang +*/ +HWTEST_F(SingleKvStoreAsyncGetTest, AsyncGetValueWithInvalidNetworkId, TestSize.Level1) +{ + EXPECT_NE(singleKvStore, nullptr); + auto status = singleKvStore->Put({ "test_key_0" }, { "test_value_0" }); + EXPECT_EQ(status, Status::SUCCESS); + Value value; + status = singleKvStore->Get({ "test_key_0" }, value); + EXPECT_EQ(status, Status::SUCCESS); + EXPECT_EQ(value.ToString(), "test_value_0"); + auto blockData = std::make_shared>(1, false); + std::function call = [blockData](Status status, Value &&value) { + EXPECT_EQ(status, Status::SUCCESS); + blockData->SetValue(true); + }; + singleKvStore->Get({ "test_key_0" }, "", call); + EXPECT_EQ(blockData->GetValue(), true); + blockData->Clear(false); + singleKvStore->Get({ "test_key_0" }, "networkId_test", call); + EXPECT_EQ(blockData->GetValue(), true); +} + +/** +* @tc.name: AsyncGetEntriesWithInvalidNetworkId +* @tc.desc: async get entries, networkId is invalid. +* @tc.type: FUNC +* @tc.require: +* @tc.author: zuojiangjiang +*/ +HWTEST_F(SingleKvStoreAsyncGetTest, AsyncGetEntriesWithInvalidNetworkId, TestSize.Level1) +{ + EXPECT_NE(singleKvStore, nullptr); + std::vector entries; + for (int i = 0; i < 10; ++i) { + Entry entry; + entry.key = "prefix_key_" + std::to_string(i); + entry.value = std::to_string(i).append("_v"); + entries.push_back(entry); + } + auto status = singleKvStore->PutBatch(entries); + EXPECT_EQ(status, Status::SUCCESS); + std::vector results; + singleKvStore->GetEntries({ "prefix_key_" }, results); + EXPECT_EQ(results.size(), 10); + auto blockData = std::make_shared>(1, false); + std::function&&)> call = [blockData](Status status, std::vector &&value) { + EXPECT_EQ(status, Status::SUCCESS); + blockData->SetValue(true); + }; + singleKvStore->GetEntries({ "prefix_key_" }, "", call); + EXPECT_EQ(blockData->GetValue(), true); + blockData->Clear(false); + singleKvStore->GetEntries({ "prefix_key_" }, "networkId_test", call); + EXPECT_EQ(blockData->GetValue(), true); +} + +/** +* @tc.name: AsyncGetValueWithLocalNetworkId +* @tc.desc: async get value, networkId is local. +* @tc.type: FUNC +* @tc.require: +* @tc.author: zuojiangjiang +*/ +HWTEST_F(SingleKvStoreAsyncGetTest, AsyncGetValueWithLocalNetworkId, TestSize.Level1) +{ + EXPECT_NE(singleKvStore, nullptr); + auto status = singleKvStore->Put({ "test_key_1" }, { "test_value_1" }); + EXPECT_EQ(status, Status::SUCCESS); + Value result; + status = singleKvStore->Get({ "test_key_1" }, result); + EXPECT_EQ(status, Status::SUCCESS); + EXPECT_EQ(result.ToString(), "test_value_1"); + auto blockData = std::make_shared>(1, false); + std::function call = [blockData, result](Status status, Value &&value) { + EXPECT_EQ(status, Status::SUCCESS); + EXPECT_EQ(result.ToString(), value.ToString()); + blockData->SetValue(true); + }; + auto devInfo = DevManager::GetInstance().GetLocalDevice(); + singleKvStore->Get("test_key_1", devInfo.networkId, call); + EXPECT_EQ(blockData->GetValue(), true); +} + +/** +* @tc.name: AsyncGetEntriesWithLocalNetworkId +* @tc.desc: async get entries, networkId is local. +* @tc.type: FUNC +* @tc.require: +* @tc.author: zuojiangjiang +*/ +HWTEST_F(SingleKvStoreAsyncGetTest, AsyncGetEntriesWithLocalNetworkId, TestSize.Level1) +{ + EXPECT_NE(singleKvStore, nullptr); + int num = 5; + for (int i = 0; i < num; i++) { + singleKvStore->Put({ "prefix_of_" + std::to_string(i) }, { "test_value_2" }); + } + std::vector results; + singleKvStore->GetEntries({ "prefix_of_" }, results); + EXPECT_EQ(results.size(), num); + auto blockData = std::make_shared>(1, false); + std::function&&)> call = + [blockData, results](Status status, std::vector&& values) { + EXPECT_EQ(status, Status::SUCCESS); + EXPECT_EQ(results.size(), values.size()); + EXPECT_EQ(values[0].value.ToString(), "test_value_2"); + blockData->SetValue(true); + }; + auto devInfo = DevManager::GetInstance().GetLocalDevice(); + singleKvStore->GetEntries("prefix_of_", devInfo.networkId, call); + EXPECT_EQ(blockData->GetValue(), true); + auto ret = singleKvStore->GetDeviceEntries("test_device_1", results); + EXPECT_EQ(ret, Status::SUCCESS); +} +} // namespace OHOS::Test \ No newline at end of file diff --git a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/single_kvstore_client_query_test.cpp b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/single_kvstore_client_query_test.cpp index fce33602f25ce60d7dce64610ed021b7c9d4d4eb..b1e9bfd721fd590dd0d00e08734ab7e48f60c101 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/single_kvstore_client_query_test.cpp +++ b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/single_kvstore_client_query_test.cpp @@ -1007,4 +1007,42 @@ HWTEST_F(SingleKvStoreClientQueryTest, DataQueryDeviceIdValidField, TestSize.Lev query.DeviceId(deviceId); EXPECT_TRUE(query.ToString().length() == 0); } -} // namespace \ No newline at end of file + +/** +* @tc.name: DataQuery +* @tc.desc: the predicate is between, the value is invalid. +* @tc.type: FUNC +* @tc.require: +* @tc.author: SQL +*/ +HWTEST_F(SingleKvStoreClientQueryTest, DataQueryBetweenInvalid, TestSize.Level1) +{ + DistributedKvDataManager manager; + Options options = { .createIfMissing = true, .encrypt = true, .autoSync = true, + .kvStoreType = KvStoreType::SINGLE_VERSION, .schema = VALID_SCHEMA_STRICT_DEFINE }; + options.area = EL1; + options.securityLevel = S1; + options.baseDir = "/data/service/el1/public/database/SingleKvStoreClientQueryTest"; + AppId appId = { "SingleKvStoreClientQueryTest" }; + StoreId storeId = { "SingleKvStoreClientQueryTestStoreId3" }; + statusGetKvStore = manager.GetSingleKvStore(options, appId, storeId, singleKvStore); + EXPECT_NE(singleKvStore, nullptr) << "kvStorePtr is null."; + singleKvStore->Put("test_key_1", "{\"name\":1}"); + singleKvStore->Put("test_key_2", "{\"name\":2}"); + singleKvStore->Put("test_key_3", "{\"name\":3}"); + + DataQuery query; + query.Between({}, {}); + std::vector results1; + Status status = singleKvStore->GetEntries(query, results1); + EXPECT_EQ(status, NOT_SUPPORT); + + singleKvStore->Delete("test_key_1"); + singleKvStore->Delete("test_key_2"); + singleKvStore->Delete("test_key_3"); + status = manager.CloseAllKvStore(appId); + EXPECT_EQ(status, Status::SUCCESS); + status = manager.DeleteAllKvStore(appId, options.baseDir); + EXPECT_EQ(status, Status::SUCCESS); +} +} // namespace diff --git a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/single_kvstore_client_test.cpp b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/single_kvstore_client_test.cpp index 91379f2c9c95f22639dedda9c1d16a7f295f3c42..affe84531ad0d7bfde7de8e9396848e2d733bfb3 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/single_kvstore_client_test.cpp +++ b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/single_kvstore_client_test.cpp @@ -24,20 +24,16 @@ using namespace testing::ext; using namespace OHOS::DistributedKv; - +namespace OHOS::Test { +static constexpr uint64_t MAX_VALUE_SIZE = 4 * 1024 * 1024; // max value size is 4M. class SingleKvStoreClientTest : public testing::Test { public: + static std::shared_ptr singleKvStore; // declare kvstore instance. + static Status status_; static void SetUpTestCase(void); - static void TearDownTestCase(void); - void SetUp(); - void TearDown(); - - static std::shared_ptr singleKvStore; // declare kvstore instance. - static Status status_; - static int MAX_VALUE_SIZE; }; const std::string VALID_SCHEMA_STRICT_DEFINE = "{\"SCHEMA_VERSION\":\"1.0\"," @@ -50,7 +46,6 @@ const std::string VALID_SCHEMA_STRICT_DEFINE = "{\"SCHEMA_VERSION\":\"1.0\"," std::shared_ptr SingleKvStoreClientTest::singleKvStore = nullptr; Status SingleKvStoreClientTest::status_ = Status::ERROR; -int SingleKvStoreClientTest::MAX_VALUE_SIZE = 4 * 1024 * 1024; // max value size is 4M. void SingleKvStoreClientTest::SetUpTestCase(void) { @@ -141,7 +136,7 @@ void KvStoreSyncCallbackTestImpl::SyncCompleted(const std::mapPut({prefix + std::to_string(i)}, {std::to_string(i)}); @@ -215,7 +210,7 @@ HWTEST_F(SingleKvStoreClientTest, GetEntriesAndResultSet001, TestSize.Level1) std::shared_ptr resultSet; Status status = singleKvStore->GetResultSet({prefix}, resultSet); EXPECT_EQ(status, Status::SUCCESS); - EXPECT_EQ(resultSet->GetCount(), sum_1) << "resultSet size is not equal 10."; + EXPECT_EQ(resultSet->GetCount(), sum1) << "resultSet size is not equal 10."; resultSet->IsFirst(); resultSet->IsAfterLast(); resultSet->IsBeforeFirst(); @@ -250,7 +245,7 @@ HWTEST_F(SingleKvStoreClientTest, GetEntriesByDataQuery, TestSize.Level1) // prepare 10 size_t sum = 10; - int sum_1 = 10; + int sum1 = 10; std::string prefix = "prefix_"; for (size_t i = 0; i < sum; i++) { singleKvStore->Put({prefix + std::to_string(i)}, {std::to_string(i)}); @@ -265,7 +260,7 @@ HWTEST_F(SingleKvStoreClientTest, GetEntriesByDataQuery, TestSize.Level1) std::shared_ptr resultSet; Status status = singleKvStore->GetResultSet(dataQuery, resultSet); EXPECT_EQ(status, Status::SUCCESS); - EXPECT_EQ(resultSet->GetCount(), sum_1) << "resultSet size is not equal 10."; + EXPECT_EQ(resultSet->GetCount(), sum1) << "resultSet size is not equal 10."; resultSet->IsFirst(); resultSet->IsAfterLast(); resultSet->IsBeforeFirst(); @@ -308,7 +303,7 @@ HWTEST_F(SingleKvStoreClientTest, GetEmptyEntries, TestSize.Level1) * @tc.name: Subscribe001 * @tc.desc: Put data and get callback. * @tc.type: FUNC -* @tc.require: SR000DORPS AR000DPRQ7 AR000DDPRPL +* @tc.require: * @tc.author: hongbo */ HWTEST_F(SingleKvStoreClientTest, Subscribe001, TestSize.Level1) @@ -328,7 +323,7 @@ HWTEST_F(SingleKvStoreClientTest, Subscribe001, TestSize.Level1) * @tc.name: SyncCallback001 * @tc.desc: Register sync callback. * @tc.type: FUNC -* @tc.require: SR000DORPS AR000DPRQ7 AR000DDPRPL +* @tc.require: * @tc.author: hongbo */ HWTEST_F(SingleKvStoreClientTest, SyncCallback001, TestSize.Level1) @@ -356,7 +351,7 @@ HWTEST_F(SingleKvStoreClientTest, SyncCallback001, TestSize.Level1) * @tc.name: RemoveDeviceData001 * @tc.desc: Remove device data. * @tc.type: FUNC -* @tc.require: SR000DORPS AR000DPRQ7 AR000DDPRPL +* @tc.require: * @tc.author: hongbo */ HWTEST_F(SingleKvStoreClientTest, RemoveDeviceData001, TestSize.Level1) @@ -369,7 +364,7 @@ HWTEST_F(SingleKvStoreClientTest, RemoveDeviceData001, TestSize.Level1) std::string deviceId = "no_exist_device_id"; auto removeStatus = singleKvStore->RemoveDeviceData(deviceId); - EXPECT_NE(removeStatus, Status::SUCCESS) << "remove device should not return success"; + EXPECT_EQ(removeStatus, Status::SUCCESS) << "remove device should return success"; Value retVal; auto getRet = singleKvStore->Get(skey, retVal); @@ -381,7 +376,7 @@ HWTEST_F(SingleKvStoreClientTest, RemoveDeviceData001, TestSize.Level1) * @tc.name: SyncData001 * @tc.desc: Synchronize device data. * @tc.type: FUNC -* @tc.require: SR000DORPS AR000DPRQ7 AR000DDPRPL +* @tc.require: * @tc.author: hongbo */ HWTEST_F(SingleKvStoreClientTest, SyncData001, TestSize.Level1) @@ -397,7 +392,7 @@ HWTEST_F(SingleKvStoreClientTest, SyncData001, TestSize.Level1) * @tc.name: TestSchemaStoreC001 * @tc.desc: Test schema single store. * @tc.type: FUNC -* @tc.require: AR000DPSF1 +@tc.require: * @tc.author: zuojiangjiang */ HWTEST_F(SingleKvStoreClientTest, TestSchemaStoreC001, TestSize.Level1) @@ -432,7 +427,7 @@ HWTEST_F(SingleKvStoreClientTest, TestSchemaStoreC001, TestSize.Level1) * @tc.name: SyncData001 * @tc.desc: Synchronize device data. * @tc.type: FUNC -* @tc.require: SR000DOGQE AR000DPUAN +* @tc.require: * @tc.author: wangtao */ HWTEST_F(SingleKvStoreClientTest, SyncData002, TestSize.Level1) @@ -449,7 +444,7 @@ HWTEST_F(SingleKvStoreClientTest, SyncData002, TestSize.Level1) * @tc.name: SyncData002 * @tc.desc: Set sync parameters - success. * @tc.type: FUNC -* @tc.require: SR000DOGQE AR000DPUAO +* @tc.require: * @tc.author: wangtao */ HWTEST_F(SingleKvStoreClientTest, SetSync001, TestSize.Level1) @@ -468,7 +463,7 @@ HWTEST_F(SingleKvStoreClientTest, SetSync001, TestSize.Level1) * @tc.name: SyncData002 * @tc.desc: Set sync parameters - failed. * @tc.type: FUNC -* @tc.require: SR000DOGQE AR000DPUAO +* @tc.require: * @tc.author: wangtao */ HWTEST_F(SingleKvStoreClientTest, SetSync002, TestSize.Level1) @@ -487,7 +482,7 @@ HWTEST_F(SingleKvStoreClientTest, SetSync002, TestSize.Level1) * @tc.name: SingleKvStoreDdmPutBatch001 * @tc.desc: Batch put data. * @tc.type: FUNC -* @tc.require: AR000DPSEA +* @tc.require: * @tc.author: shanshuangshuang */ HWTEST_F(SingleKvStoreClientTest, DdmPutBatch001, TestSize.Level2) @@ -530,7 +525,7 @@ HWTEST_F(SingleKvStoreClientTest, DdmPutBatch001, TestSize.Level2) * @tc.name: SingleKvStoreDdmPutBatch002 * @tc.desc: Batch update data. * @tc.type: FUNC -* @tc.require: AR000DPSEA +* @tc.require: * @tc.author: shanshuangshuang */ HWTEST_F(SingleKvStoreClientTest, DdmPutBatch002, TestSize.Level2) @@ -590,7 +585,7 @@ HWTEST_F(SingleKvStoreClientTest, DdmPutBatch002, TestSize.Level2) * @tc.name: DdmPutBatch003 * @tc.desc: Batch put data that contains invalid data. * @tc.type: FUNC -* @tc.require: AR000DPSEA +* @tc.require: * @tc.author: shanshuangshuang */ HWTEST_F(SingleKvStoreClientTest, DdmPutBatch003, TestSize.Level2) @@ -617,7 +612,7 @@ HWTEST_F(SingleKvStoreClientTest, DdmPutBatch003, TestSize.Level2) * @tc.name: DdmPutBatch004 * @tc.desc: Batch put data that contains invalid data. * @tc.type: FUNC -* @tc.require: AR000DPSEA +* @tc.require: * @tc.author: shanshuangshuang */ HWTEST_F(SingleKvStoreClientTest, DdmPutBatch004, TestSize.Level2) @@ -649,16 +644,16 @@ static std::string SingleGenerate1025KeyLen() } return str; } + /** * @tc.name: DdmPutBatch005 * @tc.desc: Batch put data that contains invalid data. * @tc.type: FUNC -* @tc.require: AR000DPSEA +* @tc.require: * @tc.author: shanshuangshuang */ HWTEST_F(SingleKvStoreClientTest, DdmPutBatch005, TestSize.Level2) { - EXPECT_NE(nullptr, singleKvStore) << "singleKvStore is nullptr"; std::vector entries; @@ -681,7 +676,7 @@ HWTEST_F(SingleKvStoreClientTest, DdmPutBatch005, TestSize.Level2) * @tc.name: DdmPutBatch006 * @tc.desc: Batch put large data. * @tc.type: FUNC -* @tc.require: AR000DPSEA +* @tc.require: * @tc.author: shanshuangshuang */ HWTEST_F(SingleKvStoreClientTest, DdmPutBatch006, TestSize.Level2) @@ -729,7 +724,7 @@ HWTEST_F(SingleKvStoreClientTest, DdmPutBatch006, TestSize.Level2) * @tc.name: DdmDeleteBatch001 * @tc.desc: Batch delete data. * @tc.type: FUNC -* @tc.require: AR000DPSEA +* @tc.require: * @tc.author: shanshuangshuang */ HWTEST_F(SingleKvStoreClientTest, DdmDeleteBatch001, TestSize.Level2) @@ -769,7 +764,7 @@ HWTEST_F(SingleKvStoreClientTest, DdmDeleteBatch001, TestSize.Level2) * @tc.name: DdmDeleteBatch002 * @tc.desc: Batch delete data when some keys are not in KvStore. * @tc.type: FUNC -* @tc.require: AR000DPSEA +* @tc.require: * @tc.author: shanshuangshuang */ HWTEST_F(SingleKvStoreClientTest, DdmDeleteBatch002, TestSize.Level2) @@ -810,7 +805,7 @@ HWTEST_F(SingleKvStoreClientTest, DdmDeleteBatch002, TestSize.Level2) * @tc.name: DdmDeleteBatch003 * @tc.desc: Batch delete data when some keys are invalid. * @tc.type: FUNC -* @tc.require: AR000DPSEA +* @tc.require: * @tc.author: shanshuangshuang */ HWTEST_F(SingleKvStoreClientTest, DdmDeleteBatch003, TestSize.Level2) @@ -850,7 +845,7 @@ HWTEST_F(SingleKvStoreClientTest, DdmDeleteBatch003, TestSize.Level2) * @tc.name: DdmDeleteBatch004 * @tc.desc: Batch delete data when some keys are invalid. * @tc.type: FUNC -* @tc.require: AR000DPSEA +* @tc.require: * @tc.author: shanshuangshuang */ HWTEST_F(SingleKvStoreClientTest, DdmDeleteBatch004, TestSize.Level2) @@ -895,7 +890,7 @@ HWTEST_F(SingleKvStoreClientTest, DdmDeleteBatch004, TestSize.Level2) * @tc.name: DdmDeleteBatch005 * @tc.desc: Batch delete data when some keys are invalid. * @tc.type: FUNC -* @tc.require: AR000DPSEA +* @tc.require: * @tc.author: shanshuangshuang */ HWTEST_F(SingleKvStoreClientTest, DdmDeleteBatch005, TestSize.Level2) @@ -941,7 +936,7 @@ HWTEST_F(SingleKvStoreClientTest, DdmDeleteBatch005, TestSize.Level2) * @tc.name: Transaction001 * @tc.desc: Batch delete data when some keys are invalid. * @tc.type: FUNC -* @tc.require: AR000DPSEA +* @tc.require: * @tc.author: shanshuangshuang */ HWTEST_F(SingleKvStoreClientTest, Transaction001, TestSize.Level2) @@ -998,7 +993,7 @@ HWTEST_F(SingleKvStoreClientTest, Transaction001, TestSize.Level2) * @tc.name: Transaction002 * @tc.desc: Batch delete data when some keys are invalid. * @tc.type: FUNC -* @tc.require: AR000DPSEA +* @tc.require: * @tc.author: shanshuangshuang */ HWTEST_F(SingleKvStoreClientTest, Transaction002, TestSize.Level2) @@ -1059,7 +1054,7 @@ HWTEST_F(SingleKvStoreClientTest, Transaction002, TestSize.Level2) * @tc.name: DeviceSync001 * @tc.desc: Test sync enable. * @tc.type: FUNC -* @tc.require:AR000EPAM8 AR000EPAMD +* @tc.require: * @tc.author: HongBo */ HWTEST_F(SingleKvStoreClientTest, DeviceSync001, TestSize.Level1) @@ -1088,7 +1083,7 @@ HWTEST_F(SingleKvStoreClientTest, DeviceSync001, TestSize.Level1) * @tc.name: DeviceSync002 * @tc.desc: Test sync enable. * @tc.type: FUNC -* @tc.require:SR000EPA22 AR000EPAM9 +* @tc.require: * @tc.author: HongBo */ HWTEST_F(SingleKvStoreClientTest, DeviceSync002, TestSize.Level1) @@ -1149,7 +1144,7 @@ HWTEST_F(SingleKvStoreClientTest, DisableCapability, TestSize.Level1) * @tc.name: SyncWithCondition001 * @tc.desc: sync device data with condition; * @tc.type: FUNC -* @tc.require: AR000GH097 +* @tc.require: * @tc.author: liuwenhui */ HWTEST_F(SingleKvStoreClientTest, SyncWithCondition001, TestSize.Level1) @@ -1162,11 +1157,25 @@ HWTEST_F(SingleKvStoreClientTest, SyncWithCondition001, TestSize.Level1) EXPECT_NE(syncStatus, Status::SUCCESS) << "sync device should not return success"; } +/** +* @tc.name: SyncWithCondition002 +* @tc.desc: sync device data with condition and retry is false +* @tc.type: FUNC +*/ +HWTEST_F(SingleKvStoreClientTest, SyncWithCondition002, TestSize.Level1) +{ + ASSERT_NE(singleKvStore, nullptr); + std::vector deviceIds; + DataQuery dataQuery; + auto syncStatus = singleKvStore->Sync(deviceIds, SyncMode::PUSH, dataQuery, false, nullptr); + ASSERT_NE(syncStatus, Status::SUCCESS); +} + /** * @tc.name: SubscribeWithQuery001 * desc: subscribe and sync device data with query; * type: FUNC - * require: AR000GH096 + * require: * author:taoyuxin */ HWTEST_F(SingleKvStoreClientTest, SubscribeWithQuery001, TestSize.Level1) @@ -1183,7 +1192,7 @@ HWTEST_F(SingleKvStoreClientTest, SubscribeWithQuery001, TestSize.Level1) * @tc.name: UnSubscribeWithQuery001 * desc: subscribe and sync device data with query; * type: FUNC - * require: SR000GH095 + * require: * author:taoyuxin */ HWTEST_F(SingleKvStoreClientTest, UnSubscribeWithQuery001, TestSize.Level1) @@ -1194,4 +1203,33 @@ HWTEST_F(SingleKvStoreClientTest, UnSubscribeWithQuery001, TestSize.Level1) dataQuery.KeyPrefix("name"); auto unSubscribeStatus = singleKvStore->UnsubscribeWithQuery(deviceIds, dataQuery); EXPECT_NE(unSubscribeStatus, Status::SUCCESS) << "sync device should not return success"; -} \ No newline at end of file +} + +/** + * @tc.name: CloudSync002 + * desc: create kv store which not supports cloud sync and execute CloudSync interface + * type: FUNC + * require: + * author:taoyuxin + */ +HWTEST_F(SingleKvStoreClientTest, CloudSync002, TestSize.Level1) +{ + std::shared_ptr cloudSyncKvStore = nullptr; + DistributedKvDataManager manager{}; + Options options; + options.encrypt = true; + options.securityLevel = S1; + options.area = EL1; + options.kvStoreType = KvStoreType::SINGLE_VERSION; + options.baseDir = "/data/service/el1/public/database/odmf"; + options.schema = VALID_SCHEMA_STRICT_DEFINE; + options.cloudConfig.enableCloud = false; + AppId appId = { "odmf" }; + StoreId storeId = { "cloud_store_id" }; + manager.DeleteKvStore(appId, storeId, options.baseDir); + (void)manager.GetSingleKvStore(options, appId, storeId, cloudSyncKvStore); + ASSERT_NE(cloudSyncKvStore, nullptr); + auto status = cloudSyncKvStore->CloudSync(nullptr); + EXPECT_NE(status, Status::SUCCESS); +} +} // namespace OHOS::Test \ No newline at end of file diff --git a/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/switch_observer_bridge_test.cpp b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/switch_observer_bridge_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..39bede1556b51f226869c6622926f2d638192481 --- /dev/null +++ b/frameworks/innerkitsimpl/distributeddatafwk/test/unittest/switch_observer_bridge_test.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "switch_observer_bridge.h" + +#include + +namespace OHOS::Test { +using namespace testing::ext; +using namespace OHOS::DistributedKv; +class SwitchObserverBridgeTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void) {} + void SetUp() {} + void TearDown() {} + + static AppId invalidAppId_; + static AppId validAppId_; +}; + +AppId SwitchObserverBridgeTest::invalidAppId_; +AppId SwitchObserverBridgeTest::validAppId_; + +void SwitchObserverBridgeTest::SetUpTestCase(void) +{ + invalidAppId_.appId = ""; + validAppId_.appId = "SwitchObserverBridgeTest"; +} + +class SwitchObserverTest : public KvStoreObserver { +public: + void OnSwitchChange(const SwitchNotification ¬ification) override {} +}; + +/** +* @tc.name: AddAndDeleteSwitchCallbackTest001 +* @tc.desc: test add and delete switch callback +* @tc.type: FUNC +*/ +HWTEST_F(SwitchObserverBridgeTest, AddAndDeleteSwitchCallbackTest001, TestSize.Level1) +{ + std::shared_ptr switchBridge = std::make_shared(validAppId_); + + switchBridge->AddSwitchCallback(nullptr); + ASSERT_TRUE(switchBridge->switchObservers_.Empty()); + + std::shared_ptr observer = std::make_shared(); + switchBridge->AddSwitchCallback(observer); + ASSERT_FALSE(switchBridge->switchObservers_.Empty()); + + switchBridge->DeleteSwitchCallback(nullptr); + ASSERT_FALSE(switchBridge->switchObservers_.Empty()); + + switchBridge->DeleteSwitchCallback(observer); + ASSERT_TRUE(switchBridge->switchObservers_.Empty()); +} + +/** +* @tc.name: OnRemoteDiedTest001 +* @tc.desc: test on remote died +* @tc.type: FUNC +*/ +HWTEST_F(SwitchObserverBridgeTest, OnRemoteDiedTest001, TestSize.Level1) +{ + std::shared_ptr switchBridge = std::make_shared(invalidAppId_); + switchBridge->OnRemoteDied(); + ASSERT_FALSE(switchBridge->switchAppId_.IsValid()); + + switchBridge = std::make_shared(validAppId_); + switchBridge->OnRemoteDied(); + ASSERT_TRUE(switchBridge->switchAppId_.IsValid()); + ASSERT_TRUE(switchBridge->switchObservers_.Empty()); +} +} // namespace OHOS::Test \ No newline at end of file diff --git a/frameworks/innerkitsimpl/distributeddatasvc/include/datamgr_service_proxy.h b/frameworks/innerkitsimpl/distributeddatasvc/include/datamgr_service_proxy.h index 510647da5058e305c56b4a21892c23691caa70b8..039f94f52e8268f7b8d2cd5a76512ddc90b398ce 100644 --- a/frameworks/innerkitsimpl/distributeddatasvc/include/datamgr_service_proxy.h +++ b/frameworks/innerkitsimpl/distributeddatasvc/include/datamgr_service_proxy.h @@ -22,10 +22,14 @@ public: ~DataMgrServiceProxy() = default; sptr GetFeatureInterface(const std::string &name) override; - Status RegisterClientDeathObserver(const AppId &appId, sptr observer) override; + Status RegisterClientDeathObserver(const AppId &appId, sptr observer, + const std::string &featureName = "") override; int32_t ClearAppStorage(const std::string &bundleName, int32_t userId, int32_t appIndex, int32_t tokenId) override; + int32_t Exit(const std::string &featureName) override; + + std::pair GetSelfBundleName() override; private: static inline BrokerDelegator delegator_; }; diff --git a/frameworks/innerkitsimpl/distributeddatasvc/include/distributeddata_ipc_interface_code.h b/frameworks/innerkitsimpl/distributeddatasvc/include/distributeddata_ipc_interface_code.h index 4776377e5281fe40ef90dd3c214a324c87e38295..d915786553d322d492351a87d4e97618a4b26534 100644 --- a/frameworks/innerkitsimpl/distributeddatasvc/include/distributeddata_ipc_interface_code.h +++ b/frameworks/innerkitsimpl/distributeddatasvc/include/distributeddata_ipc_interface_code.h @@ -24,6 +24,8 @@ enum class KvStoreDataServiceInterfaceCode : uint32_t { GET_FEATURE_INTERFACE = 0, REGISTERCLIENTDEATHOBSERVER, CLEAR_APP_STORAGE, + FEATURE_EXIT, + GET_SELF_BUNDLENAME, SERVICE_CMD_LAST }; } // namespace OHOS::DistributedKv diff --git a/frameworks/innerkitsimpl/distributeddatasvc/include/ikvstore_data_service.h b/frameworks/innerkitsimpl/distributeddatasvc/include/ikvstore_data_service.h index 8c30d51d24f4063ae20c6960437b33c151440ac7..e2b24cb23ab202e19d2964fd6b7bc442dadfe583 100644 --- a/frameworks/innerkitsimpl/distributeddatasvc/include/ikvstore_data_service.h +++ b/frameworks/innerkitsimpl/distributeddatasvc/include/ikvstore_data_service.h @@ -30,11 +30,15 @@ public: virtual sptr GetFeatureInterface(const std::string &name) = 0; - virtual Status RegisterClientDeathObserver(const AppId &appId, sptr observer) = 0; + virtual Status RegisterClientDeathObserver(const AppId &appId, sptr observer, + const std::string &featureName = "") = 0; virtual int32_t ClearAppStorage(const std::string &bundleName, int32_t userId, int32_t appIndex, int32_t tokenId) = 0; + virtual int32_t Exit(const std::string &featureName) = 0; + + virtual std::pair GetSelfBundleName() = 0; protected: static constexpr size_t MAX_IPC_CAPACITY = 800 * 1024; }; diff --git a/frameworks/innerkitsimpl/distributeddatasvc/src/datamgr_service_proxy.cpp b/frameworks/innerkitsimpl/distributeddatasvc/src/datamgr_service_proxy.cpp index caca03a79b6cef7648e9946abcd5185aae97a201..053e2db7c83c31b6ac141033a7963bc92ffc3461 100644 --- a/frameworks/innerkitsimpl/distributeddatasvc/src/datamgr_service_proxy.cpp +++ b/frameworks/innerkitsimpl/distributeddatasvc/src/datamgr_service_proxy.cpp @@ -27,20 +27,20 @@ namespace DistributedKv { DataMgrServiceProxy::DataMgrServiceProxy(const sptr &impl) : IRemoteProxy(impl) { - ZLOGI("init data service proxy."); + ZLOGI("Init data service proxy."); } sptr DataMgrServiceProxy::GetFeatureInterface(const std::string &name) { - ZLOGI("%s", name.c_str()); + ZLOGI("get feature:%{public}s", name.c_str()); MessageParcel data; if (!data.WriteInterfaceToken(DataMgrServiceProxy::GetDescriptor())) { - ZLOGE("write descriptor failed"); + ZLOGE("Write descriptor failed"); return nullptr; } if (!ITypesUtil::Marshal(data, name)) { - ZLOGE("write name failed, name is %{public}s", name.c_str()); + ZLOGE("Write name failed, name is %{public}s", name.c_str()); return nullptr; } @@ -55,38 +55,44 @@ sptr DataMgrServiceProxy::GetFeatureInterface(const std::string & sptr remoteObject; if (!ITypesUtil::Unmarshal(reply, remoteObject)) { - ZLOGE("remote object is nullptr"); + ZLOGE("Remote object is nullptr"); return nullptr; } return remoteObject; } -Status DataMgrServiceProxy::RegisterClientDeathObserver(const AppId &appId, sptr observer) +Status DataMgrServiceProxy::RegisterClientDeathObserver(const AppId &appId, sptr observer, + const std::string &featureName) { MessageParcel data; MessageParcel reply; if (!data.WriteInterfaceToken(DataMgrServiceProxy::GetDescriptor())) { - ZLOGE("write descriptor failed"); + ZLOGE("Write descriptor failed"); return Status::IPC_ERROR; } if (!data.WriteString(appId.appId)) { - ZLOGW("failed to write string."); + ZLOGW("Failed to write string."); return Status::IPC_ERROR; } if (observer != nullptr) { if (!data.WriteRemoteObject(observer)) { - ZLOGW("failed to write parcel."); + ZLOGW("Failed to write parcel."); return Status::IPC_ERROR; } } else { + ZLOGE("This observer is null"); return Status::INVALID_ARGUMENT; } + if (!data.WriteString(featureName)) { + ZLOGW("Failed to write featureName."); + return Status::IPC_ERROR; + } MessageOption mo { MessageOption::TF_SYNC }; int32_t error = Remote()->SendRequest( static_cast(KvStoreDataServiceInterfaceCode::REGISTERCLIENTDEATHOBSERVER), data, reply, mo); if (error != 0) { - ZLOGW("failed during IPC. errCode %d", error); + ZLOGW("Failed during IPC. errCode %d", error); return Status::IPC_ERROR; } return static_cast(reply.ReadInt32()); @@ -98,11 +104,11 @@ int32_t DataMgrServiceProxy::ClearAppStorage(const std::string &bundleName, int3 MessageParcel data; MessageParcel reply; if (!data.WriteInterfaceToken(DataMgrServiceProxy::GetDescriptor())) { - ZLOGE("write descriptor failed"); + ZLOGE("Write descriptor failed"); return Status::IPC_ERROR; } if (!ITypesUtil::Marshal(data, bundleName, userId, appIndex, tokenId)) { - ZLOGW("failed to write bundleName:%{public}s, user:%{public}d, appIndex:%{public}d, tokenID:%{public}d", + ZLOGW("Failed to write bundleName:%{public}s, user:%{public}d, appIndex:%{public}d, tokenID:%{public}d", bundleName.c_str(), userId, appIndex, tokenId); return Status::IPC_ERROR; } @@ -111,10 +117,20 @@ int32_t DataMgrServiceProxy::ClearAppStorage(const std::string &bundleName, int3 int32_t error = Remote()->SendRequest( static_cast(KvStoreDataServiceInterfaceCode::CLEAR_APP_STORAGE), data, reply, mo); if (error != 0) { - ZLOGW("failed during IPC. errCode %d", error); + ZLOGW("Failed during IPC. errCode %d", error); return Status::IPC_ERROR; } return static_cast(reply.ReadInt32()); } + +int32_t DataMgrServiceProxy::Exit(const std::string &featureName) +{ + return Status::NOT_SUPPORT; +} + +std::pair DataMgrServiceProxy::GetSelfBundleName() +{ + return {Status::NOT_SUPPORT, ""}; +} } // namespace DistributedKv } // namespace OHOS diff --git a/frameworks/innerkitsimpl/kvdb/include/convertor.h b/frameworks/innerkitsimpl/kvdb/include/convertor.h index 77cb7b51ba17ab085a46865abb34e7f7e9f0b1d0..530e474777d96944462d6289ebb1aaa92a3cea36 100644 --- a/frameworks/innerkitsimpl/kvdb/include/convertor.h +++ b/frameworks/innerkitsimpl/kvdb/include/convertor.h @@ -34,8 +34,6 @@ public: protected: virtual std::string GetRealKey(const std::string &key, const DataQuery &query) const; std::vector TrimKey(const Key &prefix) const; - -private: static constexpr size_t MAX_KEY_LENGTH = 1024; }; } // namespace OHOS::DistributedKv diff --git a/frameworks/innerkitsimpl/kvdb/include/kvdb_service.h b/frameworks/innerkitsimpl/kvdb/include/kvdb_service.h index cf438e9e913d2b9943a7bb7a87eae78aada63b6e..a0cd3d9e7bf193677c084aa9deba8849388b8a88 100644 --- a/frameworks/innerkitsimpl/kvdb/include/kvdb_service.h +++ b/frameworks/innerkitsimpl/kvdb/include/kvdb_service.h @@ -34,6 +34,7 @@ public: std::string query; uint64_t syncId = 0; int32_t triggerMode = 0; + bool isRetry = true; }; enum PasswordType { BACKUP_SECRET_KEY = 0, diff --git a/frameworks/innerkitsimpl/kvdb/include/kvdb_service_client.h b/frameworks/innerkitsimpl/kvdb/include/kvdb_service_client.h index cacb9283a5d230c5a7df596ff1a11b05c4d19f5d..54427ba0f31e4df9ca4ec1f650f38d36be5ee436 100644 --- a/frameworks/innerkitsimpl/kvdb/include/kvdb_service_client.h +++ b/frameworks/innerkitsimpl/kvdb/include/kvdb_service_client.h @@ -38,7 +38,7 @@ public: Status Close(const AppId &appId, const StoreId &storeId, int32_t subUser) override; Status Sync(const AppId &appId, const StoreId &storeId, int32_t subUser, SyncInfo &syncInfo) override; Status RegServiceNotifier(const AppId &appId, sptr notifier) override; - Status UnregServiceNotifier(const AppId &appIdd) override; + Status UnregServiceNotifier(const AppId &appId) override; Status SetSyncParam(const AppId &appId, const StoreId &storeId, int32_t subUser, const KvSyncParam &syncParam) override; Status GetSyncParam(const AppId &appId, const StoreId &storeId, int32_t subUser, KvSyncParam &syncParam) override; diff --git a/frameworks/innerkitsimpl/kvdb/include/process_communication_impl.h b/frameworks/innerkitsimpl/kvdb/include/process_communication_impl.h index 143fc33b4fdd2c286834a77a3c3a37bde709ef57..77371fae41b225160b502eb6856d9def996ffdcb 100644 --- a/frameworks/innerkitsimpl/kvdb/include/process_communication_impl.h +++ b/frameworks/innerkitsimpl/kvdb/include/process_communication_impl.h @@ -16,9 +16,9 @@ #ifndef PROCESS_COMMUNICATION_IMPL_H #define PROCESS_COMMUNICATION_IMPL_H +#include "end_point.h" #include "iprocess_communicator.h" #include "types.h" -#include "end_point.h" namespace OHOS { namespace DistributedKv { diff --git a/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h b/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h index 195467e329d355ca64761e3fd6acbb47a17dc08b..26adec5a5668851bbf6cd52ed1e854f0da2bccb4 100644 --- a/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h +++ b/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h @@ -88,6 +88,8 @@ public: Status Sync(const std::vector &devices, SyncMode mode, uint32_t delay) override; Status Sync(const std::vector &devices, SyncMode mode, const DataQuery &query, std::shared_ptr syncCallback, uint32_t delay) override; + Status Sync(const std::vector &devices, SyncMode mode, const DataQuery &query, bool isRetry, + std::shared_ptr syncCallback) override; Status RegisterSyncCallback(std::shared_ptr callback) override; Status UnRegisterSyncCallback() override; Status SetSyncParam(const KvSyncParam &syncParam) override; @@ -134,6 +136,8 @@ private: void DoNotifyChange(); void Register(); void ReportDBFaultEvent(Status status, const std::string &functionName) const; + void SetAcl(const std::string &storeId, const std::string &path); + std::vector GenerateDbFiles(const std::string &path); int32_t subUser_ = 0; int32_t apiVersion_ = -1; @@ -151,7 +155,9 @@ private: uint64_t taskId_ = 0; bool isCheckIntegrity_ = false; + bool syncable_ = false; bool encrypt_ = false; + bool autoBackup_ = false; int32_t securityLevel_ = -1; int32_t area_ = 1; std::string hapName_ = ""; diff --git a/frameworks/innerkitsimpl/kvdb/include/store_manager.h b/frameworks/innerkitsimpl/kvdb/include/store_manager.h index 025895b3abb6ea12a64affd630e372f626d1d521..c924916b08fd68b72d5402344edce843089e7d04 100644 --- a/frameworks/innerkitsimpl/kvdb/include/store_manager.h +++ b/frameworks/innerkitsimpl/kvdb/include/store_manager.h @@ -14,9 +14,13 @@ */ #ifndef OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_STORE_MANAGER_H #define OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_STORE_MANAGER_H -#include "single_kvstore.h" + +#include "concurrent_map.h" #include "kv_hiview_reporter.h" +#include "single_kvstore.h" #include "store_factory.h" +#include "switch_observer_bridge.h" + namespace OHOS::DistributedKv { class StoreManager { public: @@ -35,6 +39,7 @@ public: private: std::shared_ptr OpenWithSecretKeyFromService(const AppId &appId, const StoreId &storeId, const Options &options, Status &status, StoreParams &storeParams); + ConcurrentMap> switchObservers_; }; -} +} // namespace OHOS::DistributedKv #endif // OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_STORE_MANAGER_H diff --git a/frameworks/innerkitsimpl/kvdb/include/store_util.h b/frameworks/innerkitsimpl/kvdb/include/store_util.h index 20a24ac1cacf84d245775077517183c1c2715033..4df65a3dd12ada1f17b1c35cc9794add2693ef59 100644 --- a/frameworks/innerkitsimpl/kvdb/include/store_util.h +++ b/frameworks/innerkitsimpl/kvdb/include/store_util.h @@ -16,6 +16,7 @@ #ifndef OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_STORE_UTIL_H #define OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_STORE_UTIL_H #include +#include #include "kv_store_delegate_manager.h" #include "store_errno.h" #include "store_types.h" @@ -50,7 +51,10 @@ public: static void Flush(); static uint64_t GenSequenceId(); static bool RemoveRWXForOthers(const std::string &path); + static bool SetDatabaseGid(const std::string &path); + static bool SetServiceGid(const std::string &filePath); private: + static bool HasPermit(const std::string &path, mode_t mode); static std::atomic sequenceId_; static std::map statusMap_; }; diff --git a/frameworks/innerkitsimpl/kvdb/src/backup_manager.cpp b/frameworks/innerkitsimpl/kvdb/src/backup_manager.cpp index 3e795d12eab841ec199d97282d4195701c4b920b..380e7ac704124b9b471b523069defefdfb2b1bfa 100644 --- a/frameworks/innerkitsimpl/kvdb/src/backup_manager.cpp +++ b/frameworks/innerkitsimpl/kvdb/src/backup_manager.cpp @@ -76,6 +76,10 @@ void BackupManager::Prepare(const std::string &path, const std::string &storeId) (void)StoreUtil::InitPath(topPath); (void)StoreUtil::InitPath(storePath); (void)StoreUtil::CreateFile(autoBackupName); + if (!StoreUtil::SetServiceGid(topPath) || !StoreUtil::SetServiceGid(storePath) || + !StoreUtil::SetServiceGid(autoBackupName)) { + return; + } } void BackupManager::KeepData(const std::string &name, bool isCreated) diff --git a/frameworks/innerkitsimpl/kvdb/src/dev_manager.cpp b/frameworks/innerkitsimpl/kvdb/src/dev_manager.cpp index 7f56f1bac87cd1010ae624ea0387ebf7cd7e9d03..c13a69254d5b084d20641d41a40a2ad4a7a1b1ac 100644 --- a/frameworks/innerkitsimpl/kvdb/src/dev_manager.cpp +++ b/frameworks/innerkitsimpl/kvdb/src/dev_manager.cpp @@ -192,7 +192,12 @@ std::vector DevManager::GetRemoteDevices() DetailInfo dtInfo; auto networkId = std::string(device.networkId); std::string uuid; - DeviceManager::GetInstance().GetEncryptedUuidByNetworkId(PKG_NAME, networkId, uuid); + ret = DeviceManager::GetInstance().GetEncryptedUuidByNetworkId(PKG_NAME, networkId, uuid); + if (ret != DM_OK) { + ZLOGE("Get uuid fail by networkId,networkId:%{public}s, ret:%{public}d", + StoreUtil::Anonymous(networkId).c_str(), ret); + continue; + } dtInfo.networkId = std::move(device.networkId); dtInfo.uuid = std::move(uuid); dtInfos.push_back(dtInfo); diff --git a/frameworks/innerkitsimpl/kvdb/src/dev_manager_mock.cpp b/frameworks/innerkitsimpl/kvdb/src/dev_manager_mock.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bc30bf76f86f2811fdfd2165fe56158f2a206eea --- /dev/null +++ b/frameworks/innerkitsimpl/kvdb/src/dev_manager_mock.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "dev_manager.h" + +namespace OHOS::DistributedKv { +static constexpr const char *PKG_NAME_EX = "kv_store"; +DevManager::DevManager(const std::string &pkgName) : PKG_NAME(pkgName) +{ + RegisterDevCallback(); +} + +int32_t DevManager::Init() +{ + return -1; +} + +void DevManager::RegisterDevCallback() +{ +} + +std::function DevManager::Retry() +{ + return nullptr; +} + +DevManager &DevManager::GetInstance() +{ + static DevManager instance(PKG_NAME_EX); + return instance; +} + +std::string DevManager::ToUUID(const std::string &networkId) +{ + (void)networkId; + return ""; +} + +std::string DevManager::ToNetworkId(const std::string &uuid) +{ + (void)uuid; + return ""; +} + +DevManager::DetailInfo DevManager::GetDevInfoFromBucket(const std::string &id) +{ + (void)id; + DetailInfo detailInfo; + return detailInfo; +} + +void DevManager::UpdateBucket() +{ +} + +std::string DevManager::GetUnEncryptedUuid() +{ + return ""; +} + +const DevManager::DetailInfo &DevManager::GetLocalDevice() +{ + return localInfo_; +} + +std::vector DevManager::GetRemoteDevices() +{ + return {}; +} +} // namespace OHOS::DistributedKv \ No newline at end of file diff --git a/frameworks/innerkitsimpl/kvdb/src/device_convertor_mock.cpp b/frameworks/innerkitsimpl/kvdb/src/device_convertor_mock.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c758844368111fa0512f84655c032043fa08dac1 --- /dev/null +++ b/frameworks/innerkitsimpl/kvdb/src/device_convertor_mock.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "device_convertor.h" + +namespace OHOS::DistributedKv { +std::vector DeviceConvertor::ToLocalDBKey(const Key &key) const +{ + return GetPrefix(key); +} + +std::vector DeviceConvertor::ToWholeDBKey(const Key &key) const +{ + return GetPrefix(key); +} + +Key DeviceConvertor::ToKey(DBKey &&key, std::string &deviceId) const +{ + (void)deviceId; + return std::move(key); +} + +std::vector DeviceConvertor::GetPrefix(const Key &prefix) const +{ + std::vector dbKey = TrimKey(prefix); + if (dbKey.size() > MAX_KEY_LENGTH) { + dbKey.clear(); + } + return dbKey; +} + +std::vector DeviceConvertor::GetPrefix(const DataQuery &query) const +{ + return GetPrefix(Key(query.prefix_)); +} + +std::string DeviceConvertor::GetRealKey(const std::string &key, const DataQuery &query) const +{ + (void)query; + return key; +} + +std::vector DeviceConvertor::ConvertNetwork(const Key &in, bool withLen) const +{ + (void)in; + (void)withLen; + return {}; +} + +std::vector DeviceConvertor::ToLocal(const Key &in, bool withLen) const +{ + (void)in; + (void)withLen; + return {}; +} +} \ No newline at end of file diff --git a/frameworks/innerkitsimpl/kvdb/src/kv_hiview_reporter.cpp b/frameworks/innerkitsimpl/kvdb/src/kv_hiview_reporter.cpp index 0e382c8001518c65fb3a9d823d1b10ddc2b45546..224e77136cb6f5ca5e6530c24664eac3b176474f 100644 --- a/frameworks/innerkitsimpl/kvdb/src/kv_hiview_reporter.cpp +++ b/frameworks/innerkitsimpl/kvdb/src/kv_hiview_reporter.cpp @@ -296,12 +296,11 @@ void KVDBFaultHiViewReporter::CreateCorruptedFlag(const std::string &dbPath, con return; } std::string flagFilename = dbPath + storeId + DB_CORRUPTED_POSTFIX; - int fd = creat(flagFilename.c_str(), S_IRWXU | S_IRWXG); + int fd = creat(flagFilename.c_str(), S_IRUSR | S_IWUSR); if (fd == -1) { ZLOGW("Creat corrupted flg fail, flgname=%{public}s, errno=%{public}d", StoreUtil::Anonymous(flagFilename).c_str(), errno); return; - } close(fd); } diff --git a/frameworks/innerkitsimpl/kvdb/src/kvdb_service_client.cpp b/frameworks/innerkitsimpl/kvdb/src/kvdb_service_client.cpp index 6541c1e7e13d957fdb09db9724900dcf1150204e..62cbc503d5f86786182daca9716c567ae75d1b68 100644 --- a/frameworks/innerkitsimpl/kvdb/src/kvdb_service_client.cpp +++ b/frameworks/innerkitsimpl/kvdb/src/kvdb_service_client.cpp @@ -45,7 +45,10 @@ namespace OHOS::DistributedKv { break; \ } \ \ - ITypesUtil::Unmarshal(reply, __status); \ + if (!ITypesUtil::Unmarshal(reply, __status)) { \ + __status = IPC_ERROR; \ + break; \ + } \ } while (0); \ __status; \ }) @@ -75,14 +78,7 @@ std::shared_ptr KVDBServiceClient::GetInstance() return nullptr; } - sptr client = nullptr; - if (service->IsProxyObject()) { - client = iface_cast(service); - } - - if (client == nullptr) { - client = new (std::nothrow) KVDBServiceClient(service); - } + sptr client = new (std::nothrow) KVDBServiceClient(service); if (client == nullptr) { return nullptr; @@ -112,7 +108,10 @@ Status KVDBServiceClient::GetStoreIds(const AppId &appId, int32_t subUser, std:: ZLOGE("status:0x%{public}x, appId:%{public}s", status, appId.appId.c_str()); return static_cast(status); } - ITypesUtil::Unmarshal(reply, storeIds); + if (!ITypesUtil::Unmarshal(reply, storeIds)) { + ZLOGE("Unmarshal storeIds fail, appId:%{public}s", appId.appId.c_str()); + return ERROR; + } return static_cast(status); } @@ -169,7 +168,7 @@ Status KVDBServiceClient::Sync(const AppId &appId, const StoreId &storeId, int32 { MessageParcel reply; int32_t status = IPC_SEND(static_cast(KVDBServiceInterfaceCode::TRANS_SYNC), reply, appId, storeId, - syncInfo.seqId, syncInfo.mode, syncInfo.devices, syncInfo.delay, syncInfo.query, subUser); + syncInfo.seqId, syncInfo.mode, syncInfo.devices, syncInfo.delay, syncInfo.query, subUser, syncInfo.isRetry); if (status != SUCCESS) { ZLOGE("status:0x%{public}x, appId:%{public}s, storeId:%{public}s, sequenceId:%{public}" PRIu64, status, appId.appId.c_str(), StoreUtil::Anonymous(storeId.storeId).c_str(), syncInfo.seqId); diff --git a/frameworks/innerkitsimpl/kvdb/src/process_system_api_adapter_impl.cpp b/frameworks/innerkitsimpl/kvdb/src/process_system_api_adapter_impl.cpp index 1c545cd24810ff5183245c7161bdcd30bd74df39..748e49adacf522e2acb6f1eb57bc444f60067350 100644 --- a/frameworks/innerkitsimpl/kvdb/src/process_system_api_adapter_impl.cpp +++ b/frameworks/innerkitsimpl/kvdb/src/process_system_api_adapter_impl.cpp @@ -56,7 +56,10 @@ ProcessSystemApiAdapterImpl::DBStatus ProcessSystemApiAdapterImpl::SetSecurityOp } struct stat curStat; - stat(filePath.c_str(), &curStat); + if (stat(filePath.c_str(), &curStat) != 0) { + ZLOGE("stat fail, error:%{public}d, path:%{public}s", errno, StoreUtil::Anonymous(filePath).c_str()); + return DBStatus::INVALID_ARGS; + } if (S_ISDIR(curStat.st_mode)) { return DBStatus::NOT_SUPPORT; } @@ -89,7 +92,10 @@ ProcessSystemApiAdapterImpl::DBStatus ProcessSystemApiAdapterImpl::GetSecurityOp } struct stat curStat; - stat(filePath.c_str(), &curStat); + if (stat(filePath.c_str(), &curStat) != 0) { + ZLOGE("stat fail, error:%{public}d, path:%{public}s", errno, StoreUtil::Anonymous(filePath).c_str()); + return DBStatus::INVALID_ARGS; + } if (S_ISDIR(curStat.st_mode)) { return DBStatus::NOT_SUPPORT; } diff --git a/frameworks/innerkitsimpl/kvdb/src/security_manager.cpp b/frameworks/innerkitsimpl/kvdb/src/security_manager.cpp index 6adcb2ad332db4e4fcd5167fbecbba15baa29b99..60bfaa64b55c0c0cc936ec377d848795cb0b9c3b 100644 --- a/frameworks/innerkitsimpl/kvdb/src/security_manager.cpp +++ b/frameworks/innerkitsimpl/kvdb/src/security_manager.cpp @@ -244,15 +244,20 @@ bool SecurityManager::SaveKeyToFile(const std::string &name, const std::string & keyContent.assign(keyContent.size(), 0); auto keyPath = path + KEY_DIR; StoreUtil::InitPath(keyPath); - std::vector content; - for (size_t index = 0; index < SecurityContent::MAGIC_NUM; ++index) { - content.push_back(char(SecurityContent::MAGIC_CHAR)); - } - content.insert(content.end(), securityContent.nonceValue.begin(), securityContent.nonceValue.end()); - content.insert(content.end(), securityContent.encryptValue.begin(), securityContent.encryptValue.end()); auto keyFullPath = keyPath + SLASH + name + SUFFIX_KEY_V1; - auto ret = SaveBufferToFile(keyFullPath, content); - content.assign(content.size(), 0); + auto fd = open(keyFullPath.c_str(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); + if (fd < 0) { + ZLOGE("Create file failed, ret:%{public}d", errno); + return false; + } + std::string content(SecurityContent::MAGIC_NUM, static_cast(SecurityContent::MAGIC_CHAR)); + content.append(reinterpret_cast(securityContent.nonceValue.data()), + securityContent.nonceValue.size()); + content.append(reinterpret_cast(securityContent.encryptValue.data()), + securityContent.encryptValue.size()); + auto ret = SaveStringToFd(fd, content); + std::fill(content.begin(), content.end(), '\0'); + close(fd); if (!ret) { ZLOGE("Save key to file fail, ret:%{public}d", ret); return false; @@ -456,7 +461,7 @@ SecurityManager::KeyFiles::KeyFiles(const std::string &name, const std::string & if (!openFile) { return; } - lockFd_ = open(lockFile_.c_str(), O_RDONLY | O_CREAT, S_IRWXU | S_IRWXG); + lockFd_ = open(lockFile_.c_str(), O_RDONLY | O_CREAT, S_IRUSR | S_IWUSR); if (lockFd_ < 0) { ZLOGE("Open failed, errno:%{public}d, path:%{public}s", errno, StoreUtil::Anonymous(lockFile_).c_str()); } diff --git a/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp b/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp index e5384033fc441e707c8e43e069bbe17d7af2169b..f2eb4bd4fcfd6085c447306516ccb858ccc66d47 100644 --- a/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp +++ b/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp @@ -17,22 +17,24 @@ #include #include "accesstoken_kit.h" +#include "acl.h" #include "auto_sync_timer.h" #include "backup_manager.h" #include "dds_trace.h" #include "dev_manager.h" #include "ipc_skeleton.h" +#include "kv_hiview_reporter.h" #include "kvdb_service_client.h" #include "log_print.h" #include "store_result_set.h" #include "store_util.h" #include "task_executor.h" -#include "kv_hiview_reporter.h" namespace OHOS::DistributedKv { using namespace OHOS::DistributedDataDfx; using namespace std::chrono; using namespace Security::AccessToken; +using namespace DATABASE_UTILS; SingleStoreImpl::SingleStoreImpl( std::shared_ptr dbStore, const AppId &appId, const Options &options, const Convertor &cvt) : convertor_(cvt), dbStore_(std::move(dbStore)) @@ -52,9 +54,8 @@ SingleStoreImpl::SingleStoreImpl( area_ = options.area; hapName_ = options.hapName; subUser_ = options.subUser; - if (options.backup) { - BackupManager::GetInstance().Prepare(path, storeId_); - } + syncable_ = options.syncable; + autoBackup_ = options.backup; uint32_t tokenId = IPCSkeleton::GetSelfTokenID(); if (AccessTokenKit::GetTokenTypeFlag(tokenId) == TOKEN_HAP) { isApplication_ = true; @@ -63,6 +64,12 @@ SingleStoreImpl::SingleStoreImpl( if (!isApplication_) { isCheckIntegrity_ = true; } + if (syncable_ || autoBackup_) { + SetAcl(storeId_, path); + if (autoBackup_) { + BackupManager::GetInstance().Prepare(path, storeId_); + } + } } SingleStoreImpl::~SingleStoreImpl() @@ -610,6 +617,19 @@ Status SingleStoreImpl::Sync(const std::vector &devices, SyncMode m return DoSync(syncInfo, syncCallback); } +Status SingleStoreImpl::Sync(const std::vector &devices, SyncMode mode, const DataQuery &query, + bool isRetry, std::shared_ptr syncCallback) +{ + DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); + KVDBService::SyncInfo syncInfo; + syncInfo.seqId = StoreUtil::GenSequenceId(); + syncInfo.mode = mode; + syncInfo.devices = devices; + syncInfo.query = query.ToString(); + syncInfo.isRetry = isRetry; + return DoSync(syncInfo, syncCallback); +} + Status SingleStoreImpl::CloudSync(const AsyncDetail &async) { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); @@ -797,6 +817,9 @@ Status SingleStoreImpl::Restore(const std::string &file, const std::string &base ZLOGE("status:0x%{public}x storeId:%{public}s backup:%{public}s ", status, StoreUtil::Anonymous(storeId_).c_str(), file.c_str()); } + if (syncable_ || autoBackup_) { + SetAcl(storeId_, path_); + } Options options = { .encrypt = encrypt_, .autoSync = autoSync_, .securityLevel = securityLevel_, .area = area_, .hapName = hapName_ }; ReportInfo reportInfo = { .options = options, .errorCode = status, .systemErrorNo = errno, @@ -1086,4 +1109,38 @@ void SingleStoreImpl::ReportDBFaultEvent(Status status, const std::string &funct .appId = appId_, .storeId = storeId_, .functionName = functionName }; KVDBFaultHiViewReporter::ReportKVFaultEvent(reportInfo); } + +void SingleStoreImpl::SetAcl(const std::string &storeId, const std::string &path) +{ + std::string dbPath = ""; + DistributedDB::KvStoreDelegateManager::GetDatabaseDir(storeId_, dbPath); + std::string fullPath = path + "/kvdb/" +dbPath + "/single_ver/"; + if (!StoreUtil::SetDatabaseGid(fullPath)) { + return; + } + auto dbFiles = GenerateDbFiles(fullPath); + for (auto &dbFile : dbFiles) { + if (!StoreUtil::SetServiceGid(dbFile)) { + return; + } + } +} + +std::vector SingleStoreImpl::GenerateDbFiles(const std::string &path) +{ + std::vector dbFiles; + if (path.empty()) { + return dbFiles; + } + dbFiles.push_back(path + "/main"); + dbFiles.push_back(path + "/main/gen_natural_store.db"); + dbFiles.push_back(path + "/main/gen_natural_store.db-shm"); + dbFiles.push_back(path + "/main/gen_natural_store.db-wal"); + dbFiles.push_back(path + "/meta"); + dbFiles.push_back(path + "/meta/meta.db"); + dbFiles.push_back(path + "/meta/meta.db-shm"); + dbFiles.push_back(path + "/meta/meta.db-wal"); + dbFiles.push_back(path + "/cache"); + return dbFiles; +} } // namespace OHOS::DistributedKv \ No newline at end of file diff --git a/frameworks/innerkitsimpl/kvdb/src/store_factory.cpp b/frameworks/innerkitsimpl/kvdb/src/store_factory.cpp index 6f8e929bc8d3ac6b78b1af82c4845b79c25c88c7..e815ad2a9b47b83ed43f466c1f4a8e5867e66658 100644 --- a/frameworks/innerkitsimpl/kvdb/src/store_factory.cpp +++ b/frameworks/innerkitsimpl/kvdb/src/store_factory.cpp @@ -196,6 +196,7 @@ StoreFactory::DBOption StoreFactory::GetDBOption(const Options &options, const D dbOption.rdconfig.readOnly = (options.role == VISITOR ? true : false); dbOption.isMemoryDb = (!options.persistent); dbOption.isEncryptedDb = options.encrypt; + dbOption.localOnly = !options.isClientSync; if (options.encrypt) { dbOption.cipher = DistributedDB::CipherType::AES_256_GCM; dbOption.passwd = dbPassword.password; @@ -207,12 +208,12 @@ StoreFactory::DBOption StoreFactory::GetDBOption(const Options &options, const D dbOption.conflictResolvePolicy = DistributedDB::LAST_WIN; } else if (options.kvStoreType == KvStoreType::LOCAL_ONLY) { dbOption.storageEngineType = DistributedDB::GAUSSDB_RD; + dbOption.localOnly = false; } dbOption.schema = options.schema; dbOption.createDirByStoreIdOnly = true; dbOption.secOption = StoreUtil::GetDBSecurity(options.securityLevel); - dbOption.localOnly = !options.syncable; dbOption.rdconfig.type = StoreUtil::GetDBIndexType(options.config.type); dbOption.rdconfig.pageSize = options.config.pageSize; dbOption.rdconfig.cacheSize = options.config.cacheSize; diff --git a/frameworks/innerkitsimpl/kvdb/src/store_manager.cpp b/frameworks/innerkitsimpl/kvdb/src/store_manager.cpp index 62d1acdd73624bf3537bd05b581022a938c3dd57..1484e74f4382c2d9611b6dd32117243d6f4d55a0 100644 --- a/frameworks/innerkitsimpl/kvdb/src/store_manager.cpp +++ b/frameworks/innerkitsimpl/kvdb/src/store_manager.cpp @@ -18,6 +18,7 @@ #include "backup_manager.h" #include "dev_manager.h" #include "kvdb_service_client.h" +#include "kvstore_service_death_notifier.h" #include "log_print.h" #include "security_manager.h" @@ -213,6 +214,14 @@ Status StoreManager::SubscribeSwitchData(const AppId &appId, std::shared_ptrAddSwitchCallback(appId.appId, observer); + switchObservers_.Compute(appId.appId, [appId, observer](auto &, auto &switchBridge) { + if (switchBridge == nullptr) { + switchBridge = std::make_shared(appId); + KvStoreServiceDeathNotifier::AddServiceDeathWatcher(switchBridge); + } + switchBridge->AddSwitchCallback(observer); + return true; + }); return SUCCESS; } @@ -235,6 +244,12 @@ Status StoreManager::UnsubscribeSwitchData(const AppId &appId, std::shared_ptrDeleteSwitchCallback(appId.appId, observer); + switchObservers_.ComputeIfPresent(appId.appId, [appId, observer](auto &, auto &switchBridge) { + if (switchBridge != nullptr) { + switchBridge->DeleteSwitchCallback(observer); + } + return true; + }); return SUCCESS; } -} // namespace OHOS::DistributedKv \ No newline at end of file +} \ No newline at end of file diff --git a/frameworks/innerkitsimpl/kvdb/src/store_util.cpp b/frameworks/innerkitsimpl/kvdb/src/store_util.cpp index ddd0d95a5f5c04be2dd8a8581c786f4f025de2ec..5b52cf6f80817a34af5ab11f31b587f3d15d80f6 100644 --- a/frameworks/innerkitsimpl/kvdb/src/store_util.cpp +++ b/frameworks/innerkitsimpl/kvdb/src/store_util.cpp @@ -16,6 +16,7 @@ #include "store_util.h" #include #include +#include #include #include #include "log_print.h" @@ -27,9 +28,9 @@ constexpr mode_t DEFAULT_UMASK = 0002; constexpr int32_t HEAD_SIZE = 3; constexpr int32_t END_SIZE = 3; constexpr int32_t MIN_SIZE = HEAD_SIZE + END_SIZE + 3; +constexpr int32_t SERVICE_GID = 3012; constexpr const char *REPLACE_CHAIN = "***"; constexpr const char *DEFAULT_ANONYMOUS = "******"; -constexpr int32_t SERVICE_GID = 3012; std::atomic StoreUtil::sequenceId_ = 0; using DBStatus = DistributedDB::DBStatus; std::map StoreUtil::statusMap_ = { @@ -162,9 +163,8 @@ bool StoreUtil::InitPath(const std::string &path) ZLOGE("Mkdir error:%{public}d, path:%{public}s", errno, Anonymous(path).c_str()); return false; } - Acl acl(path); - acl.SetDefaultUser(getuid(), Acl::R_RIGHT | Acl::W_RIGHT); - acl.SetDefaultGroup(SERVICE_GID, Acl::R_RIGHT | Acl::W_RIGHT); + Acl acl(path, Acl::ACL_XATTR_DEFAULT); + acl.SetDefaultUser(getuid(), Acl::R_RIGHT | Acl::W_RIGHT | Acl::E_RIGHT); return true; } @@ -174,7 +174,7 @@ bool StoreUtil::CreateFile(const std::string &name) if (access(name.c_str(), F_OK) == 0) { return RemoveRWXForOthers(name); } - int fp = open(name.c_str(), (O_WRONLY | O_CREAT), (S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP)); + int fp = open(name.c_str(), (O_WRONLY | O_CREAT), (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)); if (fp < 0) { ZLOGE("Fopen error:%{public}d, path:%{public}s", errno, Anonymous(name).c_str()); return false; @@ -316,4 +316,64 @@ bool StoreUtil::RemoveRWXForOthers(const std::string &path) } return true; } + +bool StoreUtil::HasPermit(const std::string &path, mode_t mode) +{ + struct stat fileStat; + if (stat(path.c_str(), &fileStat) == 0) { + if (S_ISDIR(fileStat.st_mode) && ((mode & fileStat.st_mode) == mode)) { + return true; + } + } + return false; +} + +bool StoreUtil::SetDatabaseGid(const std::string &path) +{ + std::string tempDir = path; + size_t pos = tempDir.find('/'); + std::string targetPath = ""; + bool isSetAcl = false; + while (pos != std::string::npos) { + std::string dir = tempDir.substr(0, pos); + tempDir = tempDir.substr(pos + 1); + pos = tempDir.find('/'); + if (dir.empty()) { + continue; + } + if (dir == "database") { + isSetAcl = true; + } + targetPath = targetPath + "/" + dir; + if (isSetAcl && !HasPermit(targetPath, S_IXOTH)) { + if (!SetServiceGid(targetPath)) { + return false; + } + } + } + return true; +} + +bool StoreUtil::SetServiceGid(const std::string &filePath) +{ + if (filePath.empty()) { + ZLOGE("filePath is empty"); + return false; + } + struct stat fileStat; + if (stat(filePath.c_str(), &fileStat) != 0) { + ZLOGE("file not exit, filePath:%{public}s ,code:%{public}d", Anonymous(filePath).c_str(), errno); + return false; + } + uint16_t mode = Acl::R_RIGHT | Acl::W_RIGHT | Acl::E_RIGHT; + Acl acl(filePath, Acl::ACL_XATTR_ACCESS); + if (!acl.HasAccessGroup(SERVICE_GID, mode)) { + auto res = acl.SetAccessGroup(SERVICE_GID, mode); + if (res != 0) { + ZLOGE("access group set failed, error code is :%{public}d", res); + return false; + } + } + return true; +} } // namespace OHOS::DistributedKv \ No newline at end of file diff --git a/frameworks/innerkitsimpl/kvdb/src/system_api.cpp b/frameworks/innerkitsimpl/kvdb/src/system_api.cpp index 1819c49051fec0132ecbceba57d03ffab541420a..f5b426b700c2b7e6e551ec7b341c7163810838f1 100644 --- a/frameworks/innerkitsimpl/kvdb/src/system_api.cpp +++ b/frameworks/innerkitsimpl/kvdb/src/system_api.cpp @@ -49,7 +49,10 @@ SystemApi::DBStatus SystemApi::SetSecurityOption(const std::string &filePath, co } struct stat curStat; - stat(filePath.c_str(), &curStat); + if (stat(filePath.c_str(), &curStat) != 0) { + ZLOGE("stat fail, error:%{public}d, path:%{public}s", errno, StoreUtil::Anonymous(filePath).c_str()); + return DBStatus::INVALID_ARGS; + } if (S_ISDIR(curStat.st_mode)) { return DBStatus::NOT_SUPPORT; } @@ -80,7 +83,10 @@ SystemApi::DBStatus SystemApi::GetSecurityOption(const std::string &filePath, DB } struct stat curStat; - stat(filePath.c_str(), &curStat); + if (stat(filePath.c_str(), &curStat) != 0) { + ZLOGE("stat fail, error:%{public}d, path:%{public}s", errno, StoreUtil::Anonymous(filePath).c_str()); + return DBStatus::INVALID_ARGS; + } if (S_ISDIR(curStat.st_mode)) { return DBStatus::NOT_SUPPORT; } diff --git a/frameworks/innerkitsimpl/kvdb/test/BUILD.gn b/frameworks/innerkitsimpl/kvdb/test/BUILD.gn index 3dea6ee75ef26a62111d780d8ad172df7d896bf9..abe0f104b33e4e92cf11c74ba8f163ac4875b64a 100644 --- a/frameworks/innerkitsimpl/kvdb/test/BUILD.gn +++ b/frameworks/innerkitsimpl/kvdb/test/BUILD.gn @@ -26,14 +26,15 @@ config("module_private_config") { "../../../../interfaces/innerkits/distributeddatamgr/include/", "//foundation/distributeddatamgr/kv_store/frameworks/common", "//foundation/distributeddatamgr/kv_store/frameworks/innerkitsimpl/kvdb/include", - "//foundation/distributeddatamgr/kv_store/frameworks/innerkitsimpl/kvdb/src", - "${kv_store_base_path}/frameworks/innerkitsimpl/kvdb/test/mock", "//foundation/distributeddatamgr/kv_store/frameworks/innerkitsimpl/distributeddatafwk/include", "//foundation/distributeddatamgr/kv_store/frameworks/innerkitsimpl/distributeddatafwk/src", - "//foundation/distributeddatamgr/kv_store/frameworks/innerkitsimpl/distributeddatafwk/test/distributedtest/single_kvstore_client", "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/app_distributeddata/include", "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/distributeddata/include", + "//foundation/distributeddatamgr/kv_store/databaseutils/include", ] + if (dm_service_enable) { + include_dirs += [ "${kv_store_base_path}/frameworks/innerkitsimpl/kvdb/test/mock" ] + } lib_dirs = [ "//foundation/appexecfwk/libs" ] } @@ -55,14 +56,13 @@ ohos_source_set("kvdb_src_file") { "../../distributeddatafwk/src/kvstore_datashare_bridge.cpp", "../../distributeddatafwk/src/kvstore_observer_client.cpp", "../../distributeddatafwk/src/kvstore_service_death_notifier.cpp", + "../../distributeddatafwk/src/switch_observer_bridge.cpp", "../../distributeddatafwk/src/sync_observer.cpp", ] kvdb_sources = [ "../src/backup_manager.cpp", "../src/convertor.cpp", - "../src/dev_manager.cpp", - "../src/device_convertor.cpp", "../src/kv_types_util.cpp", "../src/kvdb_service_client.cpp", "../src/observer_bridge.cpp", @@ -78,11 +78,6 @@ ohos_source_set("kvdb_src_file") { ] sources = old_sources + kvdb_sources - if (qemu_disable) { - sources += [ "../src/auto_sync_timer.cpp" ] - } else { - sources += [ "../src/auto_sync_timer_mock.cpp" ] - } configs = [ ":module_private_config" ] deps = [ @@ -94,7 +89,6 @@ ohos_source_set("kvdb_src_file") { "access_token:libaccesstoken_sdk", "access_token:libtokenid_sdk", "c_utils:utils", - "device_manager:devicemanagersdk", "file_api:securitylabel", "hilog:libhilog", "hisysevent:libhisysevent", @@ -105,7 +99,22 @@ ohos_source_set("kvdb_src_file") { "samgr:samgr_proxy", ] if (dms_service_enable && qemu_disable) { + sources += [ "${kv_store_base_path}/frameworks/innerkitsimpl/kvdb/src/auto_sync_timer.cpp" ] external_deps += [ "dmsfwk:distributed_sdk" ] + } else { + sources += [ "${kv_store_base_path}/frameworks/innerkitsimpl/kvdb/src/auto_sync_timer_mock.cpp" ] + } + if (dm_service_enable) { + sources += [ + "${kv_store_base_path}/frameworks/innerkitsimpl/kvdb/src/dev_manager.cpp", + "${kv_store_base_path}/frameworks/innerkitsimpl/kvdb/src/device_convertor.cpp", + ] + external_deps += [ "device_manager:devicemanagersdk" ] + } else { + sources += [ + "${kv_store_base_path}/frameworks/innerkitsimpl/kvdb/src/dev_manager_mock.cpp", + "${kv_store_base_path}/frameworks/innerkitsimpl/kvdb/src/device_convertor_mock.cpp", + ] } public_external_deps = [ @@ -169,6 +178,10 @@ ohos_unittest("StoreUtilTest") { "samgr:samgr_proxy", ] + cflags = [ + "-Dprivate=public", + ] + deps = [ ":kvdb_src_file", "//foundation/distributeddatamgr/kv_store/frameworks/libs/distributeddb/:distributeddb", @@ -336,6 +349,7 @@ ohos_unittest("StoreFactoryMockTest") { "../../distributeddatafwk/src/kvstore_observer_client.cpp", "../../distributeddatafwk/src/kvstore_service_death_notifier.cpp", "../../distributeddatafwk/src/sync_observer.cpp", + "../../distributeddatafwk/src/switch_observer_bridge.cpp", "../../kvdb/src/kv_hiview_reporter_mock.cpp", "../src/backup_manager.cpp", "../src/convertor.cpp", @@ -411,6 +425,7 @@ ohos_unittest("SingleStoreImplMockTest") { "../../distributeddatafwk/src/kvstore_datashare_bridge.cpp", "../../distributeddatafwk/src/kvstore_observer_client.cpp", "../../distributeddatafwk/src/kvstore_service_death_notifier.cpp", + "../../distributeddatafwk/src/switch_observer_bridge.cpp", "../../distributeddatafwk/src/sync_observer.cpp", "../../kvdb/src/kv_hiview_reporter_mock.cpp", "../src/backup_manager.cpp", @@ -483,6 +498,35 @@ ohos_unittest("SingleStoreImplMockTest") { use_exceptions = true } +ohos_unittest("KvHiviewReporterTest") { + module_out_path = module_output_path + sources = [ + "../../kvdb/src/kv_hiview_reporter.cpp", + "./mock/src/hisysevent_mock.cpp", + "kv_hiview_reporter_test.cpp", + "../src/store_util.cpp", + ] + configs = [ ":module_private_config" ] + deps = [ + "${kv_store_base_path}/frameworks/libs/distributeddb:distributeddb", + "${kv_store_base_path}/interfaces/innerkits/distributeddata:distributeddata_inner", + "${kv_store_base_path}/databaseutils:database_utils", + ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "hisysevent:libhisysevent", + "googletest:gmock_main", + "googletest:gtest_main", + ] + + defines = [ + "private=public", + "protected=public", + ] +} + ############################################################################### group("unittest") { testonly = true @@ -490,12 +534,7 @@ group("unittest") { deps = [] deps += [ ":BackupManagerTest", - ":DevManagerMockTest", - ":DevManagerTest", ":SingleStoreImplGetTopTest", - ":SingleStoreImplMockTest", - ":SingleStoreImplTest", - ":StoreFactoryMockTest", ":StoreFactoryTest", ":StoreUtilTest", ] @@ -503,5 +542,16 @@ group("unittest") { if (!use_libfuzzer) { deps += [ ":SecurityManagerTest" ] } + + if (dm_service_enable) { + deps += [ + ":DevManagerMockTest", + ":DevManagerTest", + ":KvHiviewReporterTest", + ":SingleStoreImplMockTest", + ":SingleStoreImplTest", + ":StoreFactoryMockTest", + ] + } } ############################################################################### diff --git a/frameworks/innerkitsimpl/kvdb/test/auto_sync_timer_test.cpp b/frameworks/innerkitsimpl/kvdb/test/auto_sync_timer_test.cpp deleted file mode 100644 index 63983305c8220e90cf2f0db6549880bd80c6d527..0000000000000000000000000000000000000000 --- a/frameworks/innerkitsimpl/kvdb/test/auto_sync_timer_test.cpp +++ /dev/null @@ -1,412 +0,0 @@ -/* -* Copyright (c) 2022 Huawei Device Co., Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#include "auto_sync_timer.h" - -#include - -#include "block_data.h" -#include "kvdb_service_client.h" -#include "store_manager.h" - -using namespace OHOS; -using namespace testing::ext; -using namespace OHOS::DistributedKv; -using namespace std::chrono; -namespace OHOS::Test { -class AutoSyncTimerTest : public testing::Test { -public: - class KVDBServiceMock : public KVDBServiceClient { - private: - static KVDBServiceMock *instance_; - - public: - static KVDBServiceMock *GetInstance() - { - KVDBServiceClient::GetInstance(); - return instance_; - } - explicit KVDBServiceMock(const sptr &object) : KVDBServiceClient(object) - { - instance_ = this; - } - virtual ~KVDBServiceMock() - { - instance_ = nullptr; - } - - Status Sync(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) override - { - endTime = time_point_cast(system_clock::now()).time_since_epoch().count(); - values_[appId.appId].insert(storeId.storeId); - { - std::lock_guard guard(mutex_); - ++callCount; - value_.SetValue(callCount); - } - return KVDBServiceClient::Sync(appId, storeId, syncInfo); - } - - uint32_t GetCallCount(uint32_t value) - { - uint32_t retry = 0; - uint32_t callTimes = 0; - while (retry < value) { - callTimes = value_.GetValue(); - if (callTimes >= value) { - break; - } - std::lock_guard guard(mutex_); - callTimes = value_.GetValue(); - if (callTimes >= value) { - break; - } - value_.Clear(callTimes); - retry++; - } - return callTimes; - } - - void ResetToZero() - { - std::lock_guard guard(mutex_); - callCount = 0; - value_.Clear(0); - } - - uint64_t startTime = 0; - uint64_t endTime = 0; - uint32_t callCount = 0; - std::map> values_; - BlockData value_{ 1, 0 }; - std::mutex mutex_; - }; - class TestSyncCallback : public KvStoreSyncCallback { - public: - void SyncCompleted(const std::map &results) override - { - ASSERT_TRUE(true); - } - }; - static void SetUpTestCase(void); - static void TearDownTestCase(void); - void SetUp(); - void TearDown(); - -protected: - static BrokerDelegator delegator_; - static constexpr int SLEEP_TIME = 10; -}; -BrokerDelegator AutoSyncTimerTest::delegator_; -AutoSyncTimerTest::KVDBServiceMock *AutoSyncTimerTest::KVDBServiceMock::instance_ = nullptr; -void AutoSyncTimerTest::SetUpTestCase(void) -{ -} - -void AutoSyncTimerTest::TearDownTestCase(void) -{ -} - -void AutoSyncTimerTest::SetUp(void) -{ -} - -void AutoSyncTimerTest::TearDown(void) -{ - sleep(SLEEP_TIME); // make sure the case has executed completely -} - -/** -* @tc.name: SingleWrite -* @tc.desc: single write -* @tc.type: FUNC -* @tc.require: I4XVQQ -* @tc.author: Yang Qing -*/ -HWTEST_F(AutoSyncTimerTest, SingleWrite, TestSize.Level0) -{ - auto *instance = KVDBServiceMock::GetInstance(); - ASSERT_NE(instance, nullptr); - instance->ResetToZero(); - instance->startTime = time_point_cast(system_clock::now()).time_since_epoch().count(); - instance->endTime = 0; - instance->values_.clear(); - AutoSyncTimer::GetInstance().DoAutoSync("ut_test", { { "ut_test_store" } }); - EXPECT_EQ(static_cast(instance->GetCallCount(1)), 1); - auto it = instance->values_.find("ut_test"); - ASSERT_NE(it, instance->values_.end()); - ASSERT_EQ(it->second.count("ut_test_store"), 1); - ASSERT_LT(instance->endTime - instance->startTime, 100); -} - -/** -* @tc.name: MultiWriteBelowDelayTime -* @tc.desc: write every 40 milliseconds -* @tc.type: FUNC -* @tc.require: I4XVQQ -* @tc.author: Yang Qing -*/ -HWTEST_F(AutoSyncTimerTest, MultiWriteBelowDelayTime, TestSize.Level1) -{ - auto *instance = KVDBServiceMock::GetInstance(); - ASSERT_NE(instance, nullptr); - instance->ResetToZero(); - instance->startTime = time_point_cast(system_clock::now()).time_since_epoch().count(); - instance->endTime = 0; - instance->values_.clear(); - std::atomic_bool finished = false; - std::thread thread([&finished] { - while (!finished.load()) { - AutoSyncTimer::GetInstance().DoAutoSync("ut_test", { { "ut_test_store" } }); - std::this_thread::sleep_for(std::chrono::milliseconds(40)); - } - }); - EXPECT_EQ(static_cast(instance->GetCallCount(1)), 1); - ASSERT_GE(instance->endTime - instance->startTime, 200); - ASSERT_LT(instance->endTime - instance->startTime, 250); - finished.store(true); - thread.join(); - auto it = instance->values_.find("ut_test"); - ASSERT_NE(it, instance->values_.end()); - ASSERT_EQ(it->second.count("ut_test_store"), 1); -} - -/** -* @tc.name: MultiWriteOverDelayTime -* @tc.desc: write every 150 milliseconds -* @tc.type: FUNC -* @tc.require: I4XVQQ -* @tc.author: Yang Qing - */ -HWTEST_F(AutoSyncTimerTest, MultiWriteOverDelayTime, TestSize.Level1) -{ - auto *instance = KVDBServiceMock::GetInstance(); - ASSERT_NE(instance, nullptr); - instance->ResetToZero(); - instance->startTime = time_point_cast(system_clock::now()).time_since_epoch().count(); - instance->endTime = 0; - instance->values_.clear(); - std::atomic_bool finished = false; - std::thread thread([&finished] { - while (!finished.load()) { - AutoSyncTimer::GetInstance().DoAutoSync("ut_test", { { "ut_test_store" } }); - std::this_thread::sleep_for(std::chrono::milliseconds(150)); - } - }); - EXPECT_EQ(static_cast(instance->GetCallCount(1)), 1); - ASSERT_LT(instance->endTime - instance->startTime, 100); - finished.store(true); - thread.join(); - auto it = instance->values_.find("ut_test"); - ASSERT_NE(it, instance->values_.end()); - ASSERT_EQ(it->second.count("ut_test_store"), 1); -} - -/** -* @tc.name: MultiWriteOverForceTime -* @tc.desc: write every 400 milliseconds -* @tc.type: FUNC -* @tc.require: I4XVQQ -* @tc.author: Yang Qing - */ -HWTEST_F(AutoSyncTimerTest, MultiWriteOverForceTime, TestSize.Level1) -{ - auto *instance = KVDBServiceMock::GetInstance(); - ASSERT_NE(instance, nullptr); - instance->ResetToZero(); - instance->startTime = time_point_cast(system_clock::now()).time_since_epoch().count(); - instance->endTime = 0; - instance->values_.clear(); - std::atomic_bool finished = false; - std::thread thread([&finished] { - while (!finished.load()) { - AutoSyncTimer::GetInstance().DoAutoSync("ut_test", { { "ut_test_store" } }); - std::this_thread::sleep_for(std::chrono::milliseconds(400)); - } - }); - EXPECT_EQ(static_cast(instance->GetCallCount(1)), 1); - ASSERT_LT(instance->endTime - instance->startTime, 100); - finished.store(true); - thread.join(); - auto it = instance->values_.find("ut_test"); - ASSERT_NE(it, instance->values_.end()); - ASSERT_EQ(it->second.count("ut_test_store"), 1); -} - -/** -* @tc.name: SingleWriteOvertenKVStores -* @tc.desc: single write over ten kv stores -* @tc.type: FUNC -* @tc.require: I4XVQQ -* @tc.author: Yang Qing -*/ -HWTEST_F(AutoSyncTimerTest, SingleWriteOvertenKVStores, TestSize.Level1) -{ - auto *instance = KVDBServiceMock::GetInstance(); - ASSERT_NE(instance, nullptr); - instance->ResetToZero(); - instance->startTime = time_point_cast(system_clock::now()).time_since_epoch().count(); - instance->endTime = 0; - instance->values_.clear(); - AutoSyncTimer::GetInstance().DoAutoSync("ut_test", { - { "ut_test_store0" }, - { "ut_test_store1" }, - { "ut_test_store2" }, - { "ut_test_store3" }, - { "ut_test_store4" }, - { "ut_test_store5" }, - { "ut_test_store6" }, - { "ut_test_store7" }, - { "ut_test_store8" }, - { "ut_test_store9" }, - { "ut_test_store10" }, - }); - EXPECT_EQ(static_cast(instance->GetCallCount(1)), 1); - ASSERT_LT(instance->endTime - instance->startTime, 100); - EXPECT_EQ(static_cast(instance->GetCallCount(11)), 11); - auto it = instance->values_.find("ut_test"); - ASSERT_NE(it, instance->values_.end()); - ASSERT_EQ(it->second.count("ut_test_store0"), 1); - ASSERT_EQ(it->second.count("ut_test_store1"), 1); - ASSERT_EQ(it->second.count("ut_test_store2"), 1); - ASSERT_EQ(it->second.count("ut_test_store3"), 1); - ASSERT_EQ(it->second.count("ut_test_store4"), 1); - ASSERT_EQ(it->second.count("ut_test_store5"), 1); - ASSERT_EQ(it->second.count("ut_test_store6"), 1); - ASSERT_EQ(it->second.count("ut_test_store7"), 1); - ASSERT_EQ(it->second.count("ut_test_store8"), 1); - ASSERT_EQ(it->second.count("ut_test_store9"), 1); - ASSERT_EQ(it->second.count("ut_test_store10"), 1); -} - -/** -* @tc.name: MultiWriteOvertenKVStores -* @tc.desc: mulity wirte -* @tc.type: FUNC -* @tc.require: I4XVQQ -* @tc.author: YangQing -*/ -HWTEST_F(AutoSyncTimerTest, MultiWriteOvertenKVStores, TestSize.Level1) -{ - auto *instance = KVDBServiceMock::GetInstance(); - ASSERT_NE(instance, nullptr); - instance->ResetToZero(); - instance->startTime = time_point_cast(system_clock::now()).time_since_epoch().count(); - instance->endTime = 0; - instance->values_.clear(); - std::atomic_bool finished = false; - std::thread thread([&finished] { - while (!finished.load()) { - AutoSyncTimer::GetInstance().DoAutoSync("ut_test", { - { "ut_test_store0" }, - { "ut_test_store1" }, - { "ut_test_store2" }, - { "ut_test_store3" }, - { "ut_test_store4" }, - { "ut_test_store5" }, - { "ut_test_store6" }, - { "ut_test_store7" }, - { "ut_test_store8" }, - { "ut_test_store9" }, - { "ut_test_store10" }, - }); - usleep(40); - } - }); - EXPECT_EQ(static_cast(instance->GetCallCount(1)), 1); - ASSERT_GE(instance->endTime - instance->startTime, 200); - ASSERT_LT(instance->endTime - instance->startTime, 250); - EXPECT_EQ(static_cast(instance->GetCallCount(11)), 11); - auto it = instance->values_.find("ut_test"); - ASSERT_EQ(it->second.count("ut_test_store0"), 1); - ASSERT_EQ(it->second.count("ut_test_store1"), 1); - ASSERT_EQ(it->second.count("ut_test_store2"), 1); - ASSERT_EQ(it->second.count("ut_test_store3"), 1); - ASSERT_EQ(it->second.count("ut_test_store4"), 1); - ASSERT_EQ(it->second.count("ut_test_store5"), 1); - ASSERT_EQ(it->second.count("ut_test_store6"), 1); - ASSERT_EQ(it->second.count("ut_test_store7"), 1); - ASSERT_EQ(it->second.count("ut_test_store8"), 1); - ASSERT_EQ(it->second.count("ut_test_store9"), 1); - ASSERT_EQ(it->second.count("ut_test_store10"), 1); - finished.store(true); - thread.join(); -} - -/** -* @tc.name: DoubleWrite -* @tc.desc: double wirte -* @tc.type: FUNC -* @tc.require: I4XVQQ -* @tc.author: YangQing - */ -HWTEST_F(AutoSyncTimerTest, DoubleWrite, TestSize.Level1) -{ - auto *instance = KVDBServiceMock::GetInstance(); - ASSERT_NE(instance, nullptr); - instance->ResetToZero(); - instance->startTime = time_point_cast(system_clock::now()).time_since_epoch().count(); - instance->endTime = 0; - instance->values_.clear(); - AutoSyncTimer::GetInstance().DoAutoSync("ut_test", { - { "ut_test_store0" }, - { "ut_test_store1" }, - { "ut_test_store2" }, - { "ut_test_store3" }, - { "ut_test_store4" }, - { "ut_test_store5" }, - { "ut_test_store6" }, - { "ut_test_store7" }, - { "ut_test_store8" }, - { "ut_test_store9" }, - { "ut_test_store10" }, - }); - AutoSyncTimer::GetInstance().DoAutoSync("ut_test", { - { "ut_test_store-0" }, - { "ut_test_store-1" }, - { "ut_test_store-2" }, - { "ut_test_store-3" }, - { "ut_test_store-4" }, - { "ut_test_store-5" }, - { "ut_test_store-6" }, - { "ut_test_store-7" }, - { "ut_test_store-8" }, - }); - EXPECT_EQ(static_cast(instance->GetCallCount(1)), 1); - ASSERT_LT(instance->endTime - instance->startTime, 100); - EXPECT_EQ(static_cast(instance->GetCallCount(20)), 20); - auto it = instance->values_.find("ut_test"); - ASSERT_EQ(it->second.count("ut_test_store0"), 1); - ASSERT_EQ(it->second.count("ut_test_store1"), 1); - ASSERT_EQ(it->second.count("ut_test_store2"), 1); - ASSERT_EQ(it->second.count("ut_test_store3"), 1); - ASSERT_EQ(it->second.count("ut_test_store4"), 1); - ASSERT_EQ(it->second.count("ut_test_store5"), 1); - ASSERT_EQ(it->second.count("ut_test_store6"), 1); - ASSERT_EQ(it->second.count("ut_test_store7"), 1); - ASSERT_EQ(it->second.count("ut_test_store8"), 1); - ASSERT_EQ(it->second.count("ut_test_store9"), 1); - ASSERT_EQ(it->second.count("ut_test_store10"), 1); - ASSERT_EQ(it->second.count("ut_test_store-0"), 1); - ASSERT_EQ(it->second.count("ut_test_store-1"), 1); - ASSERT_EQ(it->second.count("ut_test_store-2"), 1); - ASSERT_EQ(it->second.count("ut_test_store-3"), 1); - ASSERT_EQ(it->second.count("ut_test_store-4"), 1); - ASSERT_EQ(it->second.count("ut_test_store-5"), 1); - ASSERT_EQ(it->second.count("ut_test_store-6"), 1); - ASSERT_EQ(it->second.count("ut_test_store-7"), 1); - ASSERT_EQ(it->second.count("ut_test_store-8"), 1); -} -} // namespace OHOS::Test \ No newline at end of file diff --git a/frameworks/innerkitsimpl/kvdb/test/backup_manager_test.cpp b/frameworks/innerkitsimpl/kvdb/test/backup_manager_test.cpp index b8f0ef88b192fb2384122d0a4be39319834f82fd..3315e6e26c1ce8526aaa2aa0fc428eb50c708e90 100644 --- a/frameworks/innerkitsimpl/kvdb/test/backup_manager_test.cpp +++ b/frameworks/innerkitsimpl/kvdb/test/backup_manager_test.cpp @@ -37,8 +37,7 @@ public: Status DeleteBackUpFiles(std::shared_ptr kvStore, std::string baseDir, StoreId storeId); void MkdirPath(std::string baseDir, AppId appId, StoreId storeId); - std::shared_ptr CreateKVStore( - std::string storeIdTest, std::string appIdTest, std::string baseDir, KvStoreType type, bool encrypt); + std::shared_ptr CreateKVStore(std::string storeIdTest, std::string appIdTest, Options options); std::shared_ptr kvStore_; }; @@ -61,10 +60,14 @@ void BackupManagerTest::TearDownTestCase(void) void BackupManagerTest::SetUp(void) { - std::string baseDir = "/data/service/el1/public/database/BackupManagerTest"; - kvStore_ = CreateKVStore("SingleKVStore", "BackupManagerTest", baseDir, SINGLE_VERSION, false); + Options options; + options.kvStoreType = SINGLE_VERSION; + options.baseDir = "/data/service/el1/public/database/BackupManagerTest"; + options.encrypt = false; + options.syncable = false; + kvStore_ = CreateKVStore("SingleKVStore", "BackupManagerTest", options); if (kvStore_ == nullptr) { - kvStore_ = CreateKVStore("SingleKVStore", "BackupManagerTest", baseDir, SINGLE_VERSION, false); + kvStore_ = CreateKVStore("SingleKVStore", "BackupManagerTest", options); } ASSERT_NE(kvStore_, nullptr); } @@ -84,14 +87,15 @@ void BackupManagerTest::TearDown(void) } std::shared_ptr BackupManagerTest::CreateKVStore( - std::string storeIdTest, std::string appIdTest, std::string baseDir, KvStoreType type, bool encrypt) + std::string storeIdTest, std::string appIdTest, Options opt) { Options options; - options.kvStoreType = type; + options.kvStoreType = opt.kvStoreType; options.securityLevel = S1; - options.encrypt = encrypt; + options.encrypt = opt.encrypt; options.area = EL1; - options.baseDir = baseDir; + options.baseDir = opt.baseDir; + options.syncable = opt.syncable; AppId appId = { appIdTest }; StoreId storeId = { storeIdTest }; @@ -208,6 +212,107 @@ HWTEST_F(BackupManagerTest, ReStore, TestSize.Level0) status = kvStore_->Restore("testbackup", baseDir1); ASSERT_EQ(status, INVALID_ARGUMENT); } + +/** + * @tc.name: ReStore001 + * @tc.desc: the kvstore ReStore + * @tc.type: FUNC + */ +HWTEST_F(BackupManagerTest, Restore001, TestSize.Level0) +{ + auto baseDir = "/data/service/el1/public/database/BackupManagerTest"; + AppId appId = { "BackupManagerTest" }; + StoreId storeId = { "RestoreTest001" }; + std::shared_ptr kvStore; + Options options; + options.kvStoreType = SINGLE_VERSION; + options.securityLevel = S1; + options.area = EL1; + options.syncable = false; + options.backup = false; + options.baseDir = baseDir; + Status status; + kvStore = StoreManager::GetInstance().GetKVStore(appId, storeId, options, status); + ASSERT_NE(kvStore, nullptr); + status = kvStore->Restore("testbackup", baseDir); + ASSERT_EQ(status, INVALID_ARGUMENT); +} + +/** + * @tc.name: ReStore002 + * @tc.desc: the kvstore ReStore + * @tc.type: FUNC + */ +HWTEST_F(BackupManagerTest, Restore002, TestSize.Level0) +{ + auto baseDir = "/data/service/el1/public/database/BackupManagerTest"; + AppId appId = { "BackupManagerTest" }; + StoreId storeId = { "RestoreTest002" }; + std::shared_ptr kvStore; + Options options; + options.kvStoreType = SINGLE_VERSION; + options.securityLevel = S1; + options.area = EL1; + options.syncable = true; + options.backup = false; + options.baseDir = baseDir; + Status status; + kvStore = StoreManager::GetInstance().GetKVStore(appId, storeId, options, status); + ASSERT_NE(kvStore, nullptr); + status = kvStore->Restore("testbackup", baseDir); + ASSERT_EQ(status, INVALID_ARGUMENT); +} + +/** + * @tc.name: ReStore003 + * @tc.desc: the kvstore ReStore + * @tc.type: FUNC + */ +HWTEST_F(BackupManagerTest, Restore003, TestSize.Level0) +{ + auto baseDir = "/data/service/el1/public/database/BackupManagerTest"; + AppId appId = { "BackupManagerTest" }; + StoreId storeId = { "RestoreTest003" }; + std::shared_ptr kvStore; + Options options; + options.kvStoreType = SINGLE_VERSION; + options.securityLevel = S1; + options.area = EL1; + options.syncable = false; + options.backup = true; + options.baseDir = baseDir; + Status status; + kvStore = StoreManager::GetInstance().GetKVStore(appId, storeId, options, status); + ASSERT_NE(kvStore, nullptr); + status = kvStore->Restore("testbackup", baseDir); + ASSERT_EQ(status, INVALID_ARGUMENT); +} + +/** + * @tc.name: ReStore004 + * @tc.desc: the kvstore ReStore + * @tc.type: FUNC + */ +HWTEST_F(BackupManagerTest, Restore004, TestSize.Level0) +{ + auto baseDir = "/data/service/el1/public/database/BackupManagerTest"; + AppId appId = { "BackupManagerTest" }; + StoreId storeId = { "RestoreTest004" }; + std::shared_ptr kvStore; + Options options; + options.kvStoreType = SINGLE_VERSION; + options.securityLevel = S1; + options.area = EL1; + options.syncable = true; + options.backup = true; + options.baseDir = baseDir; + Status status; + kvStore = StoreManager::GetInstance().GetKVStore(appId, storeId, options, status); + ASSERT_NE(kvStore, nullptr); + status = kvStore->Restore("testbackup", baseDir); + ASSERT_EQ(status, INVALID_ARGUMENT); +} + /** * @tc.name: DeleteBackup * @tc.desc: the kvstore DeleteBackup @@ -257,7 +362,12 @@ HWTEST_F(BackupManagerTest, RollbackKey, TestSize.Level0) ASSERT_EQ(fl, true); std::shared_ptr kvStoreEncrypt; - kvStoreEncrypt = CreateKVStore(storeId.storeId, appId.appId, baseDir, SINGLE_VERSION, true); + Options options; + options.kvStoreType = SINGLE_VERSION; + options.baseDir = baseDir; + options.encrypt = true; + options.syncable = false; + kvStoreEncrypt = CreateKVStore(storeId.storeId, appId.appId, options); ASSERT_NE(kvStoreEncrypt, nullptr); auto files = StoreUtil::GetFiles(baseDir + "/kvdb/backup/" + storeId.storeId); @@ -298,7 +408,12 @@ HWTEST_F(BackupManagerTest, RollbackData, TestSize.Level0) ASSERT_EQ(fl, true); std::shared_ptr kvStoreEncrypt; - kvStoreEncrypt = CreateKVStore(storeId.storeId, appId.appId, baseDir, SINGLE_VERSION, true); + Options options; + options.kvStoreType = SINGLE_VERSION; + options.baseDir = baseDir; + options.encrypt = true; + options.syncable = false; + kvStoreEncrypt = CreateKVStore(storeId.storeId, appId.appId, options); ASSERT_NE(kvStoreEncrypt, nullptr); auto files = StoreUtil::GetFiles(baseDir + "/kvdb/backup/" + storeId.storeId); @@ -343,7 +458,12 @@ HWTEST_F(BackupManagerTest, Rollback, TestSize.Level0) ASSERT_EQ(fl, true); std::shared_ptr kvStoreEncrypt; - kvStoreEncrypt = CreateKVStore(storeId.storeId, appId.appId, baseDir, SINGLE_VERSION, true); + Options options; + options.kvStoreType = SINGLE_VERSION; + options.baseDir = baseDir; + options.encrypt = true; + options.syncable = false; + kvStoreEncrypt = CreateKVStore(storeId.storeId, appId.appId, options); ASSERT_NE(kvStoreEncrypt, nullptr); auto files = StoreUtil::GetFiles(baseDir + "/kvdb/backup/" + storeId.storeId); @@ -398,7 +518,12 @@ HWTEST_F(BackupManagerTest, CleanTmp, TestSize.Level0) ASSERT_EQ(fl, true); std::shared_ptr kvStoreEncrypt; - kvStoreEncrypt = CreateKVStore(storeId.storeId, appId.appId, baseDir, SINGLE_VERSION, true); + Options options; + options.kvStoreType = SINGLE_VERSION; + options.baseDir = baseDir; + options.encrypt = true; + options.syncable = false; + kvStoreEncrypt = CreateKVStore(storeId.storeId, appId.appId, options); ASSERT_NE(kvStoreEncrypt, nullptr); auto files = StoreUtil::GetFiles(baseDir + "/kvdb/backup/" + storeId.storeId); @@ -441,10 +566,14 @@ HWTEST_F(BackupManagerTest, BackUpEntry, TestSize.Level0) AppId appId = { "BackupManagerTest" }; StoreId storeId = { "SingleKVStoreEncrypt" }; std::string baseDir = "/data/service/el1/public/database/BackupManagerTest"; - - auto kvStoreEncrypt = CreateKVStore(storeId.storeId, "BackupManagerTest", baseDir, SINGLE_VERSION, true); + Options options; + options.kvStoreType = SINGLE_VERSION; + options.baseDir = baseDir; + options.encrypt = true; + options.syncable = true; + auto kvStoreEncrypt = CreateKVStore(storeId.storeId, "BackupManagerTest", options); if (kvStoreEncrypt == nullptr) { - kvStoreEncrypt = CreateKVStore(storeId.storeId, "BackupManagerTest", baseDir, SINGLE_VERSION, true); + kvStoreEncrypt = CreateKVStore(storeId.storeId, "BackupManagerTest", options); } ASSERT_NE(kvStoreEncrypt, nullptr); @@ -488,7 +617,12 @@ HWTEST_F(BackupManagerTest, RestoreEncryptWithKeyFromService, TestSize.Level0) std::string baseDir = "/data/service/el1/public/database/BackupManagerTest"; // put and Backup - auto kvStoreEncrypt = CreateKVStore(storeId.storeId, "BackupManagerTest", baseDir, SINGLE_VERSION, true); + Options options; + options.kvStoreType = SINGLE_VERSION; + options.baseDir = baseDir; + options.encrypt = true; + options.syncable = false; + auto kvStoreEncrypt = CreateKVStore(storeId.storeId, "BackupManagerTest", options); ASSERT_NE(kvStoreEncrypt, nullptr); auto status = kvStoreEncrypt->Put({ "Put Test" }, { "Put Value" }); ASSERT_EQ(status, SUCCESS); diff --git a/frameworks/innerkitsimpl/kvdb/test/dev_manager_mock_test.cpp b/frameworks/innerkitsimpl/kvdb/test/dev_manager_mock_test.cpp index 3936fdca03881769a859c0f3b6d469d909bc5a79..1cf1fb19b9bee8eb1f632dc85222eef39a260a6d 100644 --- a/frameworks/innerkitsimpl/kvdb/test/dev_manager_mock_test.cpp +++ b/frameworks/innerkitsimpl/kvdb/test/dev_manager_mock_test.cpp @@ -14,12 +14,11 @@ */ #define LOG_TAG "DevManagerMockTest" -#include - #include "dev_manager.h" #include "device_manager_mock.h" #include "log_print.h" #include "types.h" +#include namespace OHOS::Test { using namespace testing; using namespace testing::ext; diff --git a/frameworks/innerkitsimpl/kvdb/test/dev_manager_test.cpp b/frameworks/innerkitsimpl/kvdb/test/dev_manager_test.cpp index 7e768322b642aa56485546fb308e59e63c8aa4a9..4214a064095af5f7e921aa8b7ef2aedb3980f526 100644 --- a/frameworks/innerkitsimpl/kvdb/test/dev_manager_test.cpp +++ b/frameworks/innerkitsimpl/kvdb/test/dev_manager_test.cpp @@ -82,7 +82,6 @@ HWTEST_F(DevManagerTest, ToUUID, TestSize.Level1) */ HWTEST_F(DevManagerTest, ToNetworkId, TestSize.Level1) { - ZLOGI("ToNetworkId begin."); auto &devMgr = DevManager::GetInstance(); auto devInfo = devMgr.GetLocalDevice(); EXPECT_NE(devInfo.uuid, ""); diff --git a/frameworks/innerkitsimpl/kvdb/test/kv_hiview_reporter_test.cpp b/frameworks/innerkitsimpl/kvdb/test/kv_hiview_reporter_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5424c2134c93d5678a7e6c3c0df0c27ebcbd27fa --- /dev/null +++ b/frameworks/innerkitsimpl/kvdb/test/kv_hiview_reporter_test.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 "KvHiviewReporterTest" +#include + +#include "include/hisysevent_mock.h" +#include "kv_hiview_reporter.h" +#include "log_print.h" +#include "types.h" +#include + +namespace OHOS::Test { +using namespace testing; +using namespace testing::ext; +using namespace OHOS::DistributedKv; + +static constexpr const char *BASE_DIR = "/data/service/el1/public/database/KvHiviewReporterTest/"; +static constexpr const char *STOREID = "test_storeId"; +static constexpr const char *DB_CORRUPTED_POSTFIX = ".corruptedflg"; + +class KvHiviewReporterTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + + void SetUp(); + void TearDown(); +}; + +void KvHiviewReporterTest::SetUpTestCase(void) +{ + auto ret = mkdir(BASE_DIR, (S_IRWXU)); + if (ret != 0) { + ZLOGE("Mkdir failed, result:%{public}d, path:%{public}s", ret, BASE_DIR); + } +} + +void KvHiviewReporterTest::TearDownTestCase(void) +{ + auto ret = remove(BASE_DIR); + if (ret != 0) { + ZLOGE("Remove failed, result:%{public}d, path:%{public}s", ret, BASE_DIR); + } +} + +void KvHiviewReporterTest::SetUp(void) { } + +void KvHiviewReporterTest::TearDown(void) { } + +/** + * @tc.name: CorruptedFlagTest001 + * @tc.desc: Create and delete corrupted flag + * @tc.type: FUNC + */ +HWTEST_F(KvHiviewReporterTest, CorruptedFlagTest001, TestSize.Level1) +{ + ZLOGI("CorruptedFlagTest001 begin."); + KVDBFaultHiViewReporter::CreateCorruptedFlag(BASE_DIR, STOREID); + std::string flagFilename = std::string(BASE_DIR) + std::string(STOREID) + std::string(DB_CORRUPTED_POSTFIX); + auto ret = access(flagFilename.c_str(), F_OK); + ASSERT_EQ(ret, 0); + KVDBFaultHiViewReporter::DeleteCorruptedFlag(BASE_DIR, STOREID); + ret = access(flagFilename.c_str(), F_OK); + ASSERT_NE(ret, 0); +} + +/** + * @tc.name: ReportKVFaultEvent001 + * @tc.desc: Execute the ReportFaultEvent method + * @tc.type: FUNC + */ +HWTEST_F(KvHiviewReporterTest, ReportKVFaultEvent001, TestSize.Level1) +{ + ZLOGI("ReportKVFaultEvent001 begin."); + HiSysEventMock mock; + EXPECT_CALL(mock, HiSysEvent_Write(_, _, _, _, _, _, _)).Times(1); + ReportInfo reportInfo; + KVDBFaultHiViewReporter::ReportKVFaultEvent(reportInfo); +} +} // namespace OHOS::Test \ No newline at end of file diff --git a/frameworks/innerkitsimpl/kvdb/test/mock/include/hisysevent_mock.h b/frameworks/innerkitsimpl/kvdb/test/mock/include/hisysevent_mock.h new file mode 100644 index 0000000000000000000000000000000000000000..101037a2657f227ff4c525726ef43c4c75dbea7f --- /dev/null +++ b/frameworks/innerkitsimpl/kvdb/test/mock/include/hisysevent_mock.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 HISYSEVENT_MOCK_H +#define HISYSEVENT_MOCK_H + +#include +#include +#include + +#include "hisysevent_c.h" +class HiSysEventMock { +public: + static HiSysEventMock *GetMock() + { + return mock.load(); + } + + HiSysEventMock(); + ~HiSysEventMock(); + + MOCK_METHOD7(HiSysEvent_Write, + int(const char *func, int64_t line, const char *domain, const char *name, HiSysEventEventType type, + const HiSysEventParam params[], size_t size)); + +private: + static inline std::atomic mock = nullptr; +}; + +#endif // HISYSEVENT_MOCK_H diff --git a/frameworks/innerkitsimpl/kvdb/test/mock/src/hisysevent_mock.cpp b/frameworks/innerkitsimpl/kvdb/test/mock/src/hisysevent_mock.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0023df3220fe94f8b606001ce956a18762dca643 --- /dev/null +++ b/frameworks/innerkitsimpl/kvdb/test/mock/src/hisysevent_mock.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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/hisysevent_mock.h" +#include + +HiSysEventMock::HiSysEventMock() +{ + mock.store(this); +} +HiSysEventMock::~HiSysEventMock() +{ + mock.store(nullptr); +} + +int HiSysEvent_Write(const char *func, int64_t line, const char *domain, const char *name, HiSysEventEventType type, + const HiSysEventParam params[], size_t size) +{ + return HiSysEventMock::GetMock()->HiSysEvent_Write(func, line, domain, name, type, params, size); +} diff --git a/frameworks/innerkitsimpl/kvdb/test/mock/src/store_util_mock.cpp b/frameworks/innerkitsimpl/kvdb/test/mock/src/store_util_mock.cpp index 7b457f6bfd24cbe9e787c2762ad6d8f151fd3ab0..9f0ce7c13940769d5d22ac59bf8b5f47b601fe5f 100644 --- a/frameworks/innerkitsimpl/kvdb/test/mock/src/store_util_mock.cpp +++ b/frameworks/innerkitsimpl/kvdb/test/mock/src/store_util_mock.cpp @@ -143,4 +143,9 @@ StoreUtil::DBMode StoreUtil::GetDBMode(SyncMode syncMode) DBMode dbMode = DBMode::SYNC_MODE_PULL_ONLY; return dbMode; } + +bool StoreUtil::SetDatabaseGid(const std::string &path) +{ + return true; +} } // namespace OHOS::DistributedKv \ No newline at end of file diff --git a/frameworks/innerkitsimpl/kvdb/test/security_manager_test.cpp b/frameworks/innerkitsimpl/kvdb/test/security_manager_test.cpp index f3a83838f49b57f058503bb95311001af86b9606..4492ee6f7584c94b164eacec0843bcb98c004b4d 100644 --- a/frameworks/innerkitsimpl/kvdb/test/security_manager_test.cpp +++ b/frameworks/innerkitsimpl/kvdb/test/security_manager_test.cpp @@ -15,9 +15,10 @@ #include "security_manager.h" -#include #include +#include + #include "block_data.h" #include "file_ex.h" #include "hks_api.h" diff --git a/frameworks/innerkitsimpl/kvdb/test/single_store_impl_mock_test.cpp b/frameworks/innerkitsimpl/kvdb/test/single_store_impl_mock_test.cpp index 24629bb10c5de72274b48fe5b2c43e7c162fad4a..a11222011de7778f8b925b9dfab18d0159feab75 100644 --- a/frameworks/innerkitsimpl/kvdb/test/single_store_impl_mock_test.cpp +++ b/frameworks/innerkitsimpl/kvdb/test/single_store_impl_mock_test.cpp @@ -58,7 +58,7 @@ public: static inline shared_ptr taskExecutorMock = nullptr; static inline shared_ptr accessTokenKitMock = nullptr; static inline shared_ptr convertorMock = nullptr; - std::shared_ptr CreateKVStore(bool autosync = false, bool backup = true); + std::shared_ptr CreateKVStore(bool autosync = false, bool backup = true, bool isSyncable = false); }; void SingleStoreImplMockTest::SetUp() { } @@ -107,7 +107,7 @@ void SingleStoreImplMockTest::TearDownTestCase() (void)remove("/data/service/el1/public/database/SingleStoreImplTest"); } -std::shared_ptr SingleStoreImplMockTest::CreateKVStore(bool autosync, bool backup) +std::shared_ptr SingleStoreImplMockTest::CreateKVStore(bool autosync, bool backup, bool isSyncable) { AppId appId = { "SingleStoreImplTest" }; StoreId storeId = { "DestructorTest" }; @@ -119,6 +119,7 @@ std::shared_ptr SingleStoreImplMockTest::CreateKVStore(bool aut options.autoSync = autosync; options.baseDir = "/data/service/el1/public/database/SingleStoreImplTest"; options.backup = backup; + options.syncable = isSyncable; StoreFactory storeFactory; auto dbManager = storeFactory.GetDBManager(options.baseDir, appId); auto dbPassword = SecurityManager::GetInstance().GetDBPassword(storeId.storeId, options.baseDir, options.encrypt); @@ -180,6 +181,7 @@ HWTEST_F(SingleStoreImplMockTest, IsRemoteChanged, testing::ext::TestSize.Level1 EXPECT_CALL(*kVDBNotifierClientMock, IsChanged(_, _)).WillOnce(Return(true)); ret = kvStore->IsRemoteChanged("123456789"); EXPECT_TRUE(ret); + kvStore = CreateKVStore(false, true, true); } catch (...) { EXPECT_TRUE(false); GTEST_LOG_(INFO) << "SingleStoreImplMockTest-an exception occurred by IsRemoteChanged."; @@ -299,7 +301,7 @@ HWTEST_F(SingleStoreImplMockTest, Put_001, testing::ext::TestSize.Level1) try { EXPECT_CALL(*taskExecutorMock, Schedule(_, _, _, _)).Times(1); EXPECT_CALL(*accessTokenKitMock, GetTokenTypeFlag(_)).Times(AnyNumber()); - std::shared_ptr kvStore = CreateKVStore(false, false); + std::shared_ptr kvStore = CreateKVStore(false, false, true); ASSERT_NE(kvStore, nullptr); EXPECT_NE(kvStore->dbStore_, nullptr); std::vector vect; diff --git a/frameworks/innerkitsimpl/kvdb/test/single_store_impl_test.cpp b/frameworks/innerkitsimpl/kvdb/test/single_store_impl_test.cpp index 0cd8a45398bc88570c74226e5011e1176df58c0d..ccd69d7f1d6a6ff0db3d5c51b68147cf817d3199 100644 --- a/frameworks/innerkitsimpl/kvdb/test/single_store_impl_test.cpp +++ b/frameworks/innerkitsimpl/kvdb/test/single_store_impl_test.cpp @@ -1929,7 +1929,7 @@ HWTEST_F(SingleStoreImplTest, DoClientSync001, TestSize.Level1) std::shared_ptr observer; observer = nullptr; auto status = kvStore->DoClientSync(syncInfo, observer); - ASSERT_EQ(status, DB_ERROR); + ASSERT_EQ(status, ERROR); } /** @@ -1987,4 +1987,20 @@ HWTEST_F(SingleStoreImplTest, IsRemoteChanged, TestSize.Level0) bool ret = kvStore->IsRemoteChanged(""); ASSERT_TRUE(ret); } + +/** + * @tc.name: GenerateDbFiles + * @tc.desc: GenerateDbFiles test + * @tc.type: FUNC + */ +HWTEST_F(SingleStoreImplTest, GenerateDbFiles, TestSize.Level0) +{ + std::shared_ptr kvStore; + kvStore = CreateKVStore(true); + ASSERT_NE(kvStore, nullptr); + StoreId storeId = { "SingleKVStore" }; + kvStore->SetAcl(storeId, ""); + auto res = kvStore->GenerateDbFiles(""); + ASSERT_EQ(res.size(), 0); +} } // namespace OHOS::Test \ No newline at end of file diff --git a/frameworks/innerkitsimpl/kvdb/test/store_util_test.cpp b/frameworks/innerkitsimpl/kvdb/test/store_util_test.cpp index a38afed1f02650909cecdc2578871dde83559252..1e7aaf0cd8c7b7f8522651e7742103b6b1b0ae79 100644 --- a/frameworks/innerkitsimpl/kvdb/test/store_util_test.cpp +++ b/frameworks/innerkitsimpl/kvdb/test/store_util_test.cpp @@ -200,4 +200,48 @@ HWTEST_F(StoreUtilTest, CheckPermissions002, TestSize.Level1) remove(fileName.c_str()); rmdir(path.c_str()); } + +/** + * @tc.name: SetDatabaseGid001 + * @tc.desc: Set ACL + * @tc.type: FUNC + */ +HWTEST_F(StoreUtilTest, SetDatabaseGid001, TestSize.Level1) +{ + std::string path = "/data/test/SetDbDirGid001"; + StoreUtil storeUtil_; + storeUtil_.SetDatabaseGid(""); + storeUtil_.SetDatabaseGid(path); + auto ret = mkdir(path.c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)); + struct stat buf; + ret = stat(path.c_str(), &buf); + ASSERT_GE(ret, 0); + ASSERT_TRUE(buf.st_mode & S_IRWXO); + + storeUtil_.SetDatabaseGid(path); + std::string fileName = path + "/test002.db"; + storeUtil_.SetServiceGid(""); + storeUtil_.SetServiceGid(fileName); + auto fp = open(fileName.c_str(), (O_WRONLY | O_CREAT), (S_IRWXU | S_IRWXG | S_IRWXO)); + ASSERT_GE(fp, 0); + close(fp); + ret = stat(fileName.c_str(), &buf); + ASSERT_GE(ret, 0); + ASSERT_TRUE(buf.st_mode & S_IRWXO); + storeUtil_.SetServiceGid(fileName); + + std::string BkfileName = path + "/autoBackup.bak"; + storeUtil_.SetServiceGid(BkfileName); + fp = open(BkfileName.c_str(), (O_WRONLY | O_CREAT), (S_IRWXU | S_IRWXG | S_IRWXO)); + ASSERT_GE(fp, 0); + close(fp); + ret = stat(BkfileName.c_str(), &buf); + ASSERT_GE(ret, 0); + ASSERT_TRUE(buf.st_mode & S_IRWXO); + storeUtil_.SetServiceGid(BkfileName); + + remove(fileName.c_str()); + remove(BkfileName.c_str()); + rmdir(path.c_str()); +} } // namespace OHOS::Test \ No newline at end of file diff --git a/frameworks/jskitsimpl/distributeddata/include/js_const_properties.h b/frameworks/jskitsimpl/distributeddata/include/js_const_properties.h index 367261d9554d2469f64780a95f92e22b54bed03b..6d42a1d1dcc809fff7d48c934f4e182cbda3b8b0 100644 --- a/frameworks/jskitsimpl/distributeddata/include/js_const_properties.h +++ b/frameworks/jskitsimpl/distributeddata/include/js_const_properties.h @@ -24,4 +24,4 @@ namespace OHOS::DistributedData { napi_status InitConstProperties(napi_env env, napi_value exports); } // namespace OHOS::DistributedData -#endif // OHOS_JS_CONST_PROPERTIES_H +#endif // OHOS_JS_CONST_PROPERTIES_H \ No newline at end of file diff --git a/frameworks/jskitsimpl/distributeddata/include/js_kv_store_resultset.h b/frameworks/jskitsimpl/distributeddata/include/js_kv_store_resultset.h index 5c20d5ea4a80ed4a9c5f7e229ca9e2bc0b15b8bf..1ad20722042d7ef4137838e1c355f807c362e139 100644 --- a/frameworks/jskitsimpl/distributeddata/include/js_kv_store_resultset.h +++ b/frameworks/jskitsimpl/distributeddata/include/js_kv_store_resultset.h @@ -14,19 +14,18 @@ */ #ifndef OHOS_KV_STORE_RESELTSET_H #define OHOS_KV_STORE_RESELTSET_H +#include "js_proxy.h" +#include "kvstore_result_set.h" #include "napi_queue.h" #include "result_set_bridge.h" -#include "kvstore_result_set.h" namespace OHOS::DistributedData { -class JsKVStoreResultSet : public DataShare::ResultSetBridge::Creator { +class JsKVStoreResultSet : public JSProxy::JSEntity { public: JsKVStoreResultSet() = default; virtual ~JsKVStoreResultSet() = default; - void SetNative(std::shared_ptr& resultSet); void SetSchema(bool isSchema); - std::shared_ptr& GetNative(); static napi_value Constructor(napi_env env); static napi_value New(napi_env env, napi_callback_info info); @@ -48,7 +47,6 @@ private: static napi_value IsAfterLast(napi_env env, napi_callback_info info); static napi_value GetEntry(napi_env env, napi_callback_info info); - std::shared_ptr resultSet_ = nullptr; bool isSchema_ = false; }; } // namespace OHOS::DistributedData diff --git a/frameworks/jskitsimpl/distributeddata/include/js_schema.h b/frameworks/jskitsimpl/distributeddata/include/js_schema.h index 615b43cb98b63a7255b3e8067a66c91c21d26922..a42b63318a318bc54d5037a7c06135f4d2303c20 100644 --- a/frameworks/jskitsimpl/distributeddata/include/js_schema.h +++ b/frameworks/jskitsimpl/distributeddata/include/js_schema.h @@ -29,7 +29,7 @@ public: static napi_value Constructor(napi_env env); static napi_value New(napi_env env, napi_callback_info info); - + static napi_status ToJson(napi_env env, napi_value inner, JsSchema*& out); std::string Dump(); private: diff --git a/frameworks/jskitsimpl/distributeddata/include/js_util.h b/frameworks/jskitsimpl/distributeddata/include/js_util.h index d9ebeeadb4ea19bbae64b1685161ea3fb13f82e9..722419602f802c57f23f629c9c58c738fbac73b0 100644 --- a/frameworks/jskitsimpl/distributeddata/include/js_util.h +++ b/frameworks/jskitsimpl/distributeddata/include/js_util.h @@ -92,7 +92,7 @@ public: static napi_status SetValue(napi_env env, const QueryVariant& in, napi_value& out); /* napi_value <-> std::vector */ - static napi_status GetValue(napi_env env, napi_value in, std::vector& out); + static napi_status GetValue(napi_env env, napi_value in, std::vector& out, bool checkLength = true); static napi_status SetValue(napi_env env, const std::vector& in, napi_value& out); /* napi_value <-> std::vector */ @@ -178,6 +178,7 @@ public: static bool IsNull(napi_env env, napi_value value); + static std::string Anonymous(const std::string &name); private: enum { /* std::map to js::tuple */ diff --git a/frameworks/jskitsimpl/distributeddata/include/uv_queue.h b/frameworks/jskitsimpl/distributeddata/include/uv_queue.h index b5b96ea7426f6ec2b288995d88cf193c902c4638..88759682c3ad2579273bf758e3fb7077c3c48713 100644 --- a/frameworks/jskitsimpl/distributeddata/include/uv_queue.h +++ b/frameworks/jskitsimpl/distributeddata/include/uv_queue.h @@ -31,13 +31,7 @@ public: napi_env GetEnv(); void AsyncCall(NapiCallbackGetter getter, NapiArgsGenerator genArgs = NapiArgsGenerator()); private: - struct UvEntry { - napi_env env; - NapiCallbackGetter callback; - NapiArgsGenerator args; - }; napi_env env_ = nullptr; - uv_loop_s* loop_ = nullptr; }; } // namespace OHOS::DistributedData #endif // OHOS_UV_QUEUE_H diff --git a/frameworks/jskitsimpl/distributeddata/src/entry_point.cpp b/frameworks/jskitsimpl/distributeddata/src/entry_point.cpp index d3f105d41207b0240099f4f9ae08b5960c9e7f1d..25c12dd601f1126d22162e72cf64425bf3abdc51 100644 --- a/frameworks/jskitsimpl/distributeddata/src/entry_point.cpp +++ b/frameworks/jskitsimpl/distributeddata/src/entry_point.cpp @@ -29,19 +29,19 @@ static napi_value Init(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("createKVManager", JsKVManager::CreateKVManager) }; napi_status status = napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); - ZLOGI("init createKVManager %{public}d", status); + ZLOGI("Init createKVManager %{public}d", status); status = napi_set_named_property(env, exports, "FieldNode", JsFieldNode::Constructor(env)); - ZLOGI("init FieldNode %{public}d", status); + ZLOGI("Init FieldNode %{public}d", status); status = napi_set_named_property(env, exports, "Schema", JsSchema::Constructor(env)); - ZLOGI("init Schema %{public}d", status); + ZLOGI("Init Schema %{public}d", status); status = napi_set_named_property(env, exports, "Query", JsQuery::Constructor(env)); - ZLOGI("init Query %{public}d", status); + ZLOGI("Init Query %{public}d", status); status = InitConstProperties(env, exports); - ZLOGI("init Enumerate Constants %{public}d", status); + ZLOGI("Init Enumerate Constants %{public}d", status); return exports; } @@ -55,5 +55,5 @@ static __attribute__((constructor)) void RegisterModule() .nm_priv = ((void*)0), .reserved = { 0 } }; napi_module_register(&module); - ZLOGI("module register data.distributedData"); + ZLOGI("Module register data.distributedData"); } diff --git a/frameworks/jskitsimpl/distributeddata/src/js_device_kv_store.cpp b/frameworks/jskitsimpl/distributeddata/src/js_device_kv_store.cpp index 4d6efe75fa0192204a1c6d00e6be4945612af3d8..c89bdff66d8d4a174809e19fb2db75a73b023eca 100644 --- a/frameworks/jskitsimpl/distributeddata/src/js_device_kv_store.cpp +++ b/frameworks/jskitsimpl/distributeddata/src/js_device_kv_store.cpp @@ -14,6 +14,7 @@ */ #define LOG_TAG "JsDeviceKVStore" #include "js_device_kv_store.h" + #include #include "js_kv_store_resultset.h" #include "js_query.h" @@ -100,7 +101,7 @@ napi_value JsDeviceKVStore::Get(napi_env env, napi_callback_info info) OHOS::DistributedKv::Value value; auto& kvStore = reinterpret_cast(ctxt->native)->GetNative(); if (kvStore == nullptr) { - ZLOGE("kvStore is nullptr"); + ZLOGE("This kvStore is nullptr"); return; } bool isSchemaStore = reinterpret_cast(ctxt->native)->IsSchemaStore(); @@ -285,7 +286,7 @@ napi_value JsDeviceKVStore::GetResultSet(napi_env env, napi_callback_info info) }; ctxt->status = (status == Status::SUCCESS) ? napi_ok : napi_generic_failure; CHECK_STATUS_RETURN_VOID(ctxt, "kvStore->GetResultSet() failed!"); - ctxt->resultSet->SetNative(kvResultSet); + ctxt->resultSet->SetInstance(kvResultSet); bool isSchema = reinterpret_cast(ctxt->native)->IsSchemaStore(); ctxt->resultSet->SetSchema(isSchema); }; @@ -323,7 +324,9 @@ napi_value JsDeviceKVStore::CloseResultSet(napi_env env, napi_callback_info info auto execute = [ctxt]() { auto& kvStore = reinterpret_cast(ctxt->native)->GetNative(); - Status status = kvStore->CloseResultSet(ctxt->resultSet->GetNative()); + auto resultSet = ctxt->resultSet->GetInstance(); + ctxt->resultSet->SetInstance(nullptr); + Status status = kvStore->CloseResultSet(resultSet); ZLOGD("kvStore->CloseResultSet return %{public}d", status); ctxt->status = (status == Status::SUCCESS) ? napi_ok : napi_generic_failure; CHECK_STATUS_RETURN_VOID(ctxt, "kvStore->CloseResultSet failed!"); @@ -390,7 +393,7 @@ napi_value JsDeviceKVStore::RemoveDeviceData(napi_env env, napi_callback_info in CHECK_ARGS_RETURN_VOID(ctxt, argc == 1, "invalid arguments!"); ctxt->status = JSUtil::GetValue(env, argv[0], ctxt->deviceId); if (ctxt->deviceId.empty()) { - ZLOGE("deviceId is empty"); + ZLOGE("This deviceId is empty"); ctxt->status = napi_generic_failure; return; } diff --git a/frameworks/jskitsimpl/distributeddata/src/js_field_node.cpp b/frameworks/jskitsimpl/distributeddata/src/js_field_node.cpp index aa4cb77ee70c6818da904cf8a78c430b72d8d6eb..84ec92ea78cbf41eb9256723a6b7a31c98ca30b4 100644 --- a/frameworks/jskitsimpl/distributeddata/src/js_field_node.cpp +++ b/frameworks/jskitsimpl/distributeddata/src/js_field_node.cpp @@ -32,9 +32,9 @@ static std::string CHILDREN = "CHILDREN"; std::map JsFieldNode::valueTypeToString_ = { { JSUtil::STRING, std::string("STRING") }, { JSUtil::INTEGER, std::string("INTEGER") }, - { JSUtil::FLOAT, std::string("FLOAT") }, + { JSUtil::FLOAT, std::string("DOUBLE") }, { JSUtil::BYTE_ARRAY, std::string("BYTE_ARRAY") }, - { JSUtil::BOOLEAN, std::string("BOOLEAN") }, + { JSUtil::BOOLEAN, std::string("BOOL") }, { JSUtil::DOUBLE, std::string("DOUBLE") } }; @@ -51,7 +51,12 @@ std::string JsFieldNode::GetFieldName() JsFieldNode::json JsFieldNode::GetValueForJson() { if (fields_.empty()) { - return ToString(valueType_) + "," + (isNullable_ ? "NULL" : "NOT NULL"); + if (valueType_ == JSUtil::STRING) { + return ToString(valueType_) + ToString(isNullable_ ? "," : ", NOT NULL,") + + " DEFAULT '" + ToString(defaultValue_) + "'"; + } + return ToString(valueType_) + ToString(isNullable_ ? "," : ", NOT NULL,") + + " DEFAULT " + ToString(defaultValue_); } json jsFields; diff --git a/frameworks/jskitsimpl/distributeddata/src/js_kv_manager.cpp b/frameworks/jskitsimpl/distributeddata/src/js_kv_manager.cpp index 665f48f23cfca664432be2dc34e8507dcaa31cd2..a01d3e5f6d8a0de9af80d3c9ccbee1e53fa8c939 100644 --- a/frameworks/jskitsimpl/distributeddata/src/js_kv_manager.cpp +++ b/frameworks/jskitsimpl/distributeddata/src/js_kv_manager.cpp @@ -134,7 +134,8 @@ 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; - ZLOGD("Options area:%{public}d dir:%{public}s", ctxt->options.area, ctxt->options.baseDir.c_str()); + ZLOGD("Options area:%{public}d dir:%{public}s", ctxt->options.area, + JSUtil::Anonymous(ctxt->options.baseDir).c_str()); std::shared_ptr kvStore; Status status = kvm->kvDataManager_.GetSingleKvStore(ctxt->options, appId, storeId, kvStore); if (status == CRYPT_ERROR) { @@ -231,7 +232,7 @@ napi_value JsKVManager::DeleteKVStore(napi_env env, napi_callback_info info) auto kvm = reinterpret_cast(ctxt->native); CHECK_ARGS_RETURN_VOID(ctxt, kvm != nullptr, "KVManager is null, failed!"); std::string databaseDir = kvm->param_->baseDir; - ZLOGD("DeleteKVStore databaseDir is: %{public}s", databaseDir.c_str()); + ZLOGD("DeleteKVStore databaseDir is: %{public}s", JSUtil::Anonymous(databaseDir).c_str()); Status status = kvm->kvDataManager_.DeleteKvStore(appId, storeId, databaseDir); ZLOGD("DeleteKvStore status:%{public}d", status); ctxt->status = (status == Status::SUCCESS) ? napi_ok : napi_generic_failure; diff --git a/frameworks/jskitsimpl/distributeddata/src/js_kv_store.cpp b/frameworks/jskitsimpl/distributeddata/src/js_kv_store.cpp index e6b173ecc9206023cec8b8636f06d1e1e904b2bb..d9d8d2d6e2fadff1ca95bbc78639dc6e69cfb18f 100644 --- a/frameworks/jskitsimpl/distributeddata/src/js_kv_store.cpp +++ b/frameworks/jskitsimpl/distributeddata/src/js_kv_store.cpp @@ -19,15 +19,13 @@ #include "log_print.h" #include "napi_queue.h" #include "datashare_values_bucket.h" -#include "datashare_predicates.h" #include "single_kvstore.h" #include "kv_utils.h" -#include "kvstore_datashare_bridge.h" using namespace OHOS::DistributedKv; -using namespace OHOS::DataShare; namespace OHOS::DistributedData { +inline static uint8_t UNVALID_SUBSCRIBE_TYPE = 255; std::map JsKVStore::onEventHandlers_ = { { "dataChange", JsKVStore::OnDataChange }, { "syncComplete", JsKVStore::OnSyncComplete } @@ -45,7 +43,16 @@ static bool ValidSubscribeType(uint8_t type) static SubscribeType ToSubscribeType(uint8_t type) { - return static_cast(type + 1); + switch (type) { + case 0: // 0 means SUBSCRIBE_TYPE_LOCAL + return SubscribeType::SUBSCRIBE_TYPE_LOCAL; + case 1: // 1 means SUBSCRIBE_TYPE_REMOTE + return SubscribeType::SUBSCRIBE_TYPE_REMOTE; + case 2: // 2 means SUBSCRIBE_TYPE_ALL + return SubscribeType::SUBSCRIBE_TYPE_ALL; + default: + return static_cast(UNVALID_SUBSCRIBE_TYPE); + } } JsKVStore::JsKVStore(const std::string& storeId) @@ -160,7 +167,7 @@ napi_value JsKVStore::Delete(napi_env env, napi_callback_info info) ctxt->GetCbInfo(env, info, [env, ctxt](size_t argc, napi_value* argv) { // required 1 arguments :: - CHECK_ARGS_RETURN_VOID(ctxt, argc == 1, "invalid arguments!"); + CHECK_ARGS_RETURN_VOID(ctxt, argc == 1, "invalid arguments!"); ctxt->status = JSUtil::GetValue(env, argv[0], ctxt->key); ZLOGD("kvStore->Delete %{public}.6s status:%{public}d", ctxt->key.c_str(), ctxt->status); CHECK_STATUS_RETURN_VOID(ctxt, "invalid arg[0], i.e. invalid key!"); @@ -554,6 +561,7 @@ void JsKVStore::OffSyncComplete(napi_env env, size_t argc, napi_value* argv, std proxy->syncObservers_.erase(it); break; } + ++it; } ctxt->status = napi_ok; } diff --git a/frameworks/jskitsimpl/distributeddata/src/js_kv_store_resultset.cpp b/frameworks/jskitsimpl/distributeddata/src/js_kv_store_resultset.cpp index 57202fc14b73dd101b37362895d06e86de7ba5f9..e6b91446c0cda8591dff000be6236c1a9c11cc2d 100644 --- a/frameworks/jskitsimpl/distributeddata/src/js_kv_store_resultset.cpp +++ b/frameworks/jskitsimpl/distributeddata/src/js_kv_store_resultset.cpp @@ -17,22 +17,11 @@ #include "js_util.h" #include "log_print.h" #include "napi_queue.h" -#include "uv_queue.h" -#include "kvstore_datashare_bridge.h" #include "kv_utils.h" using namespace OHOS::DistributedKv; using namespace OHOS::DataShare; namespace OHOS::DistributedData { -void JsKVStoreResultSet::SetNative(std::shared_ptr& resultSet) -{ - resultSet_ = resultSet; -} - -std::shared_ptr& JsKVStoreResultSet::GetNative() -{ - return resultSet_; -} napi_value JsKVStoreResultSet::Constructor(napi_env env) { @@ -83,7 +72,8 @@ napi_value JsKVStoreResultSet::GetCount(napi_env env, napi_callback_info info) / NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); ZLOGD("KVStoreResultSet::GetCount(status=%{public}d)", ctxt->status); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); int count = resultSet->GetCount(); napi_create_int32(env, count, &ctxt->output); @@ -97,7 +87,8 @@ napi_value JsKVStoreResultSet::GetPosition(napi_env env, napi_callback_info info ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); int position = resultSet->GetPosition(); napi_create_int32(env, position, &ctxt->output); @@ -111,7 +102,8 @@ napi_value JsKVStoreResultSet::MoveToFirst(napi_env env, napi_callback_info info ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isMoved = resultSet->MoveToFirst(); napi_get_boolean(env, isMoved, &ctxt->output); @@ -125,7 +117,8 @@ napi_value JsKVStoreResultSet::MoveToLast(napi_env env, napi_callback_info info) ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isMoved = resultSet->MoveToLast(); napi_get_boolean(env, isMoved, &ctxt->output); @@ -139,7 +132,8 @@ napi_value JsKVStoreResultSet::MoveToNext(napi_env env, napi_callback_info info) ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isMoved = resultSet->MoveToNext(); napi_get_boolean(env, isMoved, &ctxt->output); @@ -153,7 +147,8 @@ napi_value JsKVStoreResultSet::MoveToPrevious(napi_env env, napi_callback_info i ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isMoved = resultSet->MoveToPrevious(); napi_get_boolean(env, isMoved, &ctxt->output); @@ -173,7 +168,8 @@ napi_value JsKVStoreResultSet::Move(napi_env env, napi_callback_info info) /* bo ctxt->GetCbInfoSync(env, info, input); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isMoved = resultSet->Move(offset); napi_get_boolean(env, isMoved, &ctxt->output); @@ -193,7 +189,8 @@ napi_value JsKVStoreResultSet::MoveToPosition(napi_env env, napi_callback_info i NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); ZLOGD("KVStoreResultSet::MoveToPosition(%{public}d)", position); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isMoved = resultSet->MoveToPosition(position); napi_get_boolean(env, isMoved, &ctxt->output); @@ -207,7 +204,8 @@ napi_value JsKVStoreResultSet::IsFirst(napi_env env, napi_callback_info info) /* ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isFirst = resultSet->IsFirst(); napi_get_boolean(env, isFirst, &ctxt->output); @@ -221,7 +219,8 @@ napi_value JsKVStoreResultSet::IsLast(napi_env env, napi_callback_info info) /* ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isLast = resultSet->IsLast(); napi_get_boolean(env, isLast, &ctxt->output); @@ -235,7 +234,8 @@ napi_value JsKVStoreResultSet::IsBeforeFirst(napi_env env, napi_callback_info in ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isBeforeFirst = resultSet->IsBeforeFirst(); napi_get_boolean(env, isBeforeFirst, &ctxt->output); @@ -249,7 +249,8 @@ napi_value JsKVStoreResultSet::IsAfterLast(napi_env env, napi_callback_info info ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isAfterLast = resultSet->IsAfterLast(); napi_get_boolean(env, isAfterLast, &ctxt->output); @@ -264,7 +265,8 @@ napi_value JsKVStoreResultSet::GetEntry(napi_env env, napi_callback_info info) / NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); DistributedKv::Entry entry; - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isSchema = reinterpret_cast(ctxt->native)->isSchema_; auto status = resultSet->GetEntry(entry); if (status != Status::SUCCESS) { @@ -278,7 +280,13 @@ napi_value JsKVStoreResultSet::GetEntry(napi_env env, napi_callback_info info) / std::shared_ptr JsKVStoreResultSet::Create() { - return KvUtils::ToResultSetBridge(resultSet_); + auto instance = GetInstance(); + if (instance == nullptr) { + ZLOGE("resultSet is null"); + return nullptr; + } + SetInstance(nullptr); + return KvUtils::ToResultSetBridge(instance); } void JsKVStoreResultSet::SetSchema(bool isSchema) diff --git a/frameworks/jskitsimpl/distributeddata/src/js_schema.cpp b/frameworks/jskitsimpl/distributeddata/src/js_schema.cpp index 1de32338ea7a4f868fedf05a921a68036d5f7ed7..adb17fa8bb0e84fbae199a8133884d82ada81a64 100644 --- a/frameworks/jskitsimpl/distributeddata/src/js_schema.cpp +++ b/frameworks/jskitsimpl/distributeddata/src/js_schema.cpp @@ -213,7 +213,7 @@ napi_value JsSchema::SetIndexes(napi_env env, napi_callback_info info) auto input = [env, ctxt, &indexes](size_t argc, napi_value* argv) { // required 1 arguments :: CHECK_ARGS_RETURN_VOID(ctxt, argc == 1, "invalid arguments!"); - ctxt->status = JSUtil::GetValue(env, argv[0], indexes); + ctxt->status = JSUtil::GetValue(env, argv[0], indexes, false); CHECK_STATUS_RETURN_VOID(ctxt, "invalid arg[0], i.e. invalid indexes!"); }; ctxt->GetCbInfoSync(env, info, input); diff --git a/frameworks/jskitsimpl/distributeddata/src/js_single_kv_store.cpp b/frameworks/jskitsimpl/distributeddata/src/js_single_kv_store.cpp index b03e2a2d2ea471edf5ec33a99a5081bf61d702f0..71f5f667cfb5423eef5d0e46047e5e8d42bf2e49 100644 --- a/frameworks/jskitsimpl/distributeddata/src/js_single_kv_store.cpp +++ b/frameworks/jskitsimpl/distributeddata/src/js_single_kv_store.cpp @@ -16,7 +16,6 @@ #include "js_single_kv_store.h" #include "js_util.h" #include "js_kv_store_resultset.h" -#include "datashare_predicates.h" #include "js_query.h" #include "log_print.h" #include "napi_queue.h" @@ -24,7 +23,6 @@ #include "kv_utils.h" using namespace OHOS::DistributedKv; -using namespace OHOS::DataShare; namespace OHOS::DistributedData { JsSingleKVStore::JsSingleKVStore(const std::string& storeId) : JsKVStore(storeId) @@ -235,7 +233,7 @@ napi_value JsSingleKVStore::GetResultSet(napi_env env, napi_callback_info info) ctxt->status = (status == Status::SUCCESS) ? napi_ok : napi_generic_failure; CHECK_STATUS_RETURN_VOID(ctxt, "kvStore->GetResultSet() failed!"); - ctxt->resultSet->SetNative(kvResultSet); + ctxt->resultSet->SetInstance(kvResultSet); bool isSchema = reinterpret_cast(ctxt->native)->IsSchemaStore(); ctxt->resultSet->SetSchema(isSchema); }; @@ -273,7 +271,9 @@ napi_value JsSingleKVStore::CloseResultSet(napi_env env, napi_callback_info info auto execute = [ctxt]() { auto& kvStore = reinterpret_cast(ctxt->native)->GetNative(); - Status status = kvStore->CloseResultSet(ctxt->resultSet->GetNative()); + auto resultSet = ctxt->resultSet->GetInstance(); + ctxt->resultSet->SetInstance(nullptr); + Status status = kvStore->CloseResultSet(resultSet); ZLOGD("kvStore->CloseResultSet return %{public}d", status); ctxt->status = (status == Status::SUCCESS) ? napi_ok : napi_generic_failure; CHECK_STATUS_RETURN_VOID(ctxt, "kvStore->CloseResultSet failed!"); diff --git a/frameworks/jskitsimpl/distributeddata/src/js_util.cpp b/frameworks/jskitsimpl/distributeddata/src/js_util.cpp index 7d8debfb78b88ca851cc72a6f25c7c9e9fcf996f..1d220ab4f8d7a631e368a61072119e8fab33e3eb 100644 --- a/frameworks/jskitsimpl/distributeddata/src/js_util.cpp +++ b/frameworks/jskitsimpl/distributeddata/src/js_util.cpp @@ -30,6 +30,11 @@ using namespace OHOS::DataShare; namespace OHOS::DistributedData { constexpr int32_t STR_MAX_LENGTH = 4096; constexpr size_t STR_TAIL_LENGTH = 1; +static constexpr int32_t HEAD_SIZE = 3; +static constexpr int32_t END_SIZE = 3; +static constexpr int32_t MIN_SIZE = 9; +static constexpr const char *REPLACE_CHAIN = "***"; +static constexpr const char *DEFAULT_ANONYMOUS = "******"; struct PredicatesProxy { std::shared_ptr predicates_; }; @@ -135,7 +140,7 @@ napi_status JSUtil::SetValue(napi_env env, const std::string& in, napi_value& ou } /* napi_value <-> std::vector */ -napi_status JSUtil::GetValue(napi_env env, napi_value in, std::vector& out) +napi_status JSUtil::GetValue(napi_env env, napi_value in, std::vector& out, bool checkLength) { ZLOGD("napi_value -> std::vector"); out.clear(); @@ -145,7 +150,10 @@ napi_status JSUtil::GetValue(napi_env env, napi_value in, std::vector 0), "get_array failed!", napi_invalid_arg); + CHECK_RETURN(status == napi_ok, "get_array length failed!", napi_invalid_arg); + if (checkLength) { + CHECK_RETURN(length > 0, "check array length failed!", napi_invalid_arg); + } for (uint32_t i = 0; i < length; ++i) { napi_value item = nullptr; status = napi_get_element(env, in, i, &item); @@ -197,7 +205,7 @@ JSUtil::KvStoreVariant JSUtil::Blob2VariantValue(const DistributedKv::Blob& blob } else if (data[0] == JSUtil::DOUBLE) { uint64_t tmp = be64toh(*reinterpret_cast(&(real[0]))); return JSUtil::KvStoreVariant(*reinterpret_cast((void*)(&tmp))); - } else if (data[0] == JSUtil::STRING){ + } else if (data[0] == JSUtil::STRING) { return JSUtil::KvStoreVariant(std::string(real.begin(), real.end())); } else { // for schema-db, if (data[0] == JSUtil::STRING), no beginning byte! @@ -937,6 +945,7 @@ napi_status JSUtil::GetValue(napi_env env, napi_value in, DistributedKv::Options CHECK_RETURN(status == napi_ok, "get encrypt param failed", napi_invalid_arg); status = GetNamedProperty(env, in, "backup", options.backup, true); CHECK_RETURN(status == napi_ok, "get backup param failed", napi_invalid_arg); + options.autoSync = false; status = GetNamedProperty(env, in, "autoSync", options.autoSync, true); CHECK_RETURN(status == napi_ok, "get autoSync param failed", napi_invalid_arg); @@ -1113,7 +1122,7 @@ napi_status JSUtil::GetCurrentAbilityParam(napi_env env, ContextParam ¶m) param.hapName = hapInfo->moduleName; } ZLOGI("area:%{public}d hapName:%{public}s baseDir:%{public}s", param.area, param.hapName.c_str(), - param.baseDir.c_str()); + Anonymous(param.baseDir).c_str()); return napi_ok; } @@ -1168,4 +1177,17 @@ std::pair JSUtil::GetInnerValue( } return std::make_pair(napi_ok, inner); } + +std::string JSUtil::Anonymous(const std::string &name) +{ + if (name.length() <= HEAD_SIZE) { + return DEFAULT_ANONYMOUS; + } + + if (name.length() < MIN_SIZE) { + return (name.substr(0, HEAD_SIZE) + REPLACE_CHAIN); + } + + return (name.substr(0, HEAD_SIZE) + REPLACE_CHAIN + name.substr(name.length() - END_SIZE, END_SIZE)); +} } // namespace OHOS::DistributedData diff --git a/frameworks/jskitsimpl/distributeddata/src/napi_queue.cpp b/frameworks/jskitsimpl/distributeddata/src/napi_queue.cpp index 53d07bd79c3f2ecc80f11551762dfffc643c3d13..5c4e5102f3bbfb006d18687361d8cdf146479fac 100644 --- a/frameworks/jskitsimpl/distributeddata/src/napi_queue.cpp +++ b/frameworks/jskitsimpl/distributeddata/src/napi_queue.cpp @@ -20,7 +20,7 @@ using namespace OHOS::DistributedKv; namespace OHOS::DistributedData { ContextBase::~ContextBase() { - ZLOGD("no memory leak after callback or promise[resolved/rejected]"); + ZLOGD("No memory leak after callback or promise[resolved/rejected]"); if (env != nullptr) { if (callbackRef != nullptr) { auto status = napi_delete_reference(env, callbackRef); @@ -58,9 +58,9 @@ void ContextBase::GetCbInfo(napi_env envi, napi_callback_info info, NapiCbInfoPa status = napi_create_reference(env, argv[index], 1, &callbackRef); CHECK_STATUS_RETURN_VOID(this, "ref callback failed!"); argc = index; - ZLOGD("async callback, no promise"); + ZLOGD("Async callback, no promise"); } else { - ZLOGD("no callback, async pormose"); + ZLOGD("No callback, async pormose"); } } @@ -82,17 +82,18 @@ 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); - ZLOGD("create deferred promise"); + if (napi_create_promise(env, &aCtx->deferred, &promise) != napi_ok) { + ZLOGE("Create deferred promise fail"); + delete aCtx; + return nullptr; + } } else { napi_get_undefined(env, &promise); } napi_value resource = nullptr; napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &resource); - napi_create_async_work( - env, nullptr, resource, - [](napi_env env, void* data) { + napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) { CHECK_RETURN_VOID(data != nullptr, "napi_async_execute_callback nullptr"); auto actx = reinterpret_cast(data); ZLOGD("napi_async_execute_callback ctxt->status=%{public}d", actx->ctx->status); @@ -115,9 +116,10 @@ napi_value NapiQueue::AsyncWork(napi_env env, std::shared_ptr ctxt, delete actx; }, reinterpret_cast(aCtx), &aCtx->work); - auto status = napi_queue_async_work(env, aCtx->work); + auto status = napi_queue_async_work_with_qos(env, aCtx->work, napi_qos_user_initiated); if (status != napi_ok) { napi_get_undefined(env, &promise); + napi_reject_deferred(env, aCtx->deferred, promise); delete aCtx; } return promise; @@ -150,8 +152,8 @@ void NapiQueue::GenerateOutput(AsyncContext &ctx, napi_value output) napi_value callback = nullptr; napi_get_reference_value(ctx.env, ctx.ctx->callbackRef, &callback); napi_value callbackResult = nullptr; - ZLOGD("call callback function"); + ZLOGD("Call callback function"); napi_call_function(ctx.env, nullptr, callback, RESULT_ALL, result, &callbackResult); } } -} // namespace OHOS::DistributedData +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/frameworks/jskitsimpl/distributeddata/src/uv_queue.cpp b/frameworks/jskitsimpl/distributeddata/src/uv_queue.cpp index a54641eff80b4cd8e007123def36d78489526a95..7a5480f2b56b82ae7fd4a0f17a915af35053a556 100644 --- a/frameworks/jskitsimpl/distributeddata/src/uv_queue.cpp +++ b/frameworks/jskitsimpl/distributeddata/src/uv_queue.cpp @@ -14,77 +14,68 @@ */ #define LOG_TAG "UvQueue" -#include "uv_queue.h" #include "log_print.h" #include "napi_queue.h" +#include "uv_queue.h" namespace OHOS::DistributedData { UvQueue::UvQueue(napi_env env) : env_(env) { - if (env != nullptr) { - napi_get_uv_event_loop(env, &loop_); - } } UvQueue::~UvQueue() { - ZLOGD("no memory leak for queue-callback"); + ZLOGD("No memory leak for queue-callback"); env_ = nullptr; } void UvQueue::AsyncCall(NapiCallbackGetter getter, NapiArgsGenerator genArgs) { - if (loop_ == nullptr || !getter) { - ZLOGE("loop_ or callback is nullptr"); + if (!getter) { + ZLOGE("This callback is nullptr"); return; } - - uv_work_t* work = new (std::nothrow) uv_work_t; - if (work == nullptr) { - ZLOGE("no memory for uv_work_t"); - return; + auto task = [env = env_, getter, genArgs]() { + napi_handle_scope scope = nullptr; + napi_open_handle_scope(env, &scope); + if (scope == nullptr) { + return; + } + napi_value method = getter(env); + if (method == nullptr) { + ZLOGE("The callback is invalid, maybe is cleared!"); + napi_close_handle_scope(env, scope); + return; + } + int argc = 0; + napi_value argv[ARGC_MAX] = { nullptr }; + if (genArgs) { + argc = ARGC_MAX; + genArgs(env, argc, argv); + } + napi_value global = nullptr; + napi_status status = napi_get_global(env, &global); + if (status != napi_ok) { + ZLOGE("Get napi global failed. status: %{public}d.", status); + napi_close_handle_scope(env, scope); + return; + } + napi_value result; + status = napi_call_function(env, global, method, argc, argv, &result); + if (status != napi_ok) { + ZLOGE("Notify data change failed. status:%{public}d.", status); + } + napi_close_handle_scope(env, scope); + }; + napi_status status = napi_send_event(env_, task, napi_eprio_immediate); + if (status != napi_ok) { + ZLOGE("Failed to napi_send_event. status:%{public}d", status); } - work->data = new UvEntry{ env_, getter, std::move(genArgs) }; - uv_queue_work( - loop_, work, [](uv_work_t* work) {}, - [](uv_work_t* work, int uvstatus) { - std::shared_ptr entry(static_cast(work->data), [work](UvEntry *data) { - delete data; - delete work; - }); - napi_handle_scope scope = nullptr; - napi_open_handle_scope(entry->env, &scope); - napi_value method = entry->callback(entry->env); - if (method == nullptr) { - ZLOGE("the callback is invalid, maybe is cleared!"); - if (scope != nullptr) { - napi_close_handle_scope(entry->env, scope); - } - return ; - } - int argc = 0; - napi_value argv[ARGC_MAX] = { nullptr }; - if (entry->args) { - argc = ARGC_MAX; - entry->args(entry->env, argc, argv); - } - ZLOGD("queue uv_after_work_cb"); - napi_value global = nullptr; - napi_get_global(entry->env, &global); - napi_value result; - napi_status status = napi_call_function(entry->env, global, method, argc, argv, &result); - if (status != napi_ok) { - ZLOGE("notify data change failed status:%{public}d.", status); - } - if (scope != nullptr) { - napi_close_handle_scope(entry->env, scope); - } - }); } napi_env UvQueue::GetEnv() { return env_; } -} // namespace OHOS::DistributedData +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/frameworks/jskitsimpl/distributedkvstore/include/js_field_node.h b/frameworks/jskitsimpl/distributedkvstore/include/js_field_node.h index 600e2f2766aed925232bda70f457738004fa2654..1a132e6ee5687ff1ba596ba394c4054788668c16 100644 --- a/frameworks/jskitsimpl/distributedkvstore/include/js_field_node.h +++ b/frameworks/jskitsimpl/distributedkvstore/include/js_field_node.h @@ -23,8 +23,8 @@ namespace OHOS::DistributedKVStore { class JsFieldNode { public: using json = nlohmann::json; - explicit JsFieldNode(const std::string& fName); - ~JsFieldNode() = default; + explicit JsFieldNode(const std::string& fName, napi_env env); + ~JsFieldNode(); std::string GetFieldName(); std::string Dump(); @@ -57,6 +57,8 @@ private: JSUtil::KvStoreVariant defaultValue_; bool isWithDefaultValue_ = false; bool isNullable_ = false; + napi_env env_ = nullptr; // manage the root. set/get. + std::list refs_; }; } // namespace OHOS::DistributedKVStore #endif // OHOS_FIELD_NODE_H diff --git a/frameworks/jskitsimpl/distributedkvstore/include/js_kv_manager.h b/frameworks/jskitsimpl/distributedkvstore/include/js_kv_manager.h index 5bab6c93d72c8faa8a0b9d312a7b939003334dec..1fd6e3d66fa2b710dfcf81df9d0116fcd8b06116 100644 --- a/frameworks/jskitsimpl/distributedkvstore/include/js_kv_manager.h +++ b/frameworks/jskitsimpl/distributedkvstore/include/js_kv_manager.h @@ -27,6 +27,7 @@ struct ContextParam { std::string hapName = ""; int32_t area = DistributedKv::Area::EL1; bool isSystemApp = false; + int32_t apiVersion = 9; }; class JsKVManager { public: @@ -61,6 +62,7 @@ private: std::list> deathRecipient_ {}; std::shared_ptr uvQueue_; std::shared_ptr param_; + static constexpr int MAX_APP_ID_LEN = 256; }; } // namespace OHOS::DistributedKVStore #endif // OHOS_KV_MANAGER_H diff --git a/frameworks/jskitsimpl/distributedkvstore/include/js_kv_store_resultset.h b/frameworks/jskitsimpl/distributedkvstore/include/js_kv_store_resultset.h index 8fb9ee6284228dfb5d3d4c4045c7602856efcfa0..a952f2406d24fc074f877b2be2911d6cc88d463f 100644 --- a/frameworks/jskitsimpl/distributedkvstore/include/js_kv_store_resultset.h +++ b/frameworks/jskitsimpl/distributedkvstore/include/js_kv_store_resultset.h @@ -15,18 +15,17 @@ #ifndef OHOS_KV_STORE_RESELTSET_H #define OHOS_KV_STORE_RESELTSET_H #include "napi_queue.h" +#include "js_proxy.h" #include "result_set_bridge.h" #include "kvstore_result_set.h" namespace OHOS::DistributedKVStore { -class JsKVStoreResultSet : public DataShare::ResultSetBridge::Creator { +class JsKVStoreResultSet : public JSProxy::JSEntity { public: JsKVStoreResultSet() = default; virtual ~JsKVStoreResultSet() = default; - void SetKvStoreResultSetPtr(std::shared_ptr resultSet); void SetSchema(bool isSchema); - std::shared_ptr GetKvStoreResultSetPtr(); static napi_value Constructor(napi_env env); static napi_value New(napi_env env, napi_callback_info info); @@ -48,7 +47,6 @@ private: static napi_value IsAfterLast(napi_env env, napi_callback_info info); static napi_value GetEntry(napi_env env, napi_callback_info info); - std::shared_ptr resultSet_ = nullptr; bool isSchema_ = false; }; } // namespace OHOS::DistributedKVStore diff --git a/frameworks/jskitsimpl/distributedkvstore/include/js_single_kv_store.h b/frameworks/jskitsimpl/distributedkvstore/include/js_single_kv_store.h index b963467ede293b092cd2a839f423a7328c45101e..1c2c071d2c967ad2e72756070a1f16b36a2d9ea0 100644 --- a/frameworks/jskitsimpl/distributedkvstore/include/js_single_kv_store.h +++ b/frameworks/jskitsimpl/distributedkvstore/include/js_single_kv_store.h @@ -121,6 +121,7 @@ private: std::mutex listMutex_ {}; std::list> dataObserver_[SUBSCRIBE_COUNT]; std::shared_ptr uvQueue_; + static constexpr const char *AUTO_BACKUP_NAME = "autoBackup"; }; } // namespace OHOS::DistributedKVStore #endif // OHOS_SINGLE_KV_STORE_H diff --git a/frameworks/jskitsimpl/distributedkvstore/include/js_util.h b/frameworks/jskitsimpl/distributedkvstore/include/js_util.h index 2d24da1a7616e0f4d06638c31d3fa8c32571be01..3bb619a20193b25f2e740310981a5408b3450205 100644 --- a/frameworks/jskitsimpl/distributedkvstore/include/js_util.h +++ b/frameworks/jskitsimpl/distributedkvstore/include/js_util.h @@ -120,7 +120,7 @@ public: static StatusMsg SetValue(napi_env env, const QueryVariant& in, napi_value& out); /* napi_value <-> std::vector */ - static StatusMsg GetValue(napi_env env, napi_value in, std::vector& out); + static StatusMsg GetValue(napi_env env, napi_value in, std::vector& out, bool checkLength = true); static StatusMsg SetValue(napi_env env, const std::vector& in, napi_value& out); /* napi_value <-> std::vector */ @@ -191,6 +191,16 @@ public: return (jsValue == nullptr) ? StatusMsg(status) : GetValue(env, jsValue, value); }; + static inline bool IsValid(const std::string& storeId) + { + if (storeId.empty() || storeId.size() > MAX_STORE_ID_LEN) { + return false; + } + auto iter = std::find_if_not(storeId.begin(), storeId.end(), + [](char c) { return (std::isdigit(c) || std::isalpha(c) || c == '_'); }); + return (iter == storeId.end()); + } + static const std::optional GetJsFeatureSpace(const std::string &name); /* napi_define_class wrapper */ static napi_value DefineClass(napi_env env, const std::string &spaceName, const std::string &className, @@ -208,6 +218,9 @@ public: static bool IsNull(napi_env env, napi_value value); + static int32_t GetApiVersion(napi_env, napi_value value); + + static std::string Anonymous(const std::string &name); private: enum { /* std::map to js::tuple */ @@ -218,6 +231,9 @@ private: static napi_status GetLevel(int32_t level, int32_t &out); static std::pair GetInnerValue( napi_env env, napi_value in, const std::string& prop, bool optional); + static constexpr int MAX_STORE_ID_LEN = 128; + static constexpr int API_VERSION_MOD = 100; + static constexpr int DEFAULT_API_VERSION = 9; }; } // namespace OHOS::DistributedKVStore #endif // OHOS_JS_UTIL_H diff --git a/frameworks/jskitsimpl/distributedkvstore/include/uv_queue.h b/frameworks/jskitsimpl/distributedkvstore/include/uv_queue.h index f467a763d997fc263a15308632c0c3f65209fd7c..bd2c0e7d31c526f5dade9ce848ddecff1b5cad27 100644 --- a/frameworks/jskitsimpl/distributedkvstore/include/uv_queue.h +++ b/frameworks/jskitsimpl/distributedkvstore/include/uv_queue.h @@ -31,13 +31,7 @@ public: napi_env GetEnv(); void AsyncCall(NapiCallbackGetter getter, NapiArgsGenerator genArgs = NapiArgsGenerator()); private: - struct UvEntry { - napi_env env; - NapiCallbackGetter callback; - NapiArgsGenerator args; - }; napi_env env_ = nullptr; - uv_loop_s* loop_ = nullptr; }; } // namespace OHOS::DistributedKVStore #endif // OHOS_UV_QUEUE_H diff --git a/frameworks/jskitsimpl/distributedkvstore/src/entry_point.cpp b/frameworks/jskitsimpl/distributedkvstore/src/entry_point.cpp index a5e537c9d8bbe60b3e15f4cf2efabdade4a48bc3..085516faa56073c05288e2ae759c8bc314f51c21 100644 --- a/frameworks/jskitsimpl/distributedkvstore/src/entry_point.cpp +++ b/frameworks/jskitsimpl/distributedkvstore/src/entry_point.cpp @@ -28,20 +28,12 @@ static napi_value Init(napi_env env, napi_value exports) const napi_property_descriptor desc[] = { DECLARE_NAPI_FUNCTION("createKVManager", JsKVManager::CreateKVManager) }; - napi_status status = napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); - ZLOGI("init createKVManager %{public}d", status); + napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); + napi_set_named_property(env, exports, "FieldNode", JsFieldNode::Constructor(env)); + napi_set_named_property(env, exports, "Schema", JsSchema::Constructor(env)); + napi_set_named_property(env, exports, "Query", JsQuery::Constructor(env)); + InitConstProperties(env, exports); - status = napi_set_named_property(env, exports, "FieldNode", JsFieldNode::Constructor(env)); - ZLOGI("init FieldNode %{public}d", status); - - status = napi_set_named_property(env, exports, "Schema", JsSchema::Constructor(env)); - ZLOGI("init Schema %{public}d", status); - - status = napi_set_named_property(env, exports, "Query", JsQuery::Constructor(env)); - ZLOGI("init Query %{public}d", status); - - status = InitConstProperties(env, exports); - ZLOGI("init Enumerate Constants %{public}d", status); return exports; } @@ -55,5 +47,5 @@ static __attribute__((constructor)) void RegisterModule() .nm_priv = ((void*)0), .reserved = { 0 } }; napi_module_register(&module); - ZLOGI("module register data.distributedKvstore"); + ZLOGI("Module register data.distributedKvstore"); } diff --git a/frameworks/jskitsimpl/distributedkvstore/src/js_const_properties.cpp b/frameworks/jskitsimpl/distributedkvstore/src/js_const_properties.cpp index aa9394d9850c36462fac19401e429012d9ce893f..0e54930b46897029612dd5ba03b81e4563e8c085 100644 --- a/frameworks/jskitsimpl/distributedkvstore/src/js_const_properties.cpp +++ b/frameworks/jskitsimpl/distributedkvstore/src/js_const_properties.cpp @@ -41,7 +41,10 @@ static napi_value ExportConstants(napi_env env) constexpr int32_t MAX_BATCH_SIZE = 128; napi_value constants = nullptr; - napi_create_object(env, &constants); + napi_status status = napi_create_object(env, &constants); + if (status != napi_ok) { + return nullptr; + } SetNamedProperty(env, constants, "MAX_KEY_LENGTH", MAX_KEY_LENGTH); SetNamedProperty(env, constants, "MAX_VALUE_LENGTH", MAX_VALUE_LENGTH); SetNamedProperty(env, constants, "MAX_KEY_LENGTH_DEVICE", MAX_KEY_LENGTH_DEVICE); @@ -55,7 +58,10 @@ static napi_value ExportConstants(napi_env env) static napi_value ExportValueType(napi_env env) { napi_value valueType = nullptr; - napi_create_object(env, &valueType); + napi_status status = napi_create_object(env, &valueType); + if (status != napi_ok) { + return nullptr; + } SetNamedProperty(env, valueType, "STRING", (int32_t)JSUtil::STRING); SetNamedProperty(env, valueType, "INTEGER", (int32_t)JSUtil::INTEGER); SetNamedProperty(env, valueType, "FLOAT", (int32_t)JSUtil::FLOAT); @@ -69,7 +75,10 @@ static napi_value ExportValueType(napi_env env) static napi_value ExportSyncMode(napi_env env) { napi_value syncMode = nullptr; - napi_create_object(env, &syncMode); + napi_status status = napi_create_object(env, &syncMode); + if (status != napi_ok) { + return nullptr; + } SetNamedProperty(env, syncMode, "PULL_ONLY", (int32_t)SyncMode::PULL); SetNamedProperty(env, syncMode, "PUSH_ONLY", (int32_t)SyncMode::PUSH); SetNamedProperty(env, syncMode, "PUSH_PULL", (int32_t)SyncMode::PUSH_PULL); @@ -80,8 +89,10 @@ static napi_value ExportSyncMode(napi_env env) static napi_value ExportSubscribeType(napi_env env) { napi_value subscribeType = nullptr; - napi_create_object(env, &subscribeType); - + napi_status status = napi_create_object(env, &subscribeType); + if (status != napi_ok) { + return nullptr; + } SetNamedProperty(env, subscribeType, "SUBSCRIBE_TYPE_LOCAL", (int32_t)SUBSCRIBE_LOCAL); SetNamedProperty(env, subscribeType, "SUBSCRIBE_TYPE_REMOTE", (int32_t)SUBSCRIBE_REMOTE); SetNamedProperty(env, subscribeType, "SUBSCRIBE_TYPE_ALL", (int32_t)SUBSCRIBE_LOCAL_REMOTE); @@ -92,7 +103,10 @@ static napi_value ExportSubscribeType(napi_env env) static napi_value ExportKVStoreType(napi_env env) { napi_value kvStoreType = nullptr; - napi_create_object(env, &kvStoreType); + napi_status status = napi_create_object(env, &kvStoreType); + if (status != napi_ok) { + return nullptr; + } SetNamedProperty(env, kvStoreType, "DEVICE_COLLABORATION", (int32_t)KvStoreType::DEVICE_COLLABORATION); SetNamedProperty(env, kvStoreType, "SINGLE_VERSION", (int32_t)KvStoreType::SINGLE_VERSION); napi_object_freeze(env, kvStoreType); @@ -102,8 +116,10 @@ static napi_value ExportKVStoreType(napi_env env) static napi_value ExportSecurityLevel(napi_env env) { napi_value securityLevel = nullptr; - - napi_create_object(env, &securityLevel); + napi_status status = napi_create_object(env, &securityLevel); + if (status != napi_ok) { + return nullptr; + } SetNamedProperty(env, securityLevel, "S1", (int32_t)SecurityLevel::S1); SetNamedProperty(env, securityLevel, "S2", (int32_t)SecurityLevel::S2); SetNamedProperty(env, securityLevel, "S3", (int32_t)SecurityLevel::S3); diff --git a/frameworks/jskitsimpl/distributedkvstore/src/js_device_kv_store.cpp b/frameworks/jskitsimpl/distributedkvstore/src/js_device_kv_store.cpp index 83ce191171c821880e3fe95ae6f2e6c08f0c6290..54c9ec1f64465c6c42581782708f464f030b2778 100644 --- a/frameworks/jskitsimpl/distributedkvstore/src/js_device_kv_store.cpp +++ b/frameworks/jskitsimpl/distributedkvstore/src/js_device_kv_store.cpp @@ -13,8 +13,9 @@ * limitations under the License. */ #define LOG_TAG "JsDeviceKVStore" -#include "js_device_kv_store.h" #include + +#include "js_device_kv_store.h" #include "js_kv_store_resultset.h" #include "js_query.h" #include "js_util.h" @@ -90,15 +91,17 @@ napi_value JsDeviceKVStore::Get(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt](size_t argc, napi_value* argv) { // number 2 means: required 2 arguments, + - ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); if (argc > 1) { ctxt->status = JSUtil::GetValue(env, argv[0], ctxt->deviceId); ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The parameter deviceId is incorrect."); + "Parameter error:parameter deviceId must be string and not allow empty"); } int32_t pos = (argc == 1) ? 0 : 1; ctxt->status = JSUtil::GetValue(env, argv[pos], ctxt->key); - ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, "The type of key must be string."); + ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, + "Parameter error:type of key must be string and not allow empty"); }; ctxt->GetCbInfo(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "DeviceGet exits"); @@ -108,6 +111,9 @@ napi_value JsDeviceKVStore::Get(napi_env env, napi_callback_info info) OHOS::DistributedKv::Key key(deviceKey); OHOS::DistributedKv::Value value; auto kvStore = reinterpret_cast(ctxt->native)->GetKvStorePtr(); + if (kvStore == nullptr) { + return; + } ASSERT_STATUS(ctxt, "kvStore->result() failed!"); bool isSchemaStore = reinterpret_cast(ctxt->native)->IsSchemaStore(); Status status = kvStore->Get(key, value); @@ -135,14 +141,14 @@ static JSUtil::StatusMsg GetVariantArgs(napi_env env, size_t argc, napi_value* a napi_valuetype type = napi_undefined; JSUtil::StatusMsg statusMsg = napi_typeof(env, argv[pos], &type); if (statusMsg != napi_ok || (type != napi_string && type != napi_object)) { - va.errMsg = "The type of parameters keyPrefix/query is incorrect."; + va.errMsg = "Parameter error:parameters keyPrefix/query must be string or object"; return statusMsg != napi_ok ? statusMsg.status : napi_invalid_arg; } if (type == napi_string) { std::string keyPrefix; statusMsg = JSUtil::GetValue(env, argv[pos], keyPrefix); if (keyPrefix.empty()) { - va.errMsg = "The type of parameters keyPrefix is incorrect."; + va.errMsg = "Parameter error:parameters keyPrefix must be string"; return napi_invalid_arg; } va.dataQuery.KeyPrefix(keyPrefix); @@ -153,7 +159,7 @@ static JSUtil::StatusMsg GetVariantArgs(napi_env env, size_t argc, napi_value* a JsQuery *jsQuery = nullptr; statusMsg = JSUtil::Unwrap(env, argv[pos], reinterpret_cast(&jsQuery), JsQuery::Constructor(env)); if (jsQuery == nullptr) { - va.errMsg = "The parameters query is incorrect."; + va.errMsg = "Parameter error:The parameters query must be string"; return napi_invalid_arg; } va.dataQuery = jsQuery->GetDataQuery(); @@ -190,7 +196,8 @@ napi_value JsDeviceKVStore::GetEntries(napi_env env, napi_callback_info info) }; auto ctxt = std::make_shared(); auto input = [env, ctxt](size_t argc, napi_value* argv) { - ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = GetVariantArgs(env, argc, argv, ctxt->va); ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, ctxt->va.errMsg); }; @@ -199,6 +206,9 @@ napi_value JsDeviceKVStore::GetEntries(napi_env env, napi_callback_info info) auto execute = [ctxt]() { auto kvStore = reinterpret_cast(ctxt->native)->GetKvStorePtr(); + if (kvStore == nullptr) { + return; + } Status status = kvStore->GetEntries(ctxt->va.dataQuery, ctxt->entries); ZLOGD("kvStore->GetEntries() return %{public}d", status); ctxt->status = (GenerateNapiError(status, ctxt->jsCode, ctxt->error) == Status::SUCCESS) ? @@ -232,7 +242,8 @@ napi_value JsDeviceKVStore::GetResultSet(napi_env env, napi_callback_info info) }; auto ctxt = std::make_shared(); auto input = [env, ctxt](size_t argc, napi_value* argv) { - ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); JSUtil::StatusMsg statusMsg = GetVariantArgs(env, argc, argv, ctxt->va); ctxt->status = statusMsg.status; ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, ctxt->va.errMsg); @@ -242,7 +253,7 @@ napi_value JsDeviceKVStore::GetResultSet(napi_env env, napi_callback_info info) ctxt->ref = JSUtil::NewWithRef(env, 0, nullptr, reinterpret_cast(&ctxt->resultSet), JsKVStoreResultSet::Constructor(env)); ASSERT_BUSINESS_ERR(ctxt, ctxt->resultSet != nullptr, Status::INVALID_ARGUMENT, - "KVStoreResultSet::New failed!"); + "Parameter error:resultSet is null"); }; ctxt->GetCbInfo(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "GetResultSet exit"); @@ -250,11 +261,14 @@ napi_value JsDeviceKVStore::GetResultSet(napi_env env, napi_callback_info info) auto execute = [ctxt]() { std::shared_ptr kvResultSet; auto kvStore = reinterpret_cast(ctxt->native)->GetKvStorePtr(); + if (kvStore == nullptr) { + return; + } Status status = kvStore->GetResultSet(ctxt->va.dataQuery, kvResultSet); ZLOGD("kvStore->GetResultSet() return %{public}d", status); ctxt->status = (GenerateNapiError(status, ctxt->jsCode, ctxt->error) == Status::SUCCESS) ? napi_ok : napi_generic_failure; - ctxt->resultSet->SetKvStoreResultSetPtr(kvResultSet); + ctxt->resultSet->SetInstance(kvResultSet); bool isSchema = reinterpret_cast(ctxt->native)->IsSchemaStore(); ctxt->resultSet->SetSchema(isSchema); }; @@ -282,7 +296,8 @@ napi_value JsDeviceKVStore::GetResultSize(napi_env env, napi_callback_info info) }; auto ctxt = std::make_shared(); auto input = [env, ctxt](size_t argc, napi_value* argv) { - ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = GetVariantArgs(env, argc, argv, ctxt->va); ASSERT_BUSINESS_ERR(ctxt, ctxt->status != napi_invalid_arg, Status::INVALID_ARGUMENT, ctxt->va.errMsg); }; @@ -292,6 +307,9 @@ napi_value JsDeviceKVStore::GetResultSize(napi_env env, napi_callback_info info) auto execute = [ctxt]() { auto kvStore = reinterpret_cast(ctxt->native)->GetKvStorePtr(); + if (kvStore == nullptr) { + return; + } Status status = kvStore->GetCount(ctxt->va.dataQuery, ctxt->resultSize); ZLOGD("kvStore->GetCount() return %{public}d", status); ctxt->status = (GenerateNapiError(status, ctxt->jsCode, ctxt->error) == Status::SUCCESS) ? @@ -311,7 +329,8 @@ napi_value JsDeviceKVStore::New(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt, &storeId](size_t argc, napi_value* argv) { // required 2 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = JSUtil::GetValue(env, argv[0], storeId); ASSERT_BUSINESS_ERR(ctxt, (ctxt->status == napi_ok) && !storeId.empty(), Status::INVALID_ARGUMENT, "The type of storeId must be string."); @@ -320,7 +339,7 @@ napi_value JsDeviceKVStore::New(napi_env env, napi_callback_info info) ASSERT_NULL(!ctxt->isThrowError, "New JsDeviceKVStore exit"); JsDeviceKVStore* kvStore = new (std::nothrow) JsDeviceKVStore(storeId); - ASSERT_ERR(env, kvStore != nullptr, Status::INVALID_ARGUMENT, "no memory for kvStore"); + ASSERT_ERR(env, kvStore != nullptr, Status::INVALID_ARGUMENT, "Parameter error:kvStore is nullptr"); auto finalize = [](napi_env env, void* data, void* hint) { ZLOGI("deviceKvStore finalize."); diff --git a/frameworks/jskitsimpl/distributedkvstore/src/js_error_utils.cpp b/frameworks/jskitsimpl/distributedkvstore/src/js_error_utils.cpp index 2d07ea5eefbea0bbc5f4272d9324d1ebbe845553..d79c19b9067e4b4be665816dd6e4dd8716ebf7fb 100644 --- a/frameworks/jskitsimpl/distributedkvstore/src/js_error_utils.cpp +++ b/frameworks/jskitsimpl/distributedkvstore/src/js_error_utils.cpp @@ -22,7 +22,7 @@ namespace OHOS::DistributedKVStore { using JsErrorCode = OHOS::DistributedKVStore::JsErrorCode; static constexpr JsErrorCode JS_ERROR_CODE_MSGS[] = { - { Status::INVALID_ARGUMENT, 401, "Parameter error." }, + { Status::INVALID_ARGUMENT, 401, "Parameter error: Parameters verification failed." }, { Status::STORE_NOT_OPEN, 0, "" }, { Status::STORE_ALREADY_SUBSCRIBE, 0, "" }, { Status::STORE_NOT_SUBSCRIBE, 0, "" }, @@ -32,6 +32,7 @@ static constexpr JsErrorCode JS_ERROR_CODE_MSGS[] = { { Status::CRYPT_ERROR, 15100003, "Database corrupted." }, { Status::OVER_MAX_LIMITS, 15100001, "Over max limits." }, { 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."} }; @@ -86,16 +87,21 @@ void ThrowNapiError(napi_env env, int32_t status, const std::string &errMessage, std::string message(napiError.message); if (isParamsCheck) { - napiError.jsCode = 401; + napiError.jsCode = 401; // 401 is parameter validation error code message += errMessage; } - std::string jsCode; if (napiError.jsCode == -1) { - jsCode = ""; - } else { - jsCode = std::to_string(napiError.jsCode); + napi_throw_error(env, "", message.c_str()); + return; } - napi_throw_error(env, jsCode.c_str(), message.c_str()); + + napi_value errorObj = nullptr; + napi_value errorCode = nullptr; + napi_value errorMessage = nullptr; + napi_create_int32(env, napiError.jsCode, &errorCode); + napi_create_string_utf8(env, message.c_str(), NAPI_AUTO_LENGTH, &errorMessage); + napi_create_error(env, errorCode, errorMessage, &errorObj); + napi_throw(env, errorObj); } } // namespace OHOS::DistributedKVStore \ No newline at end of file diff --git a/frameworks/jskitsimpl/distributedkvstore/src/js_field_node.cpp b/frameworks/jskitsimpl/distributedkvstore/src/js_field_node.cpp index 112f5e1407b9e4cddebbe20007261acdbfb8682e..2354e4edf017d01249251ddb4bb2f722ccda269d 100644 --- a/frameworks/jskitsimpl/distributedkvstore/src/js_field_node.cpp +++ b/frameworks/jskitsimpl/distributedkvstore/src/js_field_node.cpp @@ -22,27 +22,41 @@ using namespace OHOS::DistributedKv; namespace OHOS::DistributedKVStore { -static std::string FIELD_NAME = "FIELD_NAME"; -static std::string VALUE_TYPE = "VALUE_TYPE"; -static std::string DEFAULT_VALUE = "DEFAULT_VALUE"; -static std::string IS_DEFAULT_VALUE = "IS_DEFAULT_VALUE"; -static std::string IS_NULLABLE = "IS_NULLABLE"; -static std::string CHILDREN = "CHILDREN"; +static constexpr const char* FIELD_NAME = "FIELD_NAME"; +static constexpr const char* VALUE_TYPE = "VALUE_TYPE"; +static constexpr const char* DEFAULT_VALUE = "DEFAULT_VALUE"; +static constexpr const char* IS_DEFAULT_VALUE = "IS_DEFAULT_VALUE"; +static constexpr const char* IS_NULLABLE = "IS_NULLABLE"; +static constexpr const char* CHILDREN = "CHILDREN"; +static constexpr const char* SPLIT = ","; +static constexpr const char* NOT_NULL = ", NOT NULL,"; +static constexpr const char* DEFAULT = " DEFAULT "; +static constexpr const char* MARK = "'"; std::map JsFieldNode::valueTypeToString_ = { { JSUtil::STRING, std::string("STRING") }, { JSUtil::INTEGER, std::string("INTEGER") }, - { JSUtil::FLOAT, std::string("FLOAT") }, + { JSUtil::FLOAT, std::string("DOUBLE") }, { JSUtil::BYTE_ARRAY, std::string("BYTE_ARRAY") }, - { JSUtil::BOOLEAN, std::string("BOOLEAN") }, + { JSUtil::BOOLEAN, std::string("BOOL") }, { JSUtil::DOUBLE, std::string("DOUBLE") } }; -JsFieldNode::JsFieldNode(const std::string& fName) - : fieldName_(fName) +JsFieldNode::JsFieldNode(const std::string& fName, napi_env env) + : fieldName_(fName), env_(env) { } +JsFieldNode::~JsFieldNode() +{ + ZLOGI("no memory leak for JsFieldNode"); + for (auto ref : refs_) { + if (ref != nullptr) { + napi_delete_reference(env_, ref); + } + } +} + std::string JsFieldNode::GetFieldName() { return fieldName_; @@ -51,7 +65,11 @@ std::string JsFieldNode::GetFieldName() JsFieldNode::json JsFieldNode::GetValueForJson() { if (fields_.empty()) { - return ToString(valueType_) + "," + (isNullable_ ? "NULL" : "NOT NULL"); + std::string jsonDesc = ToString(valueType_) + (isNullable_ ? SPLIT : NOT_NULL) + DEFAULT; + if (valueType_ == JSUtil::STRING) { + return jsonDesc += MARK + ToString(defaultValue_) + MARK; + } + return jsonDesc += ToString(defaultValue_); } json jsFields; @@ -82,19 +100,20 @@ napi_value JsFieldNode::New(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt, &fieldName](size_t argc, napi_value* argv) { // required 1 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = JSUtil::GetValue(env, argv[0], fieldName); ASSERT_BUSINESS_ERR(ctxt, ((ctxt->status == napi_ok) && !fieldName.empty()), - Status::INVALID_ARGUMENT, "The parameters of fieldName is incorrect."); + Status::INVALID_ARGUMENT, "Parameter error:fieldName empty"); }; ctxt->GetCbInfoSync(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "JsFieldNode New exit"); - JsFieldNode* fieldNode = new (std::nothrow) JsFieldNode(fieldName); - ASSERT_ERR(env, fieldNode != nullptr, Status::INVALID_ARGUMENT, "no memory for fieldNode."); + JsFieldNode* fieldNode = new (std::nothrow) JsFieldNode(fieldName, env); + ASSERT_ERR(env, fieldNode != nullptr, Status::INVALID_ARGUMENT, "Parameter error:fieldNode is nullptr"); auto finalize = [](napi_env env, void* data, void* hint) { - ZLOGD("fieldNode finalize."); + ZLOGI("fieldNode finalize."); auto* fieldNode = reinterpret_cast(data); ASSERT_VOID(fieldNode != nullptr, "fieldNode is null!"); delete fieldNode; @@ -106,21 +125,25 @@ napi_value JsFieldNode::New(napi_env env, napi_callback_info info) napi_value JsFieldNode::AppendChild(napi_env env, napi_callback_info info) { ZLOGD("FieldNode::AppendChild"); - JsFieldNode* child = nullptr; auto ctxt = std::make_shared(); - auto input = [env, ctxt, &child](size_t argc, napi_value* argv) { + auto input = [env, ctxt](size_t argc, napi_value* argv) { // required 1 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); + JsFieldNode* child = nullptr; ctxt->status = JSUtil::Unwrap(env, argv[0], reinterpret_cast(&child), JsFieldNode::Constructor(env)); ASSERT_BUSINESS_ERR(ctxt, ((ctxt->status == napi_ok) && (child != nullptr)), - Status::INVALID_ARGUMENT, "The parameters JsFieldNode is incorrect."); + Status::INVALID_ARGUMENT, "Parameter error:child is nullptr"); + + auto fieldNode = reinterpret_cast(ctxt->native); + napi_ref ref = nullptr; + ctxt->status = napi_create_reference(env, argv[0], 1, &ref); + ASSERT_STATUS(ctxt, "napi_create_reference to FieldNode failed"); + fieldNode->fields_.push_back(child); + fieldNode->refs_.push_back(ref); }; ctxt->GetCbInfoSync(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "AppendChild exit"); - - auto fieldNode = reinterpret_cast(ctxt->native); - fieldNode->fields_.push_back(child); - napi_get_boolean(env, true, &ctxt->output); return ctxt->output; } @@ -160,7 +183,8 @@ napi_value JsFieldNode::SetDefaultValue(napi_env env, napi_callback_info info) ASSERT_STATUS(ctxt, "invalid arg[0], i.e. invalid defaultValue!"); }; ctxt->GetCbInfoSync(env, info, input); - NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); + NAPI_ASSERT(env, ctxt->status == napi_ok, + "Parameter error:Parameters type must belong one of string,number,array,bool."); auto fieldNode = reinterpret_cast(ctxt->native); fieldNode->defaultValue_ = vv; @@ -188,7 +212,7 @@ napi_value JsFieldNode::SetNullable(napi_env env, napi_callback_info info) ASSERT_STATUS(ctxt, "invalid arg[0], i.e. invalid isNullable!"); }; ctxt->GetCbInfoSync(env, info, input); - NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); + NAPI_ASSERT(env, ctxt->status == napi_ok, "Parameter error:Parameters type failed"); auto fieldNode = reinterpret_cast(ctxt->native); fieldNode->isNullable_ = isNullable; @@ -218,7 +242,7 @@ napi_value JsFieldNode::SetValueType(napi_env env, napi_callback_info info) "invalid arg[0], i.e. invalid valueType!"); }; ctxt->GetCbInfoSync(env, info, input); - NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); + NAPI_ASSERT(env, ctxt->status == napi_ok, "Parameter error:Parameters type failed"); auto fieldNode = reinterpret_cast(ctxt->native); fieldNode->valueType_ = type; diff --git a/frameworks/jskitsimpl/distributedkvstore/src/js_kv_manager.cpp b/frameworks/jskitsimpl/distributedkvstore/src/js_kv_manager.cpp index 5bb09a2793500c184a82d314b45da256d972cc5c..71078694a7b89262ef578589244ab316fd8c180f 100644 --- a/frameworks/jskitsimpl/distributedkvstore/src/js_kv_manager.cpp +++ b/frameworks/jskitsimpl/distributedkvstore/src/js_kv_manager.cpp @@ -56,25 +56,25 @@ napi_value JsKVManager::CreateKVManager(napi_env env, napi_callback_info info) napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); if (argc < 1) { - ThrowNapiError(env, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ThrowNapiError(env, Status::INVALID_ARGUMENT, "Parameter error:Mandatory parameters are left unspecified"); return result; } std::string bundleName; napi_status status = JSUtil::GetNamedProperty(env, argv[0], "bundleName", bundleName); if (status == napi_generic_failure) { - ThrowNapiError(env, Status::INVALID_ARGUMENT, "Missing bundleName parameter."); + ThrowNapiError(env, Status::INVALID_ARGUMENT, "Parameter error:Missing bundleName parameter."); return result; } if (bundleName.empty()) { - ThrowNapiError(env, Status::INVALID_ARGUMENT, "The type of bundleName must be string."); + ThrowNapiError(env, Status::INVALID_ARGUMENT, "Parameter error:The type of bundleName must be string."); return result; } napi_value jsContext = nullptr; status = JSUtil::GetNamedProperty(env, argv[0], "context", jsContext); if (status == napi_generic_failure) { - ThrowNapiError(env, Status::INVALID_ARGUMENT, "Missing context parameter."); + ThrowNapiError(env, Status::INVALID_ARGUMENT, "Parameter error:Missing context parameter."); return result; } @@ -97,14 +97,18 @@ struct GetKVStoreContext : public ContextBase { { auto input = [env, this](size_t argc, napi_value* argv) { // required 2 arguments :: - ASSERT_BUSINESS_ERR(this, argc >= 2, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(this, argc >= 2, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); status = JSUtil::GetValue(env, argv[0], storeId); - ASSERT_BUSINESS_ERR(this, ((status == napi_ok) && !storeId.empty()), Status::INVALID_ARGUMENT, - "The type of storeId must be string."); + ASSERT_BUSINESS_ERR(this, ((status == napi_ok) && JSUtil::IsValid(storeId)), Status::INVALID_ARGUMENT, + "Parameter error:storeId must be string,consist of letters,digits,underscores(_),limit 128 chars"); status = JSUtil::GetValue(env, argv[1], options); - ASSERT_BUSINESS_ERR(this, status == napi_ok, Status::INVALID_ARGUMENT, "The type of options is incorrect."); + ASSERT_BUSINESS_ERR(this, status == napi_ok, Status::INVALID_ARGUMENT, + "Parameter error:The params type not matching option"); + ASSERT_BUSINESS_ERR(this, options.securityLevel != INVALID_LABEL, Status::INVALID_ARGUMENT, + "Parameter error:unusable securityLevel"); ASSERT_BUSINESS_ERR(this, IsStoreTypeSupported(options), Status::INVALID_ARGUMENT, - "The type of kvStoreType is incorrect."); + "Parameter error:only support DEVICE_COLLABORATION or SINGLE_VERSION"); ZLOGD("GetKVStore kvStoreType=%{public}d", options.kvStoreType); if (options.kvStoreType == KvStoreType::DEVICE_COLLABORATION) { ref = JSUtil::NewWithRef(env, argc, argv, reinterpret_cast(&kvStore), @@ -139,15 +143,16 @@ 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; - ZLOGD("Options area:%{public}d dir:%{public}s", ctxt->options.area, ctxt->options.baseDir.c_str()); + ctxt->options.apiVersion = kvm->param_->apiVersion; + ZLOGD("Options area:%{public}d dir:%{public}s", ctxt->options.area, + JSUtil::Anonymous(ctxt->options.baseDir).c_str()); std::shared_ptr kvStore; Status status = kvm->kvDataManager_.GetSingleKvStore(ctxt->options, appId, storeId, kvStore); - if (status == CRYPT_ERROR) { + if (status == DATA_CORRUPTED) { ctxt->options.rebuild = true; status = kvm->kvDataManager_.GetSingleKvStore(ctxt->options, appId, storeId, kvStore); ZLOGE("Data has corrupted, rebuild db"); } - ctxt->status = (GenerateNapiError(status, ctxt->jsCode, ctxt->error) == Status::SUCCESS) ? napi_ok : napi_generic_failure; ctxt->kvStore->SetKvStorePtr(kvStore); @@ -179,13 +184,14 @@ napi_value JsKVManager::CloseKVStore(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt](size_t argc, napi_value* argv) { // required 3 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = JSUtil::GetValue(env, argv[0], ctxt->appId); ASSERT_BUSINESS_ERR(ctxt, (ctxt->status == napi_ok) && !ctxt->appId.empty(), Status::INVALID_ARGUMENT, - "The type of appId must be string."); + "Parameter error:appId empty"); ctxt->status = JSUtil::GetValue(env, argv[1], ctxt->storeId); - ASSERT_BUSINESS_ERR(ctxt, (ctxt->status == napi_ok) && !ctxt->storeId.empty(), Status::INVALID_ARGUMENT, - "The type of storeId must be string."); + ASSERT_BUSINESS_ERR(ctxt, (ctxt->status == napi_ok) && JSUtil::IsValid(ctxt->storeId), Status::INVALID_ARGUMENT, + "Parameter error:storeId must be string,consist of letters, digits, underscores(_), limit 128 characters"); }; ctxt->GetCbInfo(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "CloseKVStore exits"); @@ -218,14 +224,15 @@ napi_value JsKVManager::DeleteKVStore(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt](size_t argc, napi_value* argv) { // required 2 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); size_t index = 0; ctxt->status = JSUtil::GetValue(env, argv[index++], ctxt->appId); ASSERT_BUSINESS_ERR(ctxt, !ctxt->appId.empty(), Status::INVALID_ARGUMENT, - "The parameters of appId is incorrect."); + "Parameter error:appId empty"); ctxt->status = JSUtil::GetValue(env, argv[index++], ctxt->storeId); - ASSERT_BUSINESS_ERR(ctxt, !ctxt->storeId.empty(), Status::INVALID_ARGUMENT, - "The parameters of storeId is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, JSUtil::IsValid(ctxt->storeId), Status::INVALID_ARGUMENT, + "error:storeId must be string; consist of only letters, digits underscores (_),limit 128 characters"); }; ctxt->GetCbInfo(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "DeleteKVStore exits"); @@ -236,7 +243,7 @@ napi_value JsKVManager::DeleteKVStore(napi_env env, napi_callback_info info) auto kvm = reinterpret_cast(ctxt->native); ASSERT_ARGS(ctxt, kvm != nullptr, "KVManager is null, failed!"); std::string databaseDir = kvm->param_->baseDir; - ZLOGD("DeleteKVStore databaseDir is: %{public}s", databaseDir.c_str()); + ZLOGD("DeleteKVStore databaseDir is: %{public}s", JSUtil::Anonymous(databaseDir).c_str()); Status status = kvm->kvDataManager_.DeleteKvStore(appId, storeId, databaseDir); ZLOGD("DeleteKvStore status:%{public}d", status); ctxt->status = (GenerateNapiError(status, ctxt->jsCode, ctxt->error) == Status::SUCCESS) ? @@ -260,10 +267,13 @@ napi_value JsKVManager::GetAllKVStoreId(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt](size_t argc, napi_value* argv) { // required 1 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = JSUtil::GetValue(env, argv[0], ctxt->appId); ASSERT_BUSINESS_ERR(ctxt, !ctxt->appId.empty(), Status::INVALID_ARGUMENT, - "The parameters of appId is incorrect."); + "Parameter error:appId empty"); + ASSERT_BUSINESS_ERR(ctxt, (ctxt->appId.size() < MAX_APP_ID_LEN), Status::INVALID_ARGUMENT, + "Parameter error:appId exceed 256 characters"); }; ctxt->GetCbInfo(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "GetAllKVStoreId exits"); @@ -289,20 +299,22 @@ napi_value JsKVManager::On(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt](size_t argc, napi_value* argv) { // required 2 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); std::string event; ctxt->status = JSUtil::GetValue(env, argv[0], event); ZLOGI("subscribe to event:%{public}s", event.c_str()); ASSERT_BUSINESS_ERR(ctxt, event == "distributedDataServiceDie", Status::INVALID_ARGUMENT, - "The parameters of event is incorrect."); + "Parameter error:parameter event type not equal distributedDataServiceDie"); napi_valuetype valueType = napi_undefined; ctxt->status = napi_typeof(env, argv[1], &valueType); ASSERT_BUSINESS_ERR(ctxt, (ctxt->status == napi_ok) && (valueType == napi_function), Status::INVALID_ARGUMENT, - "The type of parameters deathCallback must be a function."); + "Parameter error:parameter callback must be function type"); JsKVManager* proxy = reinterpret_cast(ctxt->native); - ASSERT_BUSINESS_ERR(ctxt, proxy != nullptr, Status::INVALID_ARGUMENT, "there is no native kv manager."); + ASSERT_BUSINESS_ERR(ctxt, proxy != nullptr, Status::INVALID_ARGUMENT, + "Parameter error:JsKVManager nullptr"); std::lock_guard lck(proxy->deathMutex_); for (auto& it : proxy->deathRecipient_) { @@ -328,19 +340,20 @@ napi_value JsKVManager::Off(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt](size_t argc, napi_value* argv) { // required 1 or 2 arguments :: [callback] - ASSERT_BUSINESS_ERR(ctxt, argc > 0, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc > 0, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); std::string event; ctxt->status = JSUtil::GetValue(env, argv[0], event); // required 1 arguments :: ZLOGI("unsubscribe to event:%{public}s %{public}s specified", event.c_str(), (argc == 1) ? "without" : "with"); ASSERT_BUSINESS_ERR(ctxt, event == "distributedDataServiceDie", Status::INVALID_ARGUMENT, - "The parameters of event is incorrect."); + "Parameter error:parameter event not equal distributedDataServiceDie"); // have 2 arguments :: have the [callback] if (argc == 2) { napi_valuetype valueType = napi_undefined; ctxt->status = napi_typeof(env, argv[1], &valueType); ASSERT_BUSINESS_ERR(ctxt, (ctxt->status == napi_ok) && (valueType == napi_function), - Status::INVALID_ARGUMENT, "The type of parameters deathCallback must be a function."); + Status::INVALID_ARGUMENT, "Parameter error:parameter callback type must be function"); } JsKVManager* proxy = reinterpret_cast(ctxt->native); std::lock_guard lck(proxy->deathMutex_); @@ -359,7 +372,7 @@ napi_value JsKVManager::Off(napi_env env, napi_callback_info info) }; ctxt->GetCbInfoSync(env, info, input); if (ctxt->status != napi_ok) { - ThrowNapiError(env, Status::INVALID_ARGUMENT, ""); + ThrowNapiError(env, Status::INVALID_ARGUMENT, "Parameter error:params must be sting or function"); } ZLOGD("KVManager::Off callback is not register or already unregister!"); return nullptr; @@ -388,23 +401,25 @@ napi_value JsKVManager::New(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt, &bundleName, ¶m](size_t argc, napi_value* argv) { // required 1 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = JSUtil::GetNamedProperty(env, argv[0], "bundleName", bundleName); ASSERT_BUSINESS_ERR(ctxt, ctxt->status != napi_generic_failure, Status::INVALID_ARGUMENT, - "Missing bundleName parameter."); + "Parameter error:The bundleName parameter is missing."); ASSERT_BUSINESS_ERR(ctxt, !bundleName.empty(), Status::INVALID_ARGUMENT, - "The type of bundleName must be string."); + "Parameter error:The bundleName field cannot be empty."); napi_value jsContext = nullptr; JSUtil::GetNamedProperty(env, argv[0], "context", jsContext); ctxt->status = JSUtil::GetValue(env, jsContext, param); - ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, "get context parameter failed."); + ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, + "Parameter error:get context failed"); }; ctxt->GetCbInfoSync(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "JsKVManager New exit"); JsKVManager* kvManager = new (std::nothrow) JsKVManager(bundleName, env, param); - ASSERT_ERR(env, kvManager != nullptr, Status::INVALID_ARGUMENT, "no memory for kvManager."); + ASSERT_ERR(env, kvManager != nullptr, Status::INVALID_ARGUMENT, "Parameter error:kvManager is nullptr"); auto finalize = [](napi_env env, void* data, void* hint) { ZLOGD("kvManager finalize."); diff --git a/frameworks/jskitsimpl/distributedkvstore/src/js_kv_store_resultset.cpp b/frameworks/jskitsimpl/distributedkvstore/src/js_kv_store_resultset.cpp index c19a9499e1a78a248b67021e434958329e4d3a33..7507a42ce42c021498d03450504aaf8ab5172dad 100644 --- a/frameworks/jskitsimpl/distributedkvstore/src/js_kv_store_resultset.cpp +++ b/frameworks/jskitsimpl/distributedkvstore/src/js_kv_store_resultset.cpp @@ -24,15 +24,6 @@ using namespace OHOS::DistributedKv; using namespace OHOS::DataShare; namespace OHOS::DistributedKVStore { -void JsKVStoreResultSet::SetKvStoreResultSetPtr(std::shared_ptr resultSet) -{ - resultSet_ = resultSet; -} - -std::shared_ptr JsKVStoreResultSet::GetKvStoreResultSetPtr() -{ - return resultSet_; -} napi_value JsKVStoreResultSet::Constructor(napi_env env) { @@ -86,7 +77,8 @@ napi_value JsKVStoreResultSet::GetCount(napi_env env, napi_callback_info info) / NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); ZLOGD("KVStoreResultSet::GetCount(status=%{public}d)", ctxt->status); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); int count = resultSet->GetCount(); napi_create_int32(env, count, &ctxt->output); @@ -100,7 +92,8 @@ napi_value JsKVStoreResultSet::GetPosition(napi_env env, napi_callback_info info ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); int position = resultSet->GetPosition(); napi_create_int32(env, position, &ctxt->output); @@ -114,7 +107,8 @@ napi_value JsKVStoreResultSet::MoveToFirst(napi_env env, napi_callback_info info ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isMoved = resultSet->MoveToFirst(); napi_get_boolean(env, isMoved, &ctxt->output); @@ -128,7 +122,8 @@ napi_value JsKVStoreResultSet::MoveToLast(napi_env env, napi_callback_info info) ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isMoved = resultSet->MoveToLast(); napi_get_boolean(env, isMoved, &ctxt->output); @@ -142,7 +137,8 @@ napi_value JsKVStoreResultSet::MoveToNext(napi_env env, napi_callback_info info) ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isMoved = resultSet->MoveToNext(); napi_get_boolean(env, isMoved, &ctxt->output); @@ -156,7 +152,8 @@ napi_value JsKVStoreResultSet::MoveToPrevious(napi_env env, napi_callback_info i ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isMoved = resultSet->MoveToPrevious(); napi_get_boolean(env, isMoved, &ctxt->output); @@ -170,14 +167,16 @@ napi_value JsKVStoreResultSet::Move(napi_env env, napi_callback_info info) /* bo auto ctxt = std::make_shared(); auto input = [env, ctxt, &offset](size_t argc, napi_value* argv) { // required 1 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = napi_get_value_int32(env, argv[0], reinterpret_cast(&offset)); }; ctxt->GetCbInfoSync(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "Move exit"); - ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, "The function MoveV9 parameter is incorrect."); + ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, "Parameter error:params offset must be number"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isMoved = resultSet->Move(offset); napi_get_boolean(env, isMoved, &ctxt->output); @@ -190,16 +189,18 @@ napi_value JsKVStoreResultSet::MoveToPosition(napi_env env, napi_callback_info i auto ctxt = std::make_shared(); auto input = [env, ctxt, &position](size_t argc, napi_value* argv) { // required 1 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = napi_get_value_int32(env, argv[0], reinterpret_cast(&position)); }; ctxt->GetCbInfoSync(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "MoveToPosition exit"); ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The function MoveToPositionV9 parameter is incorrect."); + "Parameter error:params position must be number"); ZLOGD("KVStoreResultSet::MoveToPosition(%{public}d)", position); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isMoved = resultSet->MoveToPosition(position); napi_get_boolean(env, isMoved, &ctxt->output); @@ -213,7 +214,8 @@ napi_value JsKVStoreResultSet::IsFirst(napi_env env, napi_callback_info info) /* ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isFirst = resultSet->IsFirst(); napi_get_boolean(env, isFirst, &ctxt->output); @@ -227,7 +229,8 @@ napi_value JsKVStoreResultSet::IsLast(napi_env env, napi_callback_info info) /* ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isLast = resultSet->IsLast(); napi_get_boolean(env, isLast, &ctxt->output); @@ -241,7 +244,8 @@ napi_value JsKVStoreResultSet::IsBeforeFirst(napi_env env, napi_callback_info in ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isBeforeFirst = resultSet->IsBeforeFirst(); napi_get_boolean(env, isBeforeFirst, &ctxt->output); @@ -255,7 +259,8 @@ napi_value JsKVStoreResultSet::IsAfterLast(napi_env env, napi_callback_info info ctxt->GetCbInfoSync(env, info); NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isAfterLast = resultSet->IsAfterLast(); napi_get_boolean(env, isAfterLast, &ctxt->output); @@ -270,7 +275,8 @@ napi_value JsKVStoreResultSet::GetEntry(napi_env env, napi_callback_info info) / NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); DistributedKv::Entry entry; - auto& resultSet = reinterpret_cast(ctxt->native)->resultSet_; + auto resultSet = reinterpret_cast(ctxt->native)->GetInstance(); + NAPI_ASSERT(env, resultSet != nullptr, "kvResultSet is nullptr!"); bool isSchema = reinterpret_cast(ctxt->native)->isSchema_; auto status = resultSet->GetEntry(entry); if (status != Status::SUCCESS) { @@ -284,7 +290,13 @@ napi_value JsKVStoreResultSet::GetEntry(napi_env env, napi_callback_info info) / std::shared_ptr JsKVStoreResultSet::Create() { - return KvUtils::ToResultSetBridge(resultSet_); + auto instance = GetInstance(); + if (instance == nullptr) { + ZLOGE("resultSet is null"); + return nullptr; + } + SetInstance(nullptr); + return KvUtils::ToResultSetBridge(instance); } void JsKVStoreResultSet::SetSchema(bool isSchema) diff --git a/frameworks/jskitsimpl/distributedkvstore/src/js_query.cpp b/frameworks/jskitsimpl/distributedkvstore/src/js_query.cpp index f834b5a61e4aad5ef21954026b54ad7ff5579e8c..6a33e6b21c4c6b2316e703a52f0f8729c208dca1 100644 --- a/frameworks/jskitsimpl/distributedkvstore/src/js_query.cpp +++ b/frameworks/jskitsimpl/distributedkvstore/src/js_query.cpp @@ -71,10 +71,12 @@ napi_value JsQuery::New(napi_env env, napi_callback_info info) { auto ctxt = std::make_shared(); ctxt->GetCbInfoSync(env, info); - ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, "The parameter is incorrect."); + ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, + "Parameter error:param query must be object"); JsQuery* query = new (std::nothrow) JsQuery(); - ASSERT_ERR(env, query != nullptr, Status::INVALID_ARGUMENT, "no memory for query."); + ASSERT_ERR(env, query != nullptr, Status::INVALID_ARGUMENT, + "Parameter error:query is null"); auto finalize = [](napi_env env, void* data, void* hint) { ZLOGD("query finalize."); @@ -90,7 +92,7 @@ napi_value JsQuery::Reset(napi_env env, napi_callback_info info) { auto ctxt = std::make_shared(); ctxt->GetCbInfoSync(env, info); - NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); + NAPI_ASSERT(env, ctxt->status == napi_ok, "Reset error"); auto& query = reinterpret_cast(ctxt->native)->query_; query.Reset(); @@ -105,13 +107,14 @@ struct ValueContext : public ContextBase { { auto input = [this, env](size_t argc, napi_value* argv) { // required 2 arguments :: - ASSERT_BUSINESS_ERR(this, argc >= 2, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(this, argc >= 2, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); status = JSUtil::GetValue(env, argv[0], field); ASSERT_BUSINESS_ERR(this, status == napi_ok, Status::INVALID_ARGUMENT, - "The parameters field is incorrect."); + "Parameter error:parameter field type must be string"); status = JSUtil::GetValue(env, argv[1], vv); ASSERT_BUSINESS_ERR(this, status == napi_ok, Status::INVALID_ARGUMENT, - "The parameters value is incorrect."); + "Parameter error:parameter value type must be object"); }; GetCbInfoSync(env, info, input); } @@ -128,7 +131,8 @@ napi_value JsQuery::EqualTo(napi_env env, napi_callback_info info) return nullptr; } ASSERT_NULL(!ctxt->isThrowError, "EqualTo exit"); - ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, "The function EqualTo parameter is incorrect."); + ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, + "Parameter error:equalto params must belong one of string boolean number"); auto& query = reinterpret_cast(ctxt->native)->query_; auto strValue = std::get_if(&ctxt->vv); @@ -155,7 +159,7 @@ napi_value JsQuery::NotEqualTo(napi_env env, napi_callback_info info) ctxt->GetValueSync(env, info); ASSERT_NULL(!ctxt->isThrowError, "NotEqualTo exit"); ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The function NotEqualTo parameter is incorrect."); + "Parameter error:NotEqualTo params must belong one of string boolean number"); auto& query = reinterpret_cast(ctxt->native)->query_; auto strValue = std::get_if(&ctxt->vv); @@ -182,7 +186,7 @@ napi_value JsQuery::GreaterThan(napi_env env, napi_callback_info info) ctxt->GetValueSync(env, info); ASSERT_NULL(!ctxt->isThrowError, "GreaterThan exit"); ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The function GreaterThan parameter is incorrect."); + "The function GreaterThan params must belong one of string boolean number"); auto& query = reinterpret_cast(ctxt->native)->query_; auto strValue = std::get_if(&ctxt->vv); @@ -208,7 +212,8 @@ napi_value JsQuery::LessThan(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); ctxt->GetValueSync(env, info); ASSERT_NULL(!ctxt->isThrowError, "LessThan exit"); - ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, "The function LessThan parameter is incorrect."); + ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, + "The parameter of the LessThan function must be a string or number."); auto& query = reinterpret_cast(ctxt->native)->query_; auto strValue = std::get_if(&ctxt->vv); @@ -235,7 +240,7 @@ napi_value JsQuery::GreaterThanOrEqualTo(napi_env env, napi_callback_info info) ctxt->GetValueSync(env, info); ASSERT_NULL(!ctxt->isThrowError, "GreaterThanOrEqualTo exit"); ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The function GreaterThanOrEqualTo parameter is incorrect."); + "The function GreaterThanOrEqualTo params must belong one of string number"); auto& query = reinterpret_cast(ctxt->native)->query_; auto strValue = std::get_if(&ctxt->vv); @@ -262,7 +267,7 @@ napi_value JsQuery::LessThanOrEqualTo(napi_env env, napi_callback_info info) ctxt->GetValueSync(env, info); ASSERT_NULL(!ctxt->isThrowError, "LessThanOrEqualTo exit"); ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The function LessThanOrEqualTo parameter is incorrect."); + "The function LessThanOrEqualTo params must belong one of string number."); auto& query = reinterpret_cast(ctxt->native)->query_; auto strValue = std::get_if(&ctxt->vv); @@ -288,14 +293,16 @@ napi_value JsQuery::IsNull(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt, &field](size_t argc, napi_value* argv) { // required 1 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = JSUtil::GetValue(env, argv[0], field); ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The parameters field is incorrect."); + "Parameter error:parameters field must be string"); }; ctxt->GetCbInfoSync(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "IsNull exit"); - ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, "The function IsNull parameter is incorrect."); + ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, + "Parameter error:IsNull params must be string"); auto& query = reinterpret_cast(ctxt->native)->query_; query.IsNull(field); @@ -323,10 +330,11 @@ struct NumbersContext : public ContextBase { { auto input = [this, env](size_t argc, napi_value* argv) { // required 2 arguments :: - ASSERT_BUSINESS_ERR(this, argc >= 2, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(this, argc >= 2, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); status = JSUtil::GetValue(env, argv[0], field); ASSERT_BUSINESS_ERR(this, status == napi_ok, Status::INVALID_ARGUMENT, - "The parameters field is incorrect."); + "Parameter error:parameters field must be string"); bool isTypedArray = false; status = napi_is_typedarray(env, argv[1], &isTypedArray); ZLOGD("arg[1] %{public}s a TypedArray", isTypedArray ? "is" : "is not"); @@ -338,7 +346,7 @@ struct NumbersContext : public ContextBase { void* data = nullptr; status = napi_get_typedarray_info(env, argv[1], &type, &length, &data, &buffer, &offset); ASSERT_BUSINESS_ERR(this, status == napi_ok, Status::INVALID_ARGUMENT, - "The parameters number array is incorrect."); + "Parameter error:parameters numberArray must be array"); if (type < napi_uint32_array) { status = JSUtil::GetValue(env, argv[1], intList); innerType = NumberType::NUMBER_INT; @@ -353,11 +361,11 @@ struct NumbersContext : public ContextBase { bool isArray = false; status = napi_is_array(env, argv[1], &isArray); ASSERT_BUSINESS_ERR(this, isArray, Status::INVALID_ARGUMENT, - "The type of parameters number array is incorrect."); + "Parameter error:parameter isArray must be boolean"); ZLOGD("arg[1] %{public}s a Array, treat as array of double.", isTypedArray ? "is" : "is not"); status = JSUtil::GetValue(env, argv[1], doubleList); ASSERT_BUSINESS_ERR(this, status == napi_ok, Status::INVALID_ARGUMENT, - "The parameters number array is incorrect."); + "Parameter error:parameters doubleList must be array"); innerType = NumberType::NUMBER_DOUBLE; } }; @@ -371,7 +379,8 @@ napi_value JsQuery::InNumber(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); ctxt->GetNumberSync(env, info); ASSERT_NULL(!ctxt->isThrowError, "InNumber exit"); - ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, "The function InNumber parameter is incorrect."); + ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, + "Parameter error:InNumber params must be string or array"); auto& query = reinterpret_cast(ctxt->native)->query_; if (ctxt->innerType == NumberType::NUMBER_INT) { @@ -394,17 +403,19 @@ napi_value JsQuery::InString(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt](size_t argc, napi_value* argv) { // required 2 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = JSUtil::GetValue(env, argv[0], ctxt->field); ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The type of field must be string."); + "Parameter error:parameters filed must be string"); ctxt->status = JSUtil::GetValue(env, argv[1], ctxt->valueList); ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The type of valueList must be array."); + "Parameter error:parameters valueList must be stringArray"); }; ctxt->GetCbInfoSync(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "InString exit"); - ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, "The function InString parameter is incorrect."); + ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, + "Parameter error:InString params must be string or array"); auto& query = reinterpret_cast(ctxt->native)->query_; query.In(ctxt->field, ctxt->valueList); @@ -418,7 +429,7 @@ napi_value JsQuery::NotInNumber(napi_env env, napi_callback_info info) ctxt->GetNumberSync(env, info); ASSERT_NULL(!ctxt->isThrowError, "NotInNumber exit"); ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The function InString NotInNumber is incorrect."); + "Parameter error:NotInNumber params must be string or numberArray"); auto& query = reinterpret_cast(ctxt->native)->query_; if (ctxt->innerType == NumberType::NUMBER_INT) { @@ -441,17 +452,19 @@ napi_value JsQuery::NotInString(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt](size_t argc, napi_value* argv) { // required 2 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = JSUtil::GetValue(env, argv[0], ctxt->field); ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The type of field must be string."); + "Parameter error:parameters filed must be string"); ctxt->status = JSUtil::GetValue(env, argv[1], ctxt->valueList); ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The type of valueList must be array."); + "Parameter error:parameters valueList must be array"); }; ctxt->GetCbInfoSync(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "NotInString exit"); - ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, "The function NotInString is incorrect."); + ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, + "Parameter error:NotInString params must be string or stringArray"); auto& query = reinterpret_cast(ctxt->native)->query_; query.NotIn(ctxt->field, ctxt->valueList); @@ -468,17 +481,19 @@ napi_value JsQuery::Like(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt](size_t argc, napi_value* argv) { // required 2 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = JSUtil::GetValue(env, argv[0], ctxt->field); ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The type of field must be string."); + "Parameter error:parameters filed must be string"); ctxt->status = JSUtil::GetValue(env, argv[1], ctxt->value); ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The type of value must be string."); + "Parameter error:parameters value must be string"); }; ctxt->GetCbInfoSync(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "Like exit"); - ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, "The function Like is incorrect."); + ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, + "Parameter error:Like params must be string"); auto& query = reinterpret_cast(ctxt->native)->query_; query.Like(ctxt->field, ctxt->value); @@ -495,17 +510,19 @@ napi_value JsQuery::Unlike(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt](size_t argc, napi_value* argv) { // required 2 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = JSUtil::GetValue(env, argv[0], ctxt->field); ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The type of field must be string."); + "Parameter error:parameters field must be string"); ctxt->status = JSUtil::GetValue(env, argv[1], ctxt->value); ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The type of value must be string."); + "Parameter error:parameters value must be string"); }; ctxt->GetCbInfoSync(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "Unlike exit"); - ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, "The function Unlike is incorrect."); + ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, + "Parameter error:Unlike params must be string"); auto& query = reinterpret_cast(ctxt->native)->query_; query.Unlike(ctxt->field, ctxt->value); @@ -517,7 +534,7 @@ napi_value JsQuery::And(napi_env env, napi_callback_info info) ZLOGD("Query::And()"); auto ctxt = std::make_shared(); ctxt->GetCbInfoSync(env, info); - NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); + NAPI_ASSERT(env, ctxt->status == napi_ok, "And failed"); auto& query = reinterpret_cast(ctxt->native)->query_; query.And(); @@ -529,7 +546,7 @@ napi_value JsQuery::Or(napi_env env, napi_callback_info info) ZLOGD("Query::Or()"); auto ctxt = std::make_shared(); ctxt->GetCbInfoSync(env, info); - NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); + NAPI_ASSERT(env, ctxt->status == napi_ok, "Or failed"); auto& query = reinterpret_cast(ctxt->native)->query_; query.Or(); @@ -543,14 +560,16 @@ napi_value JsQuery::OrderByAsc(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt, &field](size_t argc, napi_value* argv) { // required 1 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = JSUtil::GetValue(env, argv[0], field); ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The type of field must be string."); + "Parameter error:parameters field must be string"); }; ctxt->GetCbInfoSync(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "OrderByAsc exit"); - ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, "The function OrderByAsc is incorrect."); + ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, + "Parameter error:OrderByAsc params must be string"); auto& query = reinterpret_cast(ctxt->native)->query_; query.OrderByAsc(field); @@ -564,14 +583,16 @@ napi_value JsQuery::OrderByDesc(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt, &field](size_t argc, napi_value* argv) { // required 1 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = JSUtil::GetValue(env, argv[0], field); ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The type of field must be string."); + "Parameter error:parameters field must be string"); }; ctxt->GetCbInfoSync(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "OrderByDesc exit"); - ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, "The function OrderByDesc is incorrect."); + ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, + "Parameter error:OrderByDesc params must be string"); auto& query = reinterpret_cast(ctxt->native)->query_; query.OrderByDesc(field); @@ -587,15 +608,19 @@ napi_value JsQuery::Limit(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt](size_t argc, napi_value* argv) { // required 2 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = napi_get_value_int32(env, argv[0], &ctxt->number); - ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, "The type of number must be int."); + ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, + "Parameter error:parameters number must be int"); ctxt->status = napi_get_value_int32(env, argv[1], &ctxt->offset); - ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, "The type of offset must be int."); + ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, + "Parameter error:parameters offset must be int"); }; ctxt->GetCbInfoSync(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "Limit exit"); - ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, "The function Limit is incorrect."); + ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, + "Parameter error:Limit params must be number"); auto& query = reinterpret_cast(ctxt->native)->query_; query.Limit(ctxt->number, ctxt->offset); @@ -609,14 +634,16 @@ napi_value JsQuery::IsNotNull(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt, &field](size_t argc, napi_value* argv) { // required 1 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = JSUtil::GetValue(env, argv[0], field); ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The type of field must be string."); + "Parameter error:parameters field must be string"); }; ctxt->GetCbInfoSync(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "IsNotNull exit"); - ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, "The function IsNotNull is incorrect."); + ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, + "Parameter error:IsNotNull params must be string"); auto& query = reinterpret_cast(ctxt->native)->query_; query.IsNotNull(field); @@ -628,7 +655,7 @@ napi_value JsQuery::BeginGroup(napi_env env, napi_callback_info info) ZLOGD("Query::BeginGroup()"); auto ctxt = std::make_shared(); ctxt->GetCbInfoSync(env, info); - NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); + NAPI_ASSERT(env, ctxt->status == napi_ok, "BeginGroup failed"); auto& query = reinterpret_cast(ctxt->native)->query_; query.BeginGroup(); @@ -640,7 +667,7 @@ napi_value JsQuery::EndGroup(napi_env env, napi_callback_info info) ZLOGD("Query::EndGroup()"); auto ctxt = std::make_shared(); ctxt->GetCbInfoSync(env, info); - NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); + NAPI_ASSERT(env, ctxt->status == napi_ok, "EndGroup failed"); auto& query = reinterpret_cast(ctxt->native)->query_; query.EndGroup(); @@ -653,14 +680,16 @@ napi_value JsQuery::PrefixKey(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt, &prefix](size_t argc, napi_value* argv) { // required 1 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = JSUtil::GetValue(env, argv[0], prefix); ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The type of prefix must be string."); + "Parameter error:parameters prefix must be string"); }; ctxt->GetCbInfoSync(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "PrefixKey exit"); - ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, "The function PrefixKey is incorrect."); + ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, + "Parameter error:PrefixKey params must be string"); auto& query = reinterpret_cast(ctxt->native)->query_; query.KeyPrefix(prefix); @@ -673,14 +702,16 @@ napi_value JsQuery::SetSuggestIndex(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt, &suggestIndex](size_t argc, napi_value* argv) { // required 1 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = JSUtil::GetValue(env, argv[0], suggestIndex); ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The type of suggestIndex must be string."); + "Parameter error:parameters suggestIndex must be string"); }; ctxt->GetCbInfoSync(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "SetSuggestIndex exit"); - ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, "The function SetSuggestIndex is incorrect."); + ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, + "Parameter error:SetSuggestIndex params must be string"); auto& query = reinterpret_cast(ctxt->native)->query_; query.SetSuggestIndex(suggestIndex); @@ -693,14 +724,16 @@ napi_value JsQuery::DeviceId(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt, &deviceId](size_t argc, napi_value* argv) { // required 1 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); - ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The type of deviceId must be string."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = JSUtil::GetValue(env, argv[0], deviceId); + ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, + "Parameter error:deviceId must be string"); }; ctxt->GetCbInfoSync(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "DeviceId exit"); - ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, "The function DeviceId is incorrect."); + ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, + "Parameter error:DeviceId params must be string"); auto& query = reinterpret_cast(ctxt->native)->query_; query.DeviceId(deviceId); @@ -712,7 +745,7 @@ napi_value JsQuery::GetSqlLike(napi_env env, napi_callback_info info) { auto ctxt = std::make_shared(); ctxt->GetCbInfoSync(env, info); - NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!"); + NAPI_ASSERT(env, ctxt->status == napi_ok, "GetSqlLike failed"); auto& query = reinterpret_cast(ctxt->native)->query_; JSUtil::SetValue(env, query.ToString(), ctxt->output); diff --git a/frameworks/jskitsimpl/distributedkvstore/src/js_schema.cpp b/frameworks/jskitsimpl/distributedkvstore/src/js_schema.cpp index 26caf0b134d25220a84ff3f3d89a637fbf7936f9..177d8c19c3dc34629d8f277158fe84b7c916c79d 100644 --- a/frameworks/jskitsimpl/distributedkvstore/src/js_schema.cpp +++ b/frameworks/jskitsimpl/distributedkvstore/src/js_schema.cpp @@ -25,13 +25,14 @@ using namespace OHOS::DistributedKv; using json = nlohmann::json; namespace OHOS::DistributedKVStore { -static std::string LABEL = "Schema"; -static std::string SCHEMA_VERSION = "SCHEMA_VERSION"; -static std::string SCHEMA_MODE = "SCHEMA_MODE"; -static std::string SCHEMA_DEFINE = "SCHEMA_DEFINE"; -static std::string SCHEMA_INDEXES = "SCHEMA_INDEXES"; -static std::string SCHEMA_SKIPSIZE = "SCHEMA_SKIPSIZE"; -static std::string DEFAULT_SCHEMA_VERSION = "1.0"; +static constexpr const char* SCHEMA_VERSION = "SCHEMA_VERSION"; +static constexpr const char* SCHEMA_MODE = "SCHEMA_MODE"; +static constexpr const char* SCHEMA_DEFINE = "SCHEMA_DEFINE"; +static constexpr const char* SCHEMA_INDEXES = "SCHEMA_INDEXES"; +static constexpr const char* SCHEMA_SKIPSIZE = "SCHEMA_SKIPSIZE"; +static constexpr const char* DEFAULT_SCHEMA_VERSION = "1.0"; +static constexpr const char* SCHEMA_STRICT = "STRICT"; +static constexpr const char* SCHEMA_COMPATIBLE = "COMPATIBLE"; JsSchema::JsSchema(napi_env env) : env_(env) @@ -72,7 +73,7 @@ napi_value JsSchema::New(napi_env env, napi_callback_info info) NAPI_ASSERT(env, schema !=nullptr, "no memory for schema"); auto finalize = [](napi_env env, void* data, void* hint) { - ZLOGD("Schema finalize."); + ZLOGI("Schema finalize."); auto* schema = reinterpret_cast(data); ASSERT_VOID(schema != nullptr, "schema is null!"); delete schema; @@ -215,7 +216,7 @@ napi_value JsSchema::SetIndexes(napi_env env, napi_callback_info info) auto input = [env, ctxt, &indexes](size_t argc, napi_value* argv) { // required 1 arguments :: ASSERT_ARGS(ctxt, argc == 1, "invalid arguments!"); - ctxt->status = JSUtil::GetValue(env, argv[0], indexes); + ctxt->status = JSUtil::GetValue(env, argv[0], indexes, false); ASSERT_STATUS(ctxt, "invalid arg[0], i.e. invalid indexes!"); }; ctxt->GetCbInfoSync(env, info, input); @@ -234,7 +235,7 @@ std::string JsSchema::Dump() } json js = { { SCHEMA_VERSION, DEFAULT_SCHEMA_VERSION }, - { SCHEMA_MODE, (mode_ == SCHEMA_MODE_STRICT) ? "STRICT" : "COMPATIBLE" }, + { SCHEMA_MODE, (mode_ == SCHEMA_MODE_STRICT) ? SCHEMA_STRICT : SCHEMA_COMPATIBLE }, { SCHEMA_DEFINE, rootNode_->GetValueForJson() }, { SCHEMA_INDEXES, jsIndexes }, { SCHEMA_SKIPSIZE, skip_ }, diff --git a/frameworks/jskitsimpl/distributedkvstore/src/js_single_kv_store.cpp b/frameworks/jskitsimpl/distributedkvstore/src/js_single_kv_store.cpp index 5a0017b62b01b44437a8df5b8b7442913af43ff3..1983175e350da06e52703af65c819c4403fa8fd0 100644 --- a/frameworks/jskitsimpl/distributedkvstore/src/js_single_kv_store.cpp +++ b/frameworks/jskitsimpl/distributedkvstore/src/js_single_kv_store.cpp @@ -16,7 +16,6 @@ #include "js_single_kv_store.h" #include "js_util.h" #include "js_kv_store_resultset.h" -#include "datashare_predicates.h" #include "js_query.h" #include "log_print.h" #include "napi_queue.h" @@ -24,9 +23,8 @@ #include "kv_utils.h" using namespace OHOS::DistributedKv; -using namespace OHOS::DataShare; namespace OHOS::DistributedKVStore { - +inline static uint8_t UNVALID_SUBSCRIBE_TYPE = 255; std::map JsSingleKVStore::onEventHandlers_ = { { "dataChange", JsSingleKVStore::OnDataChange }, { "syncComplete", JsSingleKVStore::OnSyncComplete } @@ -51,7 +49,16 @@ static bool ValidSubscribeType(uint8_t type) static SubscribeType ToSubscribeType(uint8_t type) { - return static_cast(type + 1); + switch (type) { + case 0: // 0 means SUBSCRIBE_TYPE_LOCAL + return SubscribeType::SUBSCRIBE_TYPE_LOCAL; + case 1: // 1 means SUBSCRIBE_TYPE_REMOTE + return SubscribeType::SUBSCRIBE_TYPE_REMOTE; + case 2: // 2 means SUBSCRIBE_TYPE_ALL + return SubscribeType::SUBSCRIBE_TYPE_ALL; + default: + return static_cast(UNVALID_SUBSCRIBE_TYPE); + } } JsSingleKVStore::JsSingleKVStore(const std::string& storeId) @@ -91,6 +98,10 @@ void JsSingleKVStore::SetSchemaInfo(bool isSchemaStore) bool JsSingleKVStore::IsSystemApp() const { + if (param_ == nullptr) { + ZLOGE("param_ is nullptr"); + return false; + } return param_->isSystemApp; } @@ -168,16 +179,15 @@ napi_value JsSingleKVStore::Put(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); ctxt->GetCbInfo(env, info, [env, ctxt](size_t argc, napi_value* argv) { // required 2 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = JSUtil::GetValue(env, argv[0], ctxt->key); - ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, "The type of key must be string."); + ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, + "Parameter error:parameters key must be string"); ctxt->status = JSUtil::GetValue(env, argv[1], ctxt->value); if (ctxt->status != napi_ok) { ctxt->isThrowError = true; - napi_valuetype ntype = napi_undefined; - napi_typeof(env, argv[0], &ntype); - auto type = valueTypeToString_.find(ntype); - ThrowNapiError(env, Status::INVALID_ARGUMENT, "The type of value must be " + type->second); + ThrowNapiError(env, Status::INVALID_ARGUMENT, "Parameter error: invalid value type"); return; } }); @@ -189,6 +199,9 @@ napi_value JsSingleKVStore::Put(napi_env env, napi_callback_info info) auto &kvStore = reinterpret_cast(ctxt->native)->kvStore_; DistributedKv::Value value = isSchemaStore ? DistributedKv::Blob(std::get(ctxt->value)) : JSUtil::VariantValue2Blob(ctxt->value); + if (kvStore == nullptr) { + return; + } Status status = kvStore->Put(key, value); ZLOGD("kvStore->Put return %{public}d", status); ctxt->status = (GenerateNapiError(status, ctxt->jsCode, ctxt->error) == Status::SUCCESS) ? @@ -214,20 +227,21 @@ napi_value JsSingleKVStore::Delete(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); ctxt->GetCbInfo(env, info, [env, ctxt](size_t argc, napi_value* argv) { // required 1 arguments :: || - ASSERT_BUSINESS_ERR(ctxt, argc == 1, Status::INVALID_ARGUMENT, "The number of parameter is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc == 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->type = napi_undefined; ctxt->status = napi_typeof(env, argv[0], &(ctxt->type)); if (ctxt->type == napi_string) { ctxt->status = JSUtil::GetValue(env, argv[0], ctxt->key); ZLOGD("kvStore->Delete %{public}.6s status:%{public}d", ctxt->key.c_str(), ctxt->status); ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The type of key must be string."); + "Parameter error:parameters key must be string"); } else if (ctxt->type == napi_object) { JSUtil::StatusMsg statusMsg = JSUtil::GetValue(env, argv[0], ctxt->keys); ctxt->status = statusMsg.status; ZLOGD("kvStore->Delete status:%{public}d", ctxt->status); ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The parameters predicates is incorrect."); + "Parameter error:please check predicates type"); ASSERT_PERMISSION_ERR(ctxt, !JSUtil::IsSystemApi(statusMsg.jsApiType) || reinterpret_cast(ctxt->native)->IsSystemApp(), Status::PERMISSION_DENIED, ""); @@ -263,13 +277,14 @@ napi_value JsSingleKVStore::OnEvent(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt](size_t argc, napi_value* argv) { // required 2 arguments :: [...] - ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); std::string event; ctxt->status = JSUtil::GetValue(env, argv[0], event); ZLOGI("subscribe to event:%{public}s", event.c_str()); auto handle = onEventHandlers_.find(event); ASSERT_BUSINESS_ERR(ctxt, handle != onEventHandlers_.end(), Status::INVALID_ARGUMENT, - "The type of parameters event is incorrect."); + "Parameter error:onevent type must belong dataChange or syncComplete"); // shift 1 argument, for JsSingleKVStore::Exec. handle->second(env, argc - 1, &argv[1], ctxt); }; @@ -292,13 +307,14 @@ napi_value JsSingleKVStore::OffEvent(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt](size_t argc, napi_value* argv) { // required 1 arguments :: [callback] - ASSERT_BUSINESS_ERR(ctxt, argc != 0, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc != 0, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); std::string event; ctxt->status = JSUtil::GetValue(env, argv[0], event); ZLOGI("unsubscribe to event:%{public}s", event.c_str()); auto handle = offEventHandlers_.find(event); ASSERT_BUSINESS_ERR(ctxt, handle != offEventHandlers_.end(), Status::INVALID_ARGUMENT, - "The type of parameters event is incorrect."); + "Parameter error:offevent type must belong dataChange or syncComplete"); // shift 1 argument, for JsSingleKVStore::Exec. handle->second(env, argc - 1, &argv[1], ctxt); }; @@ -327,12 +343,13 @@ napi_value JsSingleKVStore::PutBatch(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); ctxt->GetCbInfo(env, info, [env, ctxt](size_t argc, napi_value *argv) { // required 1 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); auto isSchemaStore = reinterpret_cast(ctxt->native)->IsSchemaStore(); JSUtil::StatusMsg statusMsg = JSUtil::GetValue(env, argv[0], ctxt->entries, isSchemaStore); ctxt->status = statusMsg.status; ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The type of entries is incorrect."); + "Parameter error:params entries type must be one of string,number,boolean,array"); ASSERT_PERMISSION_ERR(ctxt, !JSUtil::IsSystemApi(statusMsg.jsApiType) || reinterpret_cast(ctxt->native)->IsSystemApp(), Status::PERMISSION_DENIED, ""); @@ -364,9 +381,11 @@ napi_value JsSingleKVStore::DeleteBatch(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt](size_t argc, napi_value* argv) { // required 1 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = JSUtil::GetValue(env, argv[0], ctxt->keys); - ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, "The type of keys is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, + "Parameter error:keys verification must be array"); }; ctxt->GetCbInfo(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "DeleteBatch exit"); @@ -466,10 +485,11 @@ napi_value JsSingleKVStore::EnableSync(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt](size_t argc, napi_value* argv) { // required 1 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = napi_get_value_bool(env, argv[0], &ctxt->enable); ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The parameters of enable is incorrect."); + "Parameter error:enable must be boolean"); }; ctxt->GetCbInfo(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "EnableSync exit"); @@ -500,13 +520,14 @@ napi_value JsSingleKVStore::SetSyncRange(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt](size_t argc, napi_value* argv) { // required 2 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = JSUtil::GetValue(env, argv[0], ctxt->localLabels); ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The type of parameter localLabels is string array."); + "Parameter error:parameters localLabels must be array"); ctxt->status = JSUtil::GetValue(env, argv[1], ctxt->remoteSupportLabels); ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The type of parameter remoteSupportLabels is string array."); + "Parameter error:parameters remoteSupportLabels must be array"); }; ctxt->GetCbInfo(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "SetSyncRange exit"); @@ -536,10 +557,13 @@ napi_value JsSingleKVStore::Backup(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt](size_t argc, napi_value* argv) { // required 1 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = JSUtil::GetValue(env, argv[0], ctxt->file); ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The type of parameter file is string."); + "Parameter error:param file type must be string"); + ASSERT_BUSINESS_ERR(ctxt, (ctxt->file.size() != 0 && ctxt->file != AUTO_BACKUP_NAME), Status::INVALID_ARGUMENT, + "Parameter error:empty file and filename not allow autoBackup"); }; ctxt->GetCbInfo(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "Backup exit"); @@ -569,10 +593,11 @@ napi_value JsSingleKVStore::Restore(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt](size_t argc, napi_value* argv) { // required 1 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = JSUtil::GetValue(env, argv[0], ctxt->file); ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The type of parameter file is string."); + "Parameter error:get file failed. params type must be string"); }; ctxt->GetCbInfo(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "Restore exit"); @@ -603,10 +628,11 @@ napi_value JsSingleKVStore::DeleteBackup(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt](size_t argc, napi_value* argv) { // required 1 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = JSUtil::GetValue(env, argv[0], ctxt->files); ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The type of parameter file is string."); + "Parameter error:get file failed, params files must be stringArray"); }; ctxt->GetCbInfo(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "DeleteBackup exit"); @@ -634,18 +660,19 @@ napi_value JsSingleKVStore::DeleteBackup(napi_env env, napi_callback_info info) void JsSingleKVStore::OnDataChange(napi_env env, size_t argc, napi_value* argv, std::shared_ptr ctxt) { // required 2 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); int32_t type = SUBSCRIBE_COUNT; ctxt->status = napi_get_value_int32(env, argv[0], &type); ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, ""); ASSERT_BUSINESS_ERR(ctxt, ValidSubscribeType(type), Status::INVALID_ARGUMENT, - "The type of parameter event is incorrect."); + "Parameter error:parameter event type not exist"); napi_valuetype valueType = napi_undefined; ctxt->status = napi_typeof(env, argv[1], &valueType); ASSERT_BUSINESS_ERR(ctxt, (ctxt->status == napi_ok) && (valueType == napi_function), Status::INVALID_ARGUMENT, - "The type of parameter Callback is incorrect."); + "Parameter error:parameter Callback must be function"); ZLOGI("subscribe data change type %{public}d", type); auto proxy = reinterpret_cast(ctxt->native); @@ -672,13 +699,14 @@ void JsSingleKVStore::OnDataChange(napi_env env, size_t argc, napi_value* argv, void JsSingleKVStore::OffDataChange(napi_env env, size_t argc, napi_value* argv, std::shared_ptr ctxt) { // required 1 arguments :: [callback] - ASSERT_BUSINESS_ERR(ctxt, argc <= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc <= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); // have 1 arguments :: have the callback if (argc == 1) { napi_valuetype valueType = napi_undefined; ctxt->status = napi_typeof(env, argv[0], &valueType); ASSERT_BUSINESS_ERR(ctxt, (ctxt->status == napi_ok) && (valueType == napi_function), Status::INVALID_ARGUMENT, - "The type of parameter Callback is incorrect."); + "Parameter error:parameter Callback must be function"); } ZLOGI("unsubscribe dataChange, %{public}s specified observer.", (argc == 0) ? "without": "with"); @@ -721,15 +749,17 @@ void JsSingleKVStore::OffDataChange(napi_env env, size_t argc, napi_value* argv, void JsSingleKVStore::OnSyncComplete(napi_env env, size_t argc, napi_value* argv, std::shared_ptr ctxt) { // required 1 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); napi_valuetype valueType = napi_undefined; ctxt->status = napi_typeof(env, argv[0], &valueType); ASSERT_BUSINESS_ERR(ctxt, (ctxt->status == napi_ok) && (valueType == napi_function), Status::INVALID_ARGUMENT, - "The type of parameter Callback is incorrect."); + "Parameter error:params valueType must be function"); auto proxy = reinterpret_cast(ctxt->native); ctxt->status = proxy->RegisterSyncCallback(std::make_shared(proxy->uvQueue_, argv[0])); - ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, "RegisterSyncCallback failed!"); + ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, + "Parameter error:RegisterSyncCallback params must be function"); } /* @@ -746,7 +776,7 @@ void JsSingleKVStore::OffSyncComplete(napi_env env, size_t argc, napi_value* arg napi_valuetype valueType = napi_undefined; ctxt->status = napi_typeof(env, argv[0], &valueType); ASSERT_BUSINESS_ERR(ctxt, (ctxt->status == napi_ok) && (valueType == napi_function), Status::INVALID_ARGUMENT, - "The type of parameter Callback is incorrect."); + "Parameter error:parameter types must be function"); std::lock_guard lck(proxy->listMutex_); auto it = proxy->syncObservers_.begin(); while (it != proxy->syncObservers_.end()) { @@ -755,6 +785,7 @@ void JsSingleKVStore::OffSyncComplete(napi_env env, size_t argc, napi_value* arg proxy->syncObservers_.erase(it); break; } + ++it; } ctxt->status = napi_ok; } @@ -762,7 +793,8 @@ void JsSingleKVStore::OffSyncComplete(napi_env env, size_t argc, napi_value* arg if (argc == 0 || proxy->syncObservers_.empty()) { ctxt->status = proxy->UnRegisterSyncCallback(); } - ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, "UnRegisterSyncCallback failed!"); + ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, + "Parameter error:params type must be function"); } /* @@ -860,9 +892,11 @@ napi_value JsSingleKVStore::Get(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt](size_t argc, napi_value* argv) { // required 1 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = JSUtil::GetValue(env, argv[0], ctxt->key); - ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, "The type of key must be string."); + ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, + "Parameter error:params key must be string and not allow empty"); }; ctxt->GetCbInfo(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "Get exit"); @@ -872,6 +906,9 @@ napi_value JsSingleKVStore::Get(napi_env env, napi_callback_info info) OHOS::DistributedKv::Key key(ctxt->key); OHOS::DistributedKv::Value value; auto kvStore = reinterpret_cast(ctxt->native)->GetKvStorePtr(); + if (kvStore == nullptr) { + return; + } bool isSchemaStore = reinterpret_cast(ctxt->native)->IsSchemaStore(); Status status = kvStore->Get(key, value); ZLOGD("kvStore->Get return %{public}d", status); @@ -897,14 +934,14 @@ static JSUtil::StatusMsg GetVariantArgs(napi_env env, size_t argc, napi_value* a napi_valuetype type = napi_undefined; JSUtil::StatusMsg statusMsg = napi_typeof(env, argv[0], &type); if (statusMsg != napi_ok || (type != napi_string && type != napi_object)) { - va.errMsg = "The type of parameters keyPrefix/query is incorrect."; + va.errMsg = "Parameter error:parameters keyPrefix/query must be string or object"; return statusMsg.status != napi_ok ? statusMsg.status : napi_invalid_arg; } if (type == napi_string) { std::string keyPrefix; JSUtil::GetValue(env, argv[0], keyPrefix); if (keyPrefix.empty()) { - va.errMsg = "The type of parameters keyPrefix is incorrect."; + va.errMsg = "Parameter error:parameters keyPrefix must be string"; return napi_invalid_arg; } va.dataQuery.KeyPrefix(keyPrefix); @@ -915,7 +952,7 @@ static JSUtil::StatusMsg GetVariantArgs(napi_env env, size_t argc, napi_value* a JsQuery *jsQuery = nullptr; statusMsg = JSUtil::Unwrap(env, argv[0], reinterpret_cast(&jsQuery), JsQuery::Constructor(env)); if (jsQuery == nullptr) { - va.errMsg = "The parameters query is incorrect."; + va.errMsg = "Parameter error:parameters query is must be object"; return napi_invalid_arg; } va.dataQuery = jsQuery->GetDataQuery(); @@ -945,7 +982,8 @@ napi_value JsSingleKVStore::GetEntries(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt](size_t argc, napi_value* argv) { // required 1 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = GetVariantArgs(env, argc, argv, ctxt->va); ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, ctxt->va.errMsg); }; @@ -954,6 +992,9 @@ napi_value JsSingleKVStore::GetEntries(napi_env env, napi_callback_info info) auto execute = [ctxt]() { auto kvStore = reinterpret_cast(ctxt->native)->GetKvStorePtr(); + if (kvStore == nullptr) { + return; + } Status status = kvStore->GetEntries(ctxt->va.dataQuery, ctxt->entries); ZLOGD("kvStore->GetEntries() return %{public}d", status); ctxt->status = (GenerateNapiError(status, ctxt->jsCode, ctxt->error) == Status::SUCCESS) ? @@ -985,7 +1026,8 @@ napi_value JsSingleKVStore::GetResultSet(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt](size_t argc, napi_value* argv) { // required 1 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); JSUtil::StatusMsg statusMsg = GetVariantArgs(env, argc, argv, ctxt->va); ctxt->status = statusMsg.status; ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, ctxt->va.errMsg); @@ -995,7 +1037,7 @@ napi_value JsSingleKVStore::GetResultSet(napi_env env, napi_callback_info info) ctxt->ref = JSUtil::NewWithRef(env, 0, nullptr, reinterpret_cast(&ctxt->resultSet), JsKVStoreResultSet::Constructor(env)); ASSERT_BUSINESS_ERR(ctxt, ctxt->resultSet != nullptr, Status::INVALID_ARGUMENT, - "KVStoreResultSet::New failed!"); + "Parameter error:resultSet nullptr"); }; ctxt->GetCbInfo(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "GetResultSet exit"); @@ -1003,12 +1045,15 @@ napi_value JsSingleKVStore::GetResultSet(napi_env env, napi_callback_info info) auto execute = [ctxt]() { std::shared_ptr kvResultSet; auto kvStore = reinterpret_cast(ctxt->native)->GetKvStorePtr(); + if (kvStore == nullptr) { + return; + } Status status = kvStore->GetResultSet(ctxt->va.dataQuery, kvResultSet); ZLOGD("kvStore->GetResultSet() return %{public}d", status); ctxt->status = (GenerateNapiError(status, ctxt->jsCode, ctxt->error) == Status::SUCCESS) ? napi_ok : napi_generic_failure; - ctxt->resultSet->SetKvStoreResultSetPtr(kvResultSet); + ctxt->resultSet->SetInstance(kvResultSet); bool isSchema = reinterpret_cast(ctxt->native)->IsSchemaStore(); ctxt->resultSet->SetSchema(isSchema); }; @@ -1033,22 +1078,27 @@ napi_value JsSingleKVStore::CloseResultSet(napi_env env, napi_callback_info info auto ctxt = std::make_shared(); auto input = [env, ctxt](size_t argc, napi_value* argv) { // required 1 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); napi_valuetype type = napi_undefined; ctxt->status = napi_typeof(env, argv[0], &type); ASSERT_BUSINESS_ERR(ctxt, type == napi_object, Status::INVALID_ARGUMENT, - "The type of parameters resultSet is incorrect."); + "Parameter error:Parameters type must be object"); ctxt->status = JSUtil::Unwrap(env, argv[0], reinterpret_cast(&ctxt->resultSet), JsKVStoreResultSet::Constructor(env)); ASSERT_BUSINESS_ERR(ctxt, ctxt->resultSet != nullptr, Status::INVALID_ARGUMENT, - "The parameters resultSet is incorrect."); + "Parameter error:resultSet nullptr"); }; ctxt->GetCbInfo(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "CloseResultSet exit"); auto execute = [ctxt]() { auto kvStore = reinterpret_cast(ctxt->native)->GetKvStorePtr(); - auto resultSet = ctxt->resultSet->GetKvStoreResultSetPtr(); + if (kvStore == nullptr) { + return; + } + auto resultSet = ctxt->resultSet->GetInstance(); + ctxt->resultSet->SetInstance(nullptr); Status status = kvStore->CloseResultSet(resultSet); ZLOGD("kvStore->CloseResultSet return %{public}d", status); ctxt->status = (GenerateNapiError(status, ctxt->jsCode, ctxt->error) == Status::SUCCESS) ? @@ -1071,20 +1121,24 @@ napi_value JsSingleKVStore::GetResultSize(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt](size_t argc, napi_value* argv) { // required 1 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); napi_valuetype type = napi_undefined; ctxt->status = napi_typeof(env, argv[0], &type); ASSERT_BUSINESS_ERR(ctxt, type == napi_object, Status::INVALID_ARGUMENT, - "The type of parameters query is incorrect."); + "Parameter error:Parameters type must be object"); ctxt->status = JSUtil::Unwrap(env, argv[0], reinterpret_cast(&ctxt->query), JsQuery::Constructor(env)); ASSERT_BUSINESS_ERR(ctxt, ctxt->query != nullptr, Status::INVALID_ARGUMENT, - "The parameters query is incorrect."); + "Parameter error:query nullptr"); }; ctxt->GetCbInfo(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "GetResultSize exit"); auto execute = [ctxt]() { auto kvStore = reinterpret_cast(ctxt->native)->GetKvStorePtr(); + if (kvStore == nullptr) { + return; + } auto query = ctxt->query->GetDataQuery(); Status status = kvStore->GetCount(query, ctxt->resultSize); ZLOGD("kvStore->GetCount() return %{public}d", status); @@ -1111,16 +1165,20 @@ napi_value JsSingleKVStore::RemoveDeviceData(napi_env env, napi_callback_info in auto ctxt = std::make_shared(); auto input = [env, ctxt](size_t argc, napi_value* argv) { // required 1 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = JSUtil::GetValue(env, argv[0], ctxt->deviceId); ASSERT_BUSINESS_ERR(ctxt, (!ctxt->deviceId.empty()) && (ctxt->status == napi_ok), Status::INVALID_ARGUMENT, - "The parameters deviceId is incorrect."); + "Parameter error:deviceId empty"); }; ctxt->GetCbInfo(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "RemoveDeviceData exit"); auto execute = [ctxt]() { auto kvStore = reinterpret_cast(ctxt->native)->GetKvStorePtr(); + if (kvStore == nullptr) { + return; + } Status status = kvStore->RemoveDeviceData(ctxt->deviceId); ZLOGD("kvStore->RemoveDeviceData return %{public}d", status); ctxt->status = (GenerateNapiError(status, ctxt->jsCode, ctxt->error) == Status::SUCCESS) ? @@ -1140,39 +1198,40 @@ struct SyncContext : public ContextBase { { auto input = [env, this](size_t argc, napi_value* argv) { // required 3 arguments :: [allowedDelayMs] - ASSERT_BUSINESS_ERR(this, argc >= 2, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(this, argc >= 2, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); this->status = JSUtil::GetValue(env, argv[0], this->deviceIdList); ASSERT_BUSINESS_ERR(this, this->status == napi_ok, Status::INVALID_ARGUMENT, - "The deviceIdList parameters is incorrect."); + "Parameter error:params deviceIdList must be array"); napi_typeof(env, argv[1], &this->type); if (this->type == napi_object) { this->status = JSUtil::Unwrap(env, argv[1], reinterpret_cast(&this->query), JsQuery::Constructor(env)); ASSERT_BUSINESS_ERR(this, this->status == napi_ok, Status::INVALID_ARGUMENT, - "The parameters query is incorrect."); + "Parameter error:params type must be query"); this->status = JSUtil::GetValue(env, argv[2], this->mode); ASSERT_BUSINESS_ERR(this, this->status == napi_ok, Status::INVALID_ARGUMENT, - "The parameters mode is incorrect."); + "Parameter error:params mode must be int"); if (argc == 4) { this->status = JSUtil::GetValue(env, argv[3], this->allowedDelayMs); ASSERT_BUSINESS_ERR(this, (this->status == napi_ok || JSUtil::IsNull(env, argv[3])), - Status::INVALID_ARGUMENT, "The parameters delay is incorrect."); + Status::INVALID_ARGUMENT, "Parameter error:params delay must be int"); this->status = napi_ok; } } if (this->type == napi_number) { this->status = JSUtil::GetValue(env, argv[1], this->mode); ASSERT_BUSINESS_ERR(this, this->status == napi_ok, Status::INVALID_ARGUMENT, - "The parameters mode is incorrect."); + "Parameter error:params mode must be int"); if (argc == 3) { this->status = JSUtil::GetValue(env, argv[2], this->allowedDelayMs); ASSERT_BUSINESS_ERR(this, (this->status == napi_ok || JSUtil::IsNull(env, argv[2])), - Status::INVALID_ARGUMENT, "The parameters delay is incorrect."); + Status::INVALID_ARGUMENT, "Parameter error:params delay must be int"); this->status = napi_ok; } } ASSERT_BUSINESS_ERR(this, (this->mode <= uint32_t(SyncMode::PUSH_PULL)) && (this->status == napi_ok), - Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + Status::INVALID_ARGUMENT, "Parameter error:Parameters mode must be int"); }; ContextBase::GetCbInfoSync(env, info, input); } @@ -1191,10 +1250,14 @@ napi_value JsSingleKVStore::Sync(napi_env env, napi_callback_info info) (int)ctxt->deviceIdList.size(), ctxt->mode, ctxt->allowedDelayMs); auto kvStore = reinterpret_cast(ctxt->native)->GetKvStorePtr(); + if (kvStore == nullptr) { + return nullptr; + } Status status = Status::INVALID_ARGUMENT; if (ctxt->type == napi_object) { auto query = ctxt->query->GetDataQuery(); - status = kvStore->Sync(ctxt->deviceIdList, static_cast(ctxt->mode), query, nullptr); + status = kvStore->Sync(ctxt->deviceIdList, static_cast(ctxt->mode), query, + nullptr, ctxt->allowedDelayMs); } if (ctxt->type == napi_number) { status = kvStore->Sync(ctxt->deviceIdList, static_cast(ctxt->mode), ctxt->allowedDelayMs); @@ -1217,16 +1280,20 @@ napi_value JsSingleKVStore::SetSyncParam(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt](size_t argc, napi_value* argv) { // required 1 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = JSUtil::GetValue(env, argv[0], ctxt->allowedDelayMs); ASSERT_BUSINESS_ERR(ctxt, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, - "The parameters allowedDelayMs is incorrect."); + "Parameter error:Parameters delay must be int"); }; ctxt->GetCbInfo(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "SetSyncParam exit"); auto execute = [ctxt]() { auto kvStore = reinterpret_cast(ctxt->native)->GetKvStorePtr(); + if (kvStore == nullptr) { + return; + } KvSyncParam syncParam { ctxt->allowedDelayMs }; Status status = kvStore->SetSyncParam(syncParam); ZLOGD("kvStore->SetSyncParam return %{public}d", status); @@ -1251,6 +1318,9 @@ napi_value JsSingleKVStore::GetSecurityLevel(napi_env env, napi_callback_info in auto execute = [ctxt]() { auto kvStore = reinterpret_cast(ctxt->native)->GetKvStorePtr(); + if (kvStore == nullptr) { + return; + } Status status = kvStore->GetSecurityLevel(ctxt->securityLevel); ZLOGD("kvStore->GetSecurityLevel return %{public}d", status); ctxt->status = (GenerateNapiError(status, ctxt->jsCode, ctxt->error) == Status::SUCCESS) ? @@ -1270,17 +1340,20 @@ napi_value JsSingleKVStore::New(napi_env env, napi_callback_info info) auto ctxt = std::make_shared(); auto input = [env, ctxt, &storeId](size_t argc, napi_value* argv) { // required 2 arguments :: - ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, "The number of parameters is incorrect."); + ASSERT_BUSINESS_ERR(ctxt, argc >= 2, Status::INVALID_ARGUMENT, + "Parameter error:Mandatory parameters are left unspecified"); ctxt->status = JSUtil::GetValue(env, argv[0], storeId); ASSERT_BUSINESS_ERR(ctxt, (ctxt->status == napi_ok) && !storeId.empty(), Status::INVALID_ARGUMENT, - "The type of storeId must be string."); + "Parameter error:Parameters storeId must be string"); }; ctxt->GetCbInfoSync(env, info, input); ASSERT_NULL(!ctxt->isThrowError, "SingleKVStore new exit"); - ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, "no memory for kvStore"); + ASSERT_ERR(env, ctxt->status == napi_ok, Status::INVALID_ARGUMENT, + "Parameter error:get params failed"); JsSingleKVStore* kvStore = new (std::nothrow) JsSingleKVStore(storeId); - ASSERT_ERR(env, kvStore != nullptr, Status::INVALID_ARGUMENT, "no memory for kvStore"); + ASSERT_ERR(env, kvStore != nullptr, Status::INVALID_ARGUMENT, + "Parameter error:kvStore nullptr"); auto finalize = [](napi_env env, void* data, void* hint) { ZLOGI("singleKVStore finalize."); diff --git a/frameworks/jskitsimpl/distributedkvstore/src/js_util.cpp b/frameworks/jskitsimpl/distributedkvstore/src/js_util.cpp index c219469ee04b0e78c700488cd47bb1f3f4742b5a..6eae577922ac64df1416b06ac1103ccc0d9a78e4 100644 --- a/frameworks/jskitsimpl/distributedkvstore/src/js_util.cpp +++ b/frameworks/jskitsimpl/distributedkvstore/src/js_util.cpp @@ -18,6 +18,7 @@ #include "hap_module_info.h" #include "napi_base_context.h" #include "js_schema.h" +#include "js_proxy.h" #include "kv_utils.h" #include "log_print.h" #include "napi_queue.h" @@ -26,6 +27,11 @@ namespace OHOS::DistributedKVStore { constexpr int32_t STR_MAX_LENGTH = 4096; constexpr size_t STR_TAIL_LENGTH = 1; +static constexpr int32_t HEAD_SIZE = 3; +static constexpr int32_t END_SIZE = 3; +static constexpr int32_t MIN_SIZE = 9; +static constexpr const char *REPLACE_CHAIN = "***"; +static constexpr const char *DEFAULT_ANONYMOUS = "******"; static constexpr JSUtil::JsFeatureSpace FEATURE_NAME_SPACES[] = { { "ohos.data.cloudData", "ZGF0YS5jbG91ZERhdGE=", false }, { "ohos.data.dataAbility", "ZGF0YS5kYXRhQWJpbGl0eQ==", false }, @@ -152,7 +158,7 @@ JSUtil::StatusMsg JSUtil::SetValue(napi_env env, const std::string& in, napi_val } /* napi_value <-> std::vector */ -JSUtil::StatusMsg JSUtil::GetValue(napi_env env, napi_value in, std::vector& out) +JSUtil::StatusMsg JSUtil::GetValue(napi_env env, napi_value in, std::vector& out, bool checkLength) { ZLOGD("napi_value -> std::vector"); out.clear(); @@ -162,7 +168,10 @@ JSUtil::StatusMsg JSUtil::GetValue(napi_env env, napi_value in, std::vector 0), "get_array failed!", napi_invalid_arg); + ASSERT(statusMsg.status == napi_ok, "get_array length failed!", napi_invalid_arg); + if (checkLength) { + ASSERT(length > 0, "check array length failed!", napi_invalid_arg); + } for (uint32_t i = 0; i < length; ++i) { napi_value item = nullptr; statusMsg.status = napi_get_element(env, in, i, &item); @@ -195,7 +204,7 @@ JSUtil::KvStoreVariant JSUtil::Blob2VariantValue(const DistributedKv::Blob& blob auto& data = blob.Data(); // number 2 means: valid Blob must have more than 2 bytes. if (data.size() < 1) { - ZLOGE("Blob have no data!"); + ZLOGD("Blob have no data!"); return JSUtil::KvStoreVariant(); } // number 1 means: skip the first byte, byte[0] is real data type. @@ -214,7 +223,7 @@ JSUtil::KvStoreVariant JSUtil::Blob2VariantValue(const DistributedKv::Blob& blob } else if (data[0] == JSUtil::DOUBLE) { uint64_t tmp4dbl = be64toh(*reinterpret_cast(&(real[0]))); return JSUtil::KvStoreVariant(*reinterpret_cast((void*)(&tmp4dbl))); - } else if (data[0] == JSUtil::STRING){ + } else if (data[0] == JSUtil::STRING) { return JSUtil::KvStoreVariant(std::string(real.begin(), real.end())); } else { // for schema-db, if (data[0] == JSUtil::STRING), no beginning byte! @@ -1007,6 +1016,7 @@ JSUtil::StatusMsg JSUtil::GetValue(napi_env env, napi_value in, DistributedKv::O ASSERT(statusMsg.status == napi_ok, "get encrypt param failed", statusMsg); statusMsg = GetNamedProperty(env, in, "backup", options.backup, true); ASSERT(statusMsg.status == napi_ok, "get backup param failed", statusMsg); + options.autoSync = false; statusMsg = GetNamedProperty(env, in, "autoSync", options.autoSync, true); ASSERT(statusMsg.status == napi_ok, "get autoSync param failed", statusMsg); @@ -1193,12 +1203,12 @@ JSUtil::StatusMsg JSUtil::GetValue(napi_env env, napi_value in, std::vector *jsProxy = nullptr; napi_unwrap(env, in, reinterpret_cast(&jsProxy)); - ASSERT((jsProxy != nullptr && jsProxy->predicates_ != nullptr), "invalid type", napi_invalid_arg); + ASSERT((jsProxy != nullptr && jsProxy->GetInstance() != nullptr), "invalid type", napi_invalid_arg); std::vector keys; statusMsg.status = napi_invalid_arg; - Status status = OHOS::DistributedKv::KvUtils::GetKeys(*(jsProxy->predicates_), keys); + Status status = OHOS::DistributedKv::KvUtils::GetKeys(*(jsProxy->GetInstance()), keys); if (status == Status::SUCCESS) { ZLOGD("napi_value —> GetValue Blob ok"); out = keys; @@ -1214,10 +1224,10 @@ JSUtil::StatusMsg JSUtil::GetValue(napi_env env, napi_value in, DataQuery &query napi_valuetype type = napi_undefined; napi_status nstatus = napi_typeof(env, in, &type); ASSERT((nstatus == napi_ok) && (type == napi_object), "invalid type", napi_invalid_arg); - OHOS::DataShare::DataShareAbsPredicates::JsProxy *jsProxy = nullptr; + JSProxy::JSProxy *jsProxy = nullptr; napi_unwrap(env, in, reinterpret_cast(&jsProxy)); - ASSERT((jsProxy != nullptr && jsProxy->predicates_ != nullptr), "invalid type", napi_invalid_arg); - Status status = OHOS::DistributedKv::KvUtils::ToQuery(*(jsProxy->predicates_), query); + ASSERT((jsProxy != nullptr && jsProxy->GetInstance() != nullptr), "invalid type", napi_invalid_arg); + Status status = OHOS::DistributedKv::KvUtils::ToQuery(*(jsProxy->GetInstance()), query); if (status != Status::SUCCESS) { ZLOGD("napi_value -> GetValue DataQuery failed "); } @@ -1243,7 +1253,7 @@ JSUtil::StatusMsg JSUtil::GetCurrentAbilityParam(napi_env env, ContextParam &par if (hapInfo != nullptr) { param.hapName = hapInfo->moduleName; } - ZLOGI("area:%{public}d hapName:%{public}s baseDir:%{public}s", param.area, param.hapName.c_str(), + ZLOGI("area:%{public}d hapName:%{public}s baseDir:%{public}s", param.area, Anonymous(param.hapName).c_str(), param.baseDir.c_str()); return napi_ok; @@ -1280,6 +1290,7 @@ JSUtil::StatusMsg JSUtil::GetValue(napi_env env, napi_value in, ContextParam &pa if (appInfo != nullptr) { statusMsg = GetNamedProperty(env, appInfo, "systemApp", param.isSystemApp); ASSERT(statusMsg.status == napi_ok, "get appInfo failed", napi_invalid_arg); + param.apiVersion = GetApiVersion(env, in); } return napi_ok; } @@ -1299,6 +1310,21 @@ bool JSUtil::IsNull(napi_env env, napi_value value) return false; } +int32_t JSUtil::GetApiVersion(napi_env env, napi_value value) +{ + auto context = AbilityRuntime::GetStageModeContext(env, value); + if (context == nullptr) { + ZLOGW("get context fail."); + return DEFAULT_API_VERSION; + } + auto appInfo = context->GetApplicationInfo(); + if (appInfo == nullptr) { + ZLOGW("get app info fail."); + return DEFAULT_API_VERSION; + } + return appInfo->apiTargetVersion % API_VERSION_MOD; +} + std::pair JSUtil::GetInnerValue( napi_env env, napi_value in, const std::string& prop, bool optional) { @@ -1321,4 +1347,17 @@ std::pair JSUtil::GetInnerValue( } return std::make_pair(napi_ok, inner); } + +std::string JSUtil::Anonymous(const std::string &name) +{ + if (name.length() <= HEAD_SIZE) { + return DEFAULT_ANONYMOUS; + } + + if (name.length() < MIN_SIZE) { + return (name.substr(0, HEAD_SIZE) + REPLACE_CHAIN); + } + + return (name.substr(0, HEAD_SIZE) + REPLACE_CHAIN + name.substr(name.length() - END_SIZE, END_SIZE)); +} } // namespace OHOS::DistributedKVStore diff --git a/frameworks/jskitsimpl/distributedkvstore/src/napi_queue.cpp b/frameworks/jskitsimpl/distributedkvstore/src/napi_queue.cpp index c37c898b2a6ccd6d4cee2a927342d5095935bb8d..db89206cf9f5bb61a7aa6209fc7cf9da6c617ee2 100644 --- a/frameworks/jskitsimpl/distributedkvstore/src/napi_queue.cpp +++ b/frameworks/jskitsimpl/distributedkvstore/src/napi_queue.cpp @@ -20,7 +20,7 @@ using namespace OHOS::DistributedKv; namespace OHOS::DistributedKVStore { ContextBase::~ContextBase() { - ZLOGD("no memory leak after callback or promise[resolved/rejected]"); + ZLOGD("No memory leak after callback or promise[resolved/rejected]"); if (env != nullptr) { if (callbackRef != nullptr) { auto status = napi_delete_reference(env, callbackRef); @@ -58,9 +58,9 @@ void ContextBase::GetCbInfo(napi_env envi, napi_callback_info info, NapiCbInfoPa status = napi_create_reference(env, argv[index], 1, &callbackRef); ASSERT_STATUS(this, "ref callback failed!"); argc = index; - ZLOGD("async callback, no promise"); + ZLOGD("Async callback, no promise"); } else { - ZLOGD("no callback, async pormose"); + ZLOGD("No callback, async pormose"); } } @@ -82,17 +82,18 @@ 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); - ZLOGD("create deferred promise"); + if (napi_create_promise(env, &aCtx->deferred, &promise) != napi_ok) { + ZLOGE("Create deferred promise fail"); + delete aCtx; + return nullptr; + } } else { napi_get_undefined(env, &promise); } napi_value resource = nullptr; napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &resource); - napi_create_async_work( - env, nullptr, resource, - [](napi_env env, void* data) { + napi_create_async_work(env, nullptr, resource, [](napi_env env, void* data) { ASSERT_VOID(data != nullptr, "napi_async_execute_callback nullptr"); auto actx = reinterpret_cast(data); ZLOGD("napi_async_execute_callback ctxt->status=%{public}d", actx->ctx->status); @@ -115,9 +116,10 @@ napi_value NapiQueue::AsyncWork(napi_env env, std::shared_ptr ctxt, delete actx; }, reinterpret_cast(aCtx), &aCtx->work); - auto status = napi_queue_async_work(env, aCtx->work); + auto status = napi_queue_async_work_with_qos(env, aCtx->work, napi_qos_user_initiated); if (status != napi_ok) { napi_get_undefined(env, &promise); + napi_reject_deferred(env, aCtx->deferred, promise); delete aCtx; } return promise; @@ -136,7 +138,7 @@ void NapiQueue::GenerateOutput(AsyncContext &ctx, napi_value output) napi_value message = nullptr; napi_value errorCode = nullptr; if (ctx.ctx->jsCode != 0 && ctx.ctx->jsCode != -1) { - napi_create_string_utf8(ctx.env, std::to_string(ctx.ctx->jsCode).c_str(), NAPI_AUTO_LENGTH, &errorCode); + napi_create_int32(ctx.env, ctx.ctx->jsCode, &errorCode); } if (ctx.ctx->jsCode == -1) { std::string jscode = ""; @@ -158,8 +160,8 @@ void NapiQueue::GenerateOutput(AsyncContext &ctx, napi_value output) napi_value callback = nullptr; napi_get_reference_value(ctx.env, ctx.ctx->callbackRef, &callback); napi_value callbackResult = nullptr; - ZLOGD("call callback function"); + ZLOGD("Call callback function"); napi_call_function(ctx.env, nullptr, callback, RESULT_ALL, result, &callbackResult); } } -} // namespace OHOS::DistributedKVStore +} // namespace OHOS::DistributedKVStore \ No newline at end of file diff --git a/frameworks/jskitsimpl/distributedkvstore/src/uv_queue.cpp b/frameworks/jskitsimpl/distributedkvstore/src/uv_queue.cpp index 2397918dee214236dae8cdbe54ed01dca5cf4880..5df050e547935c1995c67a1d11a41b0645a65256 100644 --- a/frameworks/jskitsimpl/distributedkvstore/src/uv_queue.cpp +++ b/frameworks/jskitsimpl/distributedkvstore/src/uv_queue.cpp @@ -14,77 +14,68 @@ */ #define LOG_TAG "UvQueue" -#include "uv_queue.h" #include "log_print.h" #include "napi_queue.h" +#include "uv_queue.h" namespace OHOS::DistributedKVStore { UvQueue::UvQueue(napi_env env) : env_(env) { - if (env != nullptr) { - napi_get_uv_event_loop(env, &loop_); - } } UvQueue::~UvQueue() { - ZLOGD("no memory leak for queue-callback"); + ZLOGD("No memory leak for queue-callback"); env_ = nullptr; } void UvQueue::AsyncCall(NapiCallbackGetter getter, NapiArgsGenerator genArgs) { - if (loop_ == nullptr || !getter) { - ZLOGE("loop_ or callback is nullptr"); + if (!getter) { + ZLOGE("This callback is nullptr"); return; } - - uv_work_t* work = new (std::nothrow) uv_work_t; - if (work == nullptr) { - ZLOGE("no memory for uv_work_t"); - return; + auto task = [env = env_, getter, genArgs]() { + napi_handle_scope scope = nullptr; + napi_open_handle_scope(env, &scope); + if (scope == nullptr) { + return; + } + napi_value method = getter(env); + if (method == nullptr) { + ZLOGE("The callback is invalid, maybe is cleared!"); + napi_close_handle_scope(env, scope); + return; + } + int argc = 0; + napi_value argv[ARGC_MAX] = { nullptr }; + if (genArgs) { + argc = ARGC_MAX; + genArgs(env, argc, argv); + } + napi_value global = nullptr; + napi_status status = napi_get_global(env, &global); + if (status != napi_ok) { + ZLOGE("Get napi global failed. status: %{public}d.", status); + napi_close_handle_scope(env, scope); + return; + } + napi_value result; + status = napi_call_function(env, global, method, argc, argv, &result); + if (status != napi_ok) { + ZLOGE("Notify data change failed. status:%{public}d.", status); + } + napi_close_handle_scope(env, scope); + }; + napi_status status = napi_send_event(env_, task, napi_eprio_immediate); + if (status != napi_ok) { + ZLOGE("Failed to napi_send_event. status:%{public}d", status); } - work->data = new UvEntry{ env_, getter, std::move(genArgs) }; - uv_queue_work( - loop_, work, [](uv_work_t* work) {}, - [](uv_work_t* work, int uvstatus) { - std::shared_ptr entry(static_cast(work->data), [work](UvEntry *data) { - delete data; - delete work; - }); - napi_handle_scope scope = nullptr; - napi_open_handle_scope(entry->env, &scope); - napi_value method = entry->callback(entry->env); - if (method == nullptr) { - ZLOGE("the callback is invalid, maybe is cleared!"); - if (scope != nullptr) { - napi_close_handle_scope(entry->env, scope); - } - return ; - } - int argc = 0; - napi_value argv[ARGC_MAX] = { nullptr }; - if (entry->args) { - argc = ARGC_MAX; - entry->args(entry->env, argc, argv); - } - ZLOGD("queue uv_after_work_cb"); - napi_value global = nullptr; - napi_get_global(entry->env, &global); - napi_value result; - napi_status status = napi_call_function(entry->env, global, method, argc, argv, &result); - if (status != napi_ok) { - ZLOGE("notify data change failed status:%{public}d.", status); - } - if (scope != nullptr) { - napi_close_handle_scope(entry->env, scope); - } - }); } napi_env UvQueue::GetEnv() { return env_; } -} // namespace OHOS::DistributedKVStore +} // namespace OHOS::DistributedKVStore \ No newline at end of file diff --git a/frameworks/native/dbm_kv_store/src/kv_store_impl_hal/dbm_kv_store.c b/frameworks/native/dbm_kv_store/src/kv_store_impl_hal/dbm_kv_store.c index 962214ea09171e61e9e27588ee4ee697102456b5..d415ebb65bdda6bbb2c55bd7351200971056dc51 100644 --- a/frameworks/native/dbm_kv_store/src/kv_store_impl_hal/dbm_kv_store.c +++ b/frameworks/native/dbm_kv_store/src/kv_store_impl_hal/dbm_kv_store.c @@ -246,14 +246,14 @@ static boolean IsStrSame(const char* value, int len, const char* str) static boolean IsHeaderValid(const char* header) { char magic[KV_MAGIC_SIZE + 1] = {0}; - if (memcpy_s(magic, KV_MAGIC_SIZE, header + KV_SUM_INDEX, KV_MAGIC_SIZE) != EOK && + if (memcpy_s(magic, sizeof(magic), header + KV_SUM_INDEX, KV_MAGIC_SIZE) != EOK && !IsStrSame(magic, KV_MAGIC_SIZE + 1, KV_MAGIC)) { return FALSE; } // after 1st magic is block size flag // magic is after 4 block - if (memcpy_s(magic, KV_MAGIC_SIZE, header + 4 * KV_SUM_BLOCK_SIZE, KV_MAGIC_SIZE) != EOK && + if (memcpy_s(magic, sizeof(magic), header + 4 * KV_SUM_BLOCK_SIZE, KV_MAGIC_SIZE) != EOK && !IsStrSame(magic, KV_MAGIC_SIZE + 1, KV_MAGIC)) { return FALSE; } @@ -265,7 +265,7 @@ static int GetSumFilePath(DBHandle db, char* sumFilePath, unsigned int len) if (!db) { return DBM_ERROR; } - + if (strlen(db->dirPath) == 0) { if (strcpy_s(sumFilePath, sizeof(KV_SUM_FILE), KV_SUM_FILE) != EOK) { return DBM_OK; @@ -317,10 +317,9 @@ static int LoadDataItem(DBHandle db, int index, KeyItem* item) } // 1st pos is default 0 - // 3 pos represented flag - item->flag.isValid = *(itemContent + 1); - item->flag.isBakValid = *(itemContent + 2); - item->flag.valueType = *(itemContent + 3); + item->flag.isValid = *(itemContent + 1); // 1 pos represented flag + item->flag.isBakValid = *(itemContent + 2); // 2 pos represented flag + item->flag.valueType = *(itemContent + 3); // 3 pos represented flag char keyLen[KV_SUM_BLOCK_SIZE] = {0}; // default key content len is 32 ret = memcpy_s(keyLen, KV_SUM_BLOCK_SIZE, itemContent + KV_SUM_BLOCK_SIZE, KV_SUM_BLOCK_SIZE); @@ -608,12 +607,12 @@ static int LoadSumFileHeader(DBHandle db) } char sumIndex[KV_SUM_INDEX + 1] = {0}; - if (memcpy_s(sumIndex, KV_SUM_INDEX, header, KV_SUM_INDEX) != EOK) { + if (memcpy_s(sumIndex, sizeof(sumIndex), header, KV_SUM_INDEX) != EOK) { return DBM_ERROR; } char headerFlag[KV_SUM_BLOCK_SIZE + 1] = {0}; - if (memcpy_s(headerFlag, KV_SUM_INDEX, header + KV_MAGIC_SIZE + KV_SUM_INDEX, KV_SUM_INDEX) != EOK) { + if (memcpy_s(headerFlag, sizeof(headerFlag), header + KV_MAGIC_SIZE + KV_SUM_INDEX, KV_SUM_INDEX) != EOK) { return DBM_ERROR; } @@ -719,7 +718,8 @@ static boolean IsDataItemMatched(DBHandle db, const char* key, int index) return IsStrSame(itemContent + KV_MAGIC_SIZE + KV_SUM_BLOCK_SIZE, strlen(key) + 1, key); } -static int IsNeedTransferValue(DBHandle db, const char* key, const char* fileRead, unsigned int fileLen, boolean* isNeed) +static int IsNeedTransferValue(DBHandle db, const char* key, const char* fileRead, unsigned int fileLen, + boolean* isNeed) { if (fileLen <= KV_SUM_BLOCK_SIZE) { // value size < index, means old version data *isNeed = FALSE; @@ -966,7 +966,7 @@ static int UpdateKV(DBHandle db, const KeyItem* item, const void* value, unsigne return DBM_ERROR; } - (void)memset_s(valueContent, len +KV_SUM_BLOCK_SIZE, 0, len + KV_SUM_BLOCK_SIZE); + (void)memset_s(valueContent, len + KV_SUM_BLOCK_SIZE, 0, len + KV_SUM_BLOCK_SIZE); int contentLen = InitValue(item->index, value, len, valueContent, len + KV_SUM_BLOCK_SIZE); if (contentLen < 0) { @@ -1326,7 +1326,9 @@ static int DelSumFile(DBHandle db) static int RemoveKVStoreFile(DBHandle db, int sumFileLen) { char flag[KV_SUM_BLOCK_SIZE + 1] = {0}; - (void)memset_s(flag, KV_SUM_BLOCK_SIZE, 1, KV_SUM_BLOCK_SIZE); + if (memset_s(flag, sizeof(flag), 1, KV_SUM_BLOCK_SIZE) != EOK) { + MST_LOG("RemoveKVStoreFile: flag info set 1 failed!"); + } int ret = FileWriteCursor(db->sumFileFd, KV_SUM_INDEX + KV_SUM_BLOCK_SIZE, SEEK_SET_FS, flag, KV_SUM_BLOCK_SIZE); if (ret < 0) { // ret is fd offset DBM_INFO("RemoveKVStoreFile: write sum file delete all flag fail.");