From fca1d8ce4db1161c84503fc6a87f17545e7b33a9 Mon Sep 17 00:00:00 2001 From: htt1997 Date: Mon, 12 Jun 2023 17:04:06 +0800 Subject: [PATCH] update Signed-off-by: htt1997 --- datamgr_service/bundle.json | 4 +- datamgr_service/conf/BUILD.gn | 4 +- datamgr_service/datamgr_service.gni | 2 + .../framework/include/error/general_error.h | 1 + .../include/metadata/store_meta_data.h | 1 + .../framework/include/store/auto_cache.h | 2 + .../framework/include/store/general_store.h | 2 +- .../framework/include/store/general_value.h | 13 +- .../framework/include/store/general_watcher.h | 6 + .../framework/metadata/store_meta_data.cpp | 6 + .../framework/store/auto_cache.cpp | 5 + .../service/cloud/cloud_service_impl.cpp | 9 +- .../service/cloud/sync_manager.cpp | 8 +- .../service/data_share/rdb_adaptor.cpp | 3 +- .../service/kvdb/kvdb_service_impl.cpp | 2 +- .../service/object/object_service_impl.cpp | 3 +- .../service/rdb/rdb_cloud.cpp | 1 - .../service/rdb/rdb_general_store.cpp | 7 +- .../service/rdb/rdb_service_impl.cpp | 20 +- .../service/rdb/rdb_service_impl.h | 6 +- .../service/rdb/rdb_service_stub.cpp | 30 +-- .../service/rdb/rdb_syncer.cpp | 12 +- .../service/rdb/rdb_syncer.h | 4 +- .../service/rdb/rdb_watcher.cpp | 3 +- .../service/rdb/value_proxy.cpp | 11 +- .../frameworks/common/test/traits_test.cpp | 2 +- kv_store/frameworks/common/traits.h | 42 ++-- .../interfaces/include/store_observer.h | 1 + .../relational_store_delegate_impl.cpp | 13 +- .../DeviceKvStoreKVCallbackJsTest.js | 2 +- mock/sqlite/include/sqlite3.h | 60 ++--- mock/src/mock_device_manager.cpp | 2 +- .../js/napi/cloud_data/src/js_config.cpp | 3 +- .../js/napi/common/include/js_utils.h | 16 +- .../js/napi/common/src/js_utils.cpp | 115 ++------- .../frameworks/js/napi/rdb/BUILD.gn | 1 + .../js/napi/rdb/src/napi_rdb_js_utils.cpp | 26 +- .../js/napi/rdb/src/napi_rdb_store_helper.cpp | 6 +- .../relationalstore/include/napi_async_call.h | 1 + .../include/napi_rdb_js_utils.h | 20 ++ .../relationalstore/include/napi_rdb_store.h | 2 +- .../include/napi_rdb_store_observer.h | 8 + .../relationalstore/include/napi_result_set.h | 3 + .../relationalstore/src/napi_async_call.cpp | 19 ++ .../src/napi_rdb_const_properties.cpp | 3 +- .../relationalstore/src/napi_rdb_js_utils.cpp | 171 +++++++++++-- .../relationalstore/src/napi_rdb_store.cpp | 101 +++++--- .../src/napi_rdb_store_helper.cpp | 6 +- .../src/napi_rdb_store_observer.cpp | 18 +- .../relationalstore/src/napi_result_set.cpp | 32 +++ .../native/appdatafwk/src/general_endian.cpp | 28 +++ .../native/appdatafwk/src/mingw_endian.cpp | 27 ++ .../native/appdatafwk/src/serializable.cpp | 208 ++++++++++++++++ .../native/rdb/include/raw_data_parser.h | 12 + .../native/rdb/include/rdb_service_proxy.h | 11 +- .../native/rdb/include/rdb_store_impl.h | 14 +- .../native/rdb/include/rdb_types_util.h | 2 +- .../rdb/include/sqlite_shared_result_set.h | 1 - .../native/rdb/mock/include/rdb_store_impl.h | 2 +- .../native/rdb/src/abs_rdb_predicates.cpp | 2 +- .../native/rdb/src/abs_result_set.cpp | 12 + .../native/rdb/src/abs_shared_result_set.cpp | 2 +- .../native/rdb/src/raw_data_parser.cpp | 105 +++++++- .../native/rdb/src/rdb_notifier_stub.cpp | 2 +- .../native/rdb/src/rdb_security_manager.cpp | 10 +- .../native/rdb/src/rdb_service_proxy.cpp | 15 +- .../native/rdb/src/rdb_sql_utils.cpp | 82 +++++++ .../native/rdb/src/rdb_store_impl.cpp | 138 ++++++++--- .../native/rdb/src/rdb_store_manager.cpp | 4 + .../native/rdb/src/rdb_types_util.cpp | 10 +- .../frameworks/native/rdb/src/share_block.cpp | 3 +- .../rdb/src/shared_block_serializer_info.cpp | 4 +- .../native/rdb/src/sqlite_connection.cpp | 12 +- .../native/rdb/src/sqlite_connection_pool.cpp | 1 + .../native/rdb/src/sqlite_database_utils.cpp | 231 ------------------ .../rdb/src/sqlite_shared_result_set.cpp | 7 +- .../native/rdb/src/sqlite_statement.cpp | 16 ++ .../native/rdb/src/step_result_set.cpp | 18 +- .../interfaces/inner_api/appdatafwk/BUILD.gn | 16 +- .../include/multi_platform_endian.h | 29 +++ .../appdatafwk/include/serializable.h | 123 ++++++++++ .../js/@ohos.data.relationalStore.d.ts | 65 ++++- .../interfaces/inner_api/rdb/BUILD.gn | 43 +++- .../rdb/include/abs_rdb_predicates.h | 4 +- .../inner_api/rdb/include/asset_value.h | 10 + .../inner_api/rdb/include/rdb_service.h | 2 +- ...transaction_observer.h => rdb_sql_utils.h} | 36 +-- .../inner_api/rdb/include/rdb_store.h | 3 +- .../inner_api/rdb/include/rdb_types.h | 14 +- .../inner_api/rdb/include/remote_result_set.h | 4 + .../rdb/include/sqlite_database_utils.h | 72 ------ .../inner_api/rdb/mock/include/asset_value.h | 9 + .../rdb/mock/include/sqlite_database_utils.h | 70 ------ .../unittest/src/RdbStoreCloud.test.js | 154 ++++++++++++ .../rdbimpl_fuzzer/rdbimpl_fuzzer.cpp | 2 +- .../test/native/rdb/unittest/common.h | 5 +- .../native/rdb/unittest/rdb_asset_test.cpp | 156 ++++++++++++ .../rdb/unittest/rdb_store_rekey_test.cpp | 4 +- .../rdb/unittest/rdb_store_subscribe_test.cpp | 145 ++++++++--- 99 files changed, 1952 insertions(+), 831 deletions(-) create mode 100644 relational_store/frameworks/native/appdatafwk/src/general_endian.cpp create mode 100644 relational_store/frameworks/native/appdatafwk/src/mingw_endian.cpp create mode 100644 relational_store/frameworks/native/appdatafwk/src/serializable.cpp create mode 100644 relational_store/frameworks/native/rdb/src/rdb_sql_utils.cpp delete mode 100644 relational_store/frameworks/native/rdb/src/sqlite_database_utils.cpp create mode 100644 relational_store/interfaces/inner_api/appdatafwk/include/multi_platform_endian.h create mode 100644 relational_store/interfaces/inner_api/appdatafwk/include/serializable.h rename relational_store/interfaces/inner_api/rdb/include/{transaction_observer.h => rdb_sql_utils.h} (53%) delete mode 100644 relational_store/interfaces/inner_api/rdb/include/sqlite_database_utils.h delete mode 100644 relational_store/interfaces/inner_api/rdb/mock/include/sqlite_database_utils.h create mode 100644 relational_store/test/js/relationalstore/unittest/src/RdbStoreCloud.test.js create mode 100644 relational_store/test/native/rdb/unittest/rdb_asset_test.cpp diff --git a/datamgr_service/bundle.json b/datamgr_service/bundle.json index c0a31d6a..cac29ffe 100644 --- a/datamgr_service/bundle.json +++ b/datamgr_service/bundle.json @@ -42,7 +42,9 @@ "SystemCapability.DistributedDataManager.KVStore.Lite", "SystemCapability.DistributedDataManager.KVStore.DistributedKVStore" ], - "features": [], + "features": [ + "datamgr_service_config" + ], "adapted_system_type": [ "standard" ], diff --git a/datamgr_service/conf/BUILD.gn b/datamgr_service/conf/BUILD.gn index 0e9037c6..14f7ca2c 100644 --- a/datamgr_service/conf/BUILD.gn +++ b/datamgr_service/conf/BUILD.gn @@ -15,7 +15,9 @@ import("//build/ohos_var.gni") #/system/etc/distributeddata/conf group("build_module") { - deps = [ ":default_conf" ] + if (datamgr_service_config) { + deps = [ ":default_conf" ] + } } ohos_prebuilt_etc("default_conf") { source = "config.json" diff --git a/datamgr_service/datamgr_service.gni b/datamgr_service/datamgr_service.gni index 15f8ddfc..ba383a0f 100644 --- a/datamgr_service/datamgr_service.gni +++ b/datamgr_service/datamgr_service.gni @@ -42,4 +42,6 @@ declare_args() { } else { os_account_part_is_enabled = false } + + datamgr_service_config = true; } diff --git a/datamgr_service/services/distributeddataservice/framework/include/error/general_error.h b/datamgr_service/services/distributeddataservice/framework/include/error/general_error.h index 27ec5595..56fc4a8f 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/error/general_error.h +++ b/datamgr_service/services/distributeddataservice/framework/include/error/general_error.h @@ -27,6 +27,7 @@ enum GeneralError : int32_t { E_ALREADY_CLOSED, E_UNOPENED, E_RETRY_TIMEOUT, + E_ALREADY_LOCKED, E_BUTT, }; } diff --git a/datamgr_service/services/distributeddataservice/framework/include/metadata/store_meta_data.h b/datamgr_service/services/distributeddataservice/framework/include/metadata/store_meta_data.h index bb134e35..cf0e8f41 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/metadata/store_meta_data.h +++ b/datamgr_service/services/distributeddataservice/framework/include/metadata/store_meta_data.h @@ -66,6 +66,7 @@ struct API_EXPORT StoreMetaData final : public Serializable { API_EXPORT bool Marshal(json &node) const override; API_EXPORT bool Unmarshal(const json &node) override; API_EXPORT std::string GetKey() const; + API_EXPORT std::string GetStoreAlias() const; API_EXPORT std::string GetKeyLocal() const; API_EXPORT std::string GetSecretKey() const; API_EXPORT std::string GetStrategyKey() const; diff --git a/datamgr_service/services/distributeddataservice/framework/include/store/auto_cache.h b/datamgr_service/services/distributeddataservice/framework/include/store/auto_cache.h index b5e91e68..e4940b91 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/store/auto_cache.h +++ b/datamgr_service/services/distributeddataservice/framework/include/store/auto_cache.h @@ -48,6 +48,8 @@ public: API_EXPORT void CloseStore(uint32_t tokenId, const std::string &storeId); + API_EXPORT void CloseStore(uint32_t tokenId); + API_EXPORT void CloseExcept(const std::set &users); API_EXPORT void SetObserver(uint32_t tokenId, const std::string &storeId, const Watchers &watchers); diff --git a/datamgr_service/services/distributeddataservice/framework/include/store/general_store.h b/datamgr_service/services/distributeddataservice/framework/include/store/general_store.h index b7a3775b..fc52bd8d 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/store/general_store.h +++ b/datamgr_service/services/distributeddataservice/framework/include/store/general_store.h @@ -35,7 +35,7 @@ public: NEARBY_PUSH = NEARBY_BEGIN, NEARBY_PULL, NEARBY_PULL_PUSH, - NEARBY_END, + NEARBY_END = 4, CLOUD_BEGIN = NEARBY_END, CLOUD_TIME_FIRST = CLOUD_BEGIN, CLOUD_NATIVE_FIRST, diff --git a/datamgr_service/services/distributeddataservice/framework/include/store/general_value.h b/datamgr_service/services/distributeddataservice/framework/include/store/general_value.h index 18df10a1..9c8c9afa 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/store/general_value.h +++ b/datamgr_service/services/distributeddataservice/framework/include/store/general_value.h @@ -50,9 +50,20 @@ struct GenProgressDetail { }; struct Asset { - uint32_t version; + enum Status : int32_t { + STATUS_NORMAL, + STATUS_ABNORMAL, + STATUS_DOWNLOADING, + STATUS_BUTT + }; + + static constexpr uint64_t NO_EXPIRES_TIME = 0; + uint32_t version = 0; + uint32_t status = STATUS_NORMAL; + uint64_t expiresTime = NO_EXPIRES_TIME; std::string name; std::string uri; + std::string path; std::string createTime; std::string modifyTime; std::string size; diff --git a/datamgr_service/services/distributeddataservice/framework/include/store/general_watcher.h b/datamgr_service/services/distributeddataservice/framework/include/store/general_watcher.h index 4583aa9d..db0cde87 100644 --- a/datamgr_service/services/distributeddataservice/framework/include/store/general_watcher.h +++ b/datamgr_service/services/distributeddataservice/framework/include/store/general_watcher.h @@ -29,7 +29,13 @@ public: ORIGIN_ALL, ORIGIN_BUTT, }; + enum DataType : int32_t { + BASIC_DATA, + ASSET_DATA, + TYPE_BUTT, + }; int32_t origin = ORIGIN_BUTT; + int32_t dataType = BASIC_DATA; // origin is ORIGIN_LOCAL, the id is empty // origin is ORIGIN_NEARBY, the id is networkId; // origin is ORIGIN_CLOUD, the id is the cloud account id diff --git a/datamgr_service/services/distributeddataservice/framework/metadata/store_meta_data.cpp b/datamgr_service/services/distributeddataservice/framework/metadata/store_meta_data.cpp index d7867f89..116490ac 100644 --- a/datamgr_service/services/distributeddataservice/framework/metadata/store_meta_data.cpp +++ b/datamgr_service/services/distributeddataservice/framework/metadata/store_meta_data.cpp @@ -19,6 +19,7 @@ #include "metadata/store_meta_data_local.h" #include "metadata/strategy_meta_data.h" #include "utils/constant.h" +#include "utils/anonymous.h" namespace OHOS { namespace DistributedData { constexpr uint32_t StoreMetaData::CURRENT_VERSION; @@ -175,5 +176,10 @@ std::string StoreMetaData::GetPrefix(const std::initializer_list &f { return GetKey(fields).append(Constant::KEY_SEPARATOR); } + +std::string StoreMetaData::GetStoreAlias() const +{ + return Anonymous::Change(storeId); +} } // namespace DistributedData } // namespace OHOS diff --git a/datamgr_service/services/distributeddataservice/framework/store/auto_cache.cpp b/datamgr_service/services/distributeddataservice/framework/store/auto_cache.cpp index ec9dea51..381c9cb7 100644 --- a/datamgr_service/services/distributeddataservice/framework/store/auto_cache.cpp +++ b/datamgr_service/services/distributeddataservice/framework/store/auto_cache.cpp @@ -94,6 +94,11 @@ void AutoCache::CloseStore(uint32_t tokenId, const std::string &storeId) }); } +void AutoCache::CloseStore(uint32_t tokenId) +{ + stores_.Erase(tokenId); +} + void AutoCache::CloseExcept(const std::set &users) { stores_.EraseIf([&users](const auto &tokenId, std::map &delegates) { diff --git a/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.cpp index c7722dd3..c0686642 100644 --- a/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/cloud/cloud_service_impl.cpp @@ -151,7 +151,7 @@ int32_t CloudServiceImpl::NotifyDataChange(const std::string &id, const std::str return ERROR; } if (cloudInfo.id != id) { - ZLOGE("invalid args, [input] id:%{public}s, [exist] id:%{public}s", Anonymous::Change(id).c_str(), + ZLOGE("invalid args, [input] id:%{public}s, [meta] id:%{public}s", Anonymous::Change(id).c_str(), Anonymous::Change(cloudInfo.id).c_str()); return INVALID_ARGUMENT; } @@ -206,7 +206,9 @@ int32_t CloudServiceImpl::OnBind(const BindInfo &info) int32_t CloudServiceImpl::OnUserChange(uint32_t code, const std::string &user, const std::string &account) { int32_t userId = atoi(user.c_str()); - Execute(GetCloudTask(0, userId, { WORK_CLOUD_INFO_UPDATE, WORK_SCHEMA_UPDATE })); + if (code == static_cast(DistributedKv::AccountStatus::DEVICE_ACCOUNT_SWITCHED)) { + Execute(GetCloudTask(0, userId, { WORK_CLOUD_INFO_UPDATE, WORK_SCHEMA_UPDATE })); + } syncManager_.StopCloudSync(userId); return E_OK; } @@ -336,7 +338,8 @@ ExecutorPool::Task CloudServiceImpl::GenTask(int32_t retry, int32_t user, AsyncW bool finished = true; std::vector users; if (user == 0) { - finished = Account::GetInstance()->QueryUsers(users); + auto account = Account::GetInstance(); + finished = account == nullptr ? false : account->QueryUsers(users); } else { users.push_back(user); } diff --git a/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.cpp b/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.cpp index f55515a7..924ccfff 100644 --- a/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.cpp +++ b/datamgr_service/services/distributeddataservice/service/cloud/sync_manager.cpp @@ -219,12 +219,12 @@ std::function SyncManager::GetSyncHandler() meta.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; if (!MetaDataManager::GetInstance().LoadMeta(meta.GetKey(), meta)) { ZLOGE("failed, no store meta bundleName:%{public}s, storeId:%{public}s", meta.bundleName.c_str(), - meta.storeId.c_str()); + meta.GetStoreAlias().c_str()); return; } auto store = AutoCache::GetInstance().GetStore(meta, {}); if (store == nullptr) { - ZLOGE("store null, storeId:%{public}s", meta.storeId.c_str()); + ZLOGE("store null, storeId:%{public}s", meta.GetStoreAlias().c_str()); return; } @@ -235,7 +235,7 @@ std::function SyncManager::GetSyncHandler() std::string schemaKey = info.GetSchemaKey(storeInfo.bundleName, storeInfo.instanceId); if (!MetaDataManager::GetInstance().LoadMeta(std::move(schemaKey), schemaMeta, true)) { ZLOGE("failed, no schema bundleName:%{public}s, storeId:%{public}s", storeInfo.bundleName.c_str(), - storeInfo.storeName.c_str()); + meta.GetStoreAlias().c_str()); return; } auto dbMeta = schemaMeta.GetDataBase(storeInfo.storeName); @@ -248,7 +248,7 @@ std::function SyncManager::GetSyncHandler() store->Bind(dbMeta, std::move(cloudDB)); } ZLOGD("database:<%{public}d:%{public}s:%{public}s> sync start", storeInfo.user, storeInfo.bundleName.c_str(), - storeInfo.storeName.c_str()); + meta.GetStoreAlias().c_str()); store->Sync({ "default" }, evt.GetMode(), *(evt.GetQuery()), evt.GetAsyncDetail(), evt.GetWait()); }; } diff --git a/datamgr_service/services/distributeddataservice/service/data_share/rdb_adaptor.cpp b/datamgr_service/services/distributeddataservice/service/data_share/rdb_adaptor.cpp index d9916ea6..a17e225a 100644 --- a/datamgr_service/services/distributeddataservice/service/data_share/rdb_adaptor.cpp +++ b/datamgr_service/services/distributeddataservice/service/data_share/rdb_adaptor.cpp @@ -71,7 +71,8 @@ RdbDelegate::RdbDelegate(const StoreMetaData &meta, int &errCode) DefaultOpenCallback callback; store_ = RdbHelper::GetRdbStore(config, meta.version, callback, errCode); if (errCode != E_OK) { - ZLOGE("GetRdbStore failed, errCode is %{public}d, storeId is %{public}s", errCode, meta.storeId.c_str()); + ZLOGE("GetRdbStore failed, errCode is %{public}d, storeId is %{public}s", errCode, + meta.GetStoreAlias().c_str()); } } diff --git a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp index 98f1c5ef..3a6f9f6f 100644 --- a/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp @@ -495,7 +495,7 @@ int32_t KVDBServiceImpl::OnReady(const std::string &device) if (!data.isAutoSync) { continue; } - ZLOGI("[onReady] appId:%{public}s, storeId:%{public}s", data.bundleName.c_str(), data.storeId.c_str()); + ZLOGI("[onReady] appId:%{public}s, storeId:%{public}s", data.bundleName.c_str(), data.GetStoreAlias().c_str()); StoreMetaDataLocal localMetaData; MetaDataManager::GetInstance().LoadMeta(data.GetKeyLocal(), localMetaData, true); if (!localMetaData.HasPolicy(PolicyType::IMMEDIATE_SYNC_ON_READY) && diff --git a/datamgr_service/services/distributeddataservice/service/object/object_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/object/object_service_impl.cpp index ccd1e57a..a785f866 100644 --- a/datamgr_service/services/distributeddataservice/service/object/object_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/object/object_service_impl.cpp @@ -112,7 +112,8 @@ int32_t ObjectServiceImpl::OnInitialize() if (!saved) { ZLOGE("Save appIdMeta failed"); } - ZLOGI("SaveMeta success appId %{public}s, storeId %{public}s", saveMeta.appId.c_str(), saveMeta.storeId.c_str()); + ZLOGI("SaveMeta success appId %{public}s, storeId %{public}s", saveMeta.appId.c_str(), + saveMeta.GetStoreAlias().c_str()); return OBJECT_SUCCESS; } diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.cpp index 8929f73f..746ea246 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_cloud.cpp @@ -102,7 +102,6 @@ DBStatus RdbCloud::Close() return ConvertStatus(static_cast(error)); } - DBStatus RdbCloud::ConvertStatus(DistributedData::GeneralError error) { switch (error) { diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.cpp index 87049d11..1d1d9cf5 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_general_store.cpp @@ -65,7 +65,7 @@ RdbGeneralStore::RdbGeneralStore(const StoreMetaData &meta) : manager_(meta.appI option.iterateTimes = ITERATE_TIMES; option.cipher = CipherType::AES_256_GCM; } - option.observer = nullptr; + option.observer = &observer_; manager_.OpenStore(meta.dataDir, meta.storeId, option, delegate_); RdbStoreConfig config(meta.dataDir); config.SetCreateNecessary(false); @@ -73,7 +73,8 @@ RdbGeneralStore::RdbGeneralStore(const StoreMetaData &meta) : manager_(meta.appI int32_t errCode = NativeRdb::E_OK; store_ = RdbHelper::GetRdbStore(config, -1, callback, errCode); if (errCode != NativeRdb::E_OK) { - ZLOGE("GetRdbStore failed, errCode is %{public}d, storeId is %{public}s", errCode, meta.storeId.c_str()); + ZLOGE("GetRdbStore failed, errCode is %{public}d, storeId is %{public}s", errCode, + meta.GetStoreAlias().c_str()); } } @@ -300,6 +301,8 @@ void RdbGeneralStore::ObserverProxy::OnChange(DBOrigin origin, const std::string genOrigin.origin = (origin == DBOrigin::ORIGIN_LOCAL) ? GenOrigin::ORIGIN_LOCAL : (origin == DBOrigin::ORIGIN_CLOUD) ? GenOrigin::ORIGIN_CLOUD : GenOrigin::ORIGIN_NEARBY; + genOrigin.dataType = (data.type == TYPE_INDEX || data.type == TYPE_INDEX) ? GenOrigin::ASSET_DATA + : GenOrigin::BASIC_DATA; genOrigin.id.push_back(originalId); genOrigin.store = storeId_; Watcher::PRIFields fields; diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.cpp index e455ffc4..187e7874 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.cpp @@ -116,11 +116,12 @@ int32_t RdbServiceImpl::ResolveAutoLaunch(const std::string &identifier, Distrib auto aIdentifier = DistributedDB::RelationalStoreManager::GetRelationalStoreIdentifier( entry.user, entry.appId, entry.storeId); - ZLOGI("%{public}s %{public}s %{public}s", entry.user.c_str(), entry.appId.c_str(), entry.storeId.c_str()); + ZLOGI("%{public}s %{public}s %{public}s", entry.user.c_str(), entry.appId.c_str(), + entry.GetStoreAlias().c_str()); if (aIdentifier != identifier) { continue; } - ZLOGI("find identifier %{public}s", entry.storeId.c_str()); + ZLOGI("find identifier %{public}s", entry.GetStoreAlias().c_str()); param.userId = entry.user; param.appId = entry.appId; param.storeId = entry.storeId; @@ -142,6 +143,7 @@ int32_t RdbServiceImpl::ResolveAutoLaunch(const std::string &identifier, Distrib int32_t RdbServiceImpl::OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &bundleName) { OnClientDied(pid); + AutoCache::GetInstance().CloseStore(tokenId); return E_OK; } @@ -247,7 +249,7 @@ void RdbServiceImpl::SyncerTimeout(std::shared_ptr syncer) return; } auto storeId = syncer->GetStoreId(); - ZLOGI("%{public}s", storeId.c_str()); + ZLOGI("%{public}s", Anonymous::Change(storeId).c_str()); syncers_.ComputeIfPresent(syncer->GetPid(), [this, storeId](const auto& key, StoreSyncersType& syncers) { syncers.erase(storeId); syncerNum_--; @@ -324,7 +326,7 @@ int32_t RdbServiceImpl::SetDistributedTables(const RdbSyncerParam ¶m, const } std::pair RdbServiceImpl::DoSync(const RdbSyncerParam ¶m, const Option &option, - const RdbPredicates &pred) + const PredicatesMemo &pred) { if (!CheckAccess(param.bundleName_, param.storeName_)) { ZLOGE("permission error"); @@ -341,14 +343,14 @@ std::pair RdbServiceImpl::DoSync(const RdbSyncerParam ¶m, void RdbServiceImpl::OnAsyncComplete(uint32_t tokenId, uint32_t seqNum, Details &&result) { - ZLOGI("pid=%{public}x seqnum=%{public}u", tokenId, seqNum); + ZLOGI("Sync complete, pid=%{public}x seqnum=%{public}u", tokenId, seqNum); auto [success, agent] = syncAgents_.Find(tokenId); if (success && agent.notifier_ != nullptr) { agent.notifier_->OnComplete(seqNum, std::move(result)); } } -int32_t RdbServiceImpl::DoAsync(const RdbSyncerParam ¶m, const Option &option, const RdbPredicates &pred) +int32_t RdbServiceImpl::DoAsync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &pred) { if (!CheckAccess(param.bundleName_, param.storeName_)) { ZLOGE("permission error"); @@ -444,12 +446,14 @@ int32_t RdbServiceImpl::RemoteQuery(const RdbSyncerParam& param, const std::stri return syncer->RemoteQuery(device, sql, selectionArgs, resultSet); } -int32_t RdbServiceImpl::Sync(const RdbSyncerParam ¶m, const Option &option, const RdbPredicates &predicates, +int32_t RdbServiceImpl::Sync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &predicates, const AsyncDetail &async) { if (!option.isAsync) { auto [status, details] = DoSync(param, option, predicates); - async(std::move(details)); + if (async != nullptr) { + async(std::move(details)); + } return status; } return DoAsync(param, option, predicates); diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.h b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.h index 36d2041c..3777efa8 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_impl.h @@ -48,7 +48,7 @@ public: int32_t RemoteQuery(const RdbSyncerParam& param, const std::string& device, const std::string& sql, const std::vector& selectionArgs, sptr& resultSet) override; - int32_t Sync(const RdbSyncerParam ¶m, const Option &option, const RdbPredicates &predicates, + int32_t Sync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &predicates, const AsyncDetail &async) override; int32_t Subscribe(const RdbSyncerParam ¶m, const SubscribeOption &option, RdbStoreObserver *observer) override; @@ -94,9 +94,9 @@ private: static constexpr int32_t MAX_SYNCER_PER_PROCESS = 10; static constexpr int32_t SYNCER_TIMEOUT = 60 * 1000; // ms - std::pair DoSync(const RdbSyncerParam ¶m, const Option &option, const RdbPredicates &pred); + std::pair DoSync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &pred); - int32_t DoAsync(const RdbSyncerParam ¶m, const Option &option, const RdbPredicates &pred); + int32_t DoAsync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &pred); Watchers GetWatchers(uint32_t tokenId, const std::string &storeName); diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.cpp index 87ec6b42..f1f8fec6 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_service_stub.cpp @@ -22,13 +22,13 @@ #include "utils/anonymous.h" namespace OHOS::DistributedRdb { +using Anonymous = DistributedData::Anonymous; int32_t RdbServiceStub::OnRemoteObtainDistributedTableName(MessageParcel &data, MessageParcel &reply) { std::string device; std::string table; if (!ITypesUtil::Unmarshal(data, device, table)) { - ZLOGE("Unmarshal device:%{public}s table:%{public}s", DistributedData::Anonymous::Change(device).c_str(), - table.c_str()); + ZLOGE("Unmarshal device:%{public}s table:%{public}s", Anonymous::Change(device).c_str(), table.c_str()); return IPC_STUB_INVALID_DATA_ERR; } @@ -45,7 +45,7 @@ int32_t RdbServiceStub::OnGetSchema(MessageParcel &data, MessageParcel &reply) RdbSyncerParam param; if (!ITypesUtil::Unmarshal(data, param)) { ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s", param.bundleName_.c_str(), - param.storeName_.c_str()); + Anonymous::Change(param.storeName_).c_str()); return IPC_STUB_INVALID_DATA_ERR; } auto status = GetSchema(param); @@ -62,7 +62,7 @@ int32_t RdbServiceStub::OnRemoteInitNotifier(MessageParcel &data, MessageParcel sptr notifier; if (!ITypesUtil::Unmarshal(data, param, notifier) || notifier == nullptr) { ZLOGE("Unmarshal bundleName:%{public}s storeName_:%{public}s notifier is nullptr:%{public}d", - param.bundleName_.c_str(), param.storeName_.c_str(), notifier == nullptr); + param.bundleName_.c_str(), Anonymous::Change(param.storeName_).c_str(), notifier == nullptr); return IPC_STUB_INVALID_DATA_ERR; } auto status = InitNotifier(param, notifier); @@ -79,7 +79,7 @@ int32_t RdbServiceStub::OnRemoteSetDistributedTables(MessageParcel &data, Messag std::vector tables; if (!ITypesUtil::Unmarshal(data, param, tables)) { ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s tables size:%{public}zu", - param.bundleName_.c_str(), param.storeName_.c_str(), tables.size()); + param.bundleName_.c_str(), Anonymous::Change(param.storeName_).c_str(), tables.size()); return IPC_STUB_INVALID_DATA_ERR; } @@ -95,10 +95,10 @@ int32_t RdbServiceStub::OnRemoteDoSync(MessageParcel &data, MessageParcel &reply { RdbSyncerParam param; Option option {}; - RdbPredicates predicates; + PredicatesMemo predicates; if (!ITypesUtil::Unmarshal(data, param, option, predicates)) { ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s tables:%{public}zu", param.bundleName_.c_str(), - param.storeName_.c_str(), predicates.tables_.size()); + Anonymous::Change(param.storeName_).c_str(), predicates.tables_.size()); return IPC_STUB_INVALID_DATA_ERR; } @@ -117,9 +117,9 @@ int32_t RdbServiceStub::OnRemoteDoAsync(MessageParcel &data, MessageParcel &repl Option option {}; RdbPredicates predicates; if (!ITypesUtil::Unmarshal(data, param, option, predicates)) { - ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s seqNum:%{public}u tables:%{public}s", - param.bundleName_.c_str(), param.storeName_.c_str(), option.seqNum, - (*(predicates.tables_.begin())).c_str()); + ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s seqNum:%{public}u table:%{public}s", + param.bundleName_.c_str(), Anonymous::Change(param.storeName_).c_str(), option.seqNum, + predicates.tables_.empty() ? "null" : predicates.tables_.begin()->c_str()); return IPC_STUB_INVALID_DATA_ERR; } auto status = Sync(param, option, predicates, nullptr); @@ -136,7 +136,7 @@ int32_t RdbServiceStub::OnRemoteDoSubscribe(MessageParcel &data, MessageParcel & SubscribeOption option; if (!ITypesUtil::Unmarshal(data, param, option)) { ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s", param.bundleName_.c_str(), - param.storeName_.c_str()); + Anonymous::Change(param.storeName_).c_str()); return IPC_STUB_INVALID_DATA_ERR; } @@ -154,7 +154,7 @@ int32_t RdbServiceStub::OnRemoteDoUnSubscribe(MessageParcel &data, MessageParcel SubscribeOption option; if (!ITypesUtil::Unmarshal(data, param)) { ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s", param.bundleName_.c_str(), - param.storeName_.c_str()); + Anonymous::Change(param.storeName_).c_str()); return IPC_STUB_INVALID_DATA_ERR; } @@ -174,9 +174,9 @@ int32_t RdbServiceStub::OnRemoteDoRemoteQuery(MessageParcel& data, MessageParcel std::vector selectionArgs; if (!ITypesUtil::Unmarshal(data, param, device, sql, selectionArgs)) { ZLOGE("Unmarshal bundleName_:%{public}s storeName_:%{public}s device:%{public}s sql:%{public}s " - "selectionArgs size:%{public}zu", param.bundleName_.c_str(), param.storeName_.c_str(), - DistributedData::Anonymous::Change(device).c_str(), - DistributedData::Anonymous::Change(sql).c_str(), selectionArgs.size()); + "selectionArgs size:%{public}zu", param.bundleName_.c_str(), + Anonymous::Change(param.storeName_).c_str(), Anonymous::Change(device).c_str(), + Anonymous::Change(sql).c_str(), selectionArgs.size()); return IPC_STUB_INVALID_DATA_ERR; } diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_syncer.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_syncer.cpp index a9e83914..d620126d 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_syncer.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_syncer.cpp @@ -336,7 +336,7 @@ void RdbSyncer::Limit(const RdbPredicateOperation &operation, DistributedDB::Que ZLOGI("limit=%{public}d offset=%{public}d", limit, offset); } -DistributedDB::Query RdbSyncer::MakeQuery(const RdbPredicates &predicates) +DistributedDB::Query RdbSyncer::MakeQuery(const PredicatesMemo &predicates) { ZLOGI("table=%{public}zu", predicates.tables_.size()); auto query = predicates.tables_.size() == 1 ? DistributedDB::Query::Select(*predicates.tables_.begin()) @@ -352,7 +352,7 @@ DistributedDB::Query RdbSyncer::MakeQuery(const RdbPredicates &predicates) return query; } -int32_t RdbSyncer::DoSync(const Option &option, const RdbPredicates &predicates, const AsyncDetail &async) +int32_t RdbSyncer::DoSync(const Option &option, const PredicatesMemo &predicates, const AsyncDetail &async) { auto *delegate = GetDelegate(); if (delegate == nullptr) { @@ -366,10 +366,12 @@ int32_t RdbSyncer::DoSync(const Option &option, const RdbPredicates &predicates, return delegate->Sync( devices, static_cast(option.mode), MakeQuery(predicates), [async](const std::map> &syncStatus) { - async(HandleSyncStatus(syncStatus)); + if (async != nullptr) { + async(HandleSyncStatus(syncStatus)); + } }, - option.isAsync); - } else if (option.mode < DistributedData::GeneralStore::CLOUD_END) { + !option.isAsync); + } else if ( DistributedData::GeneralStore::CLOUD_BEGIN <= option.mode && option.mode < DistributedData::GeneralStore::CLOUD_END) { CloudEvent::StoreInfo storeInfo; storeInfo.bundleName = GetBundleName(); storeInfo.user = AccountDelegate::GetInstance()->GetUserByToken(token_); diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_syncer.h b/datamgr_service/services/distributeddataservice/service/rdb/rdb_syncer.h index 8f09fb34..c6b93a19 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_syncer.h +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_syncer.h @@ -53,7 +53,7 @@ public: int32_t SetDistributedTables(const std::vector &tables, int32_t type); - int32_t DoSync(const Option &option, const RdbPredicates &predicates, const AsyncDetail &async); + int32_t DoSync(const Option &option, const PredicatesMemo &predicates, const AsyncDetail &async); int32_t RemoteQuery(const std::string &device, const std::string &sql, const std::vector &selectionArgs, sptr &resultSet); @@ -66,7 +66,7 @@ public: static bool GetPassword(const StoreMetaData &metaData, DistributedDB::CipherPassword &password); - static DistributedDB::Query MakeQuery(const RdbPredicates &predicates); + static DistributedDB::Query MakeQuery(const PredicatesMemo &predicates); private: std::string GetUserId() const; diff --git a/datamgr_service/services/distributeddataservice/service/rdb/rdb_watcher.cpp b/datamgr_service/services/distributeddataservice/service/rdb/rdb_watcher.cpp index 1294f292..a0d4d0ed 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/rdb_watcher.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/rdb_watcher.cpp @@ -35,9 +35,10 @@ int32_t RdbWatcher::OnChange(const Origin &origin, const PRIFields &primaryField } DistributedRdb::Origin rdbOrigin; rdbOrigin.origin = origin.origin; + rdbOrigin.dataType = origin.dataType; rdbOrigin.id = origin.id; rdbOrigin.store = origin.store; - // notifier->OnChange(rdbOrigin, primaryFields, std::move(values)) + notifier->OnChange(rdbOrigin, primaryFields, std::move(values)); return E_OK; } diff --git a/datamgr_service/services/distributeddataservice/service/rdb/value_proxy.cpp b/datamgr_service/services/distributeddataservice/service/rdb/value_proxy.cpp index fbd7c5f9..6b658009 100644 --- a/datamgr_service/services/distributeddataservice/service/rdb/value_proxy.cpp +++ b/datamgr_service/services/distributeddataservice/service/rdb/value_proxy.cpp @@ -14,7 +14,6 @@ */ #define LOG_TAG "ValueProxy" -#include "log_print.h" #include "value_proxy.h" namespace OHOS::DistributedRdb { using namespace OHOS::DistributedData; @@ -124,8 +123,11 @@ ValueProxy::Asset::Asset(DistributedData::Asset asset) ValueProxy::Asset::Asset(NativeRdb::AssetValue asset) { asset_ = DistributedData::Asset { .version = asset.version, + .status = asset.status, + .expiresTime = asset.timeStamp, .name = std::move(asset.name), .uri = std::move(asset.uri), + .path = std::move(asset.path), .createTime = std::move(asset.createTime), .modifyTime = std::move(asset.modifyTime), .size = std::move(asset.size), @@ -135,6 +137,8 @@ ValueProxy::Asset::Asset(NativeRdb::AssetValue asset) ValueProxy::Asset::Asset(DistributedDB::Asset asset) { asset_ = DistributedData::Asset { .version = asset.version, + .status = DistributedData::Asset::Status::STATUS_NORMAL, + .expiresTime = DistributedData::Asset::NO_EXPIRES_TIME, .name = std::move(asset.name), .uri = std::move(asset.uri), .createTime = std::move(asset.createTime), @@ -164,12 +168,15 @@ ValueProxy::Asset &ValueProxy::Asset::operator=(Asset &&proxy) noexcept ValueProxy::Asset::operator NativeRdb::AssetValue() { return NativeRdb::AssetValue { .version = asset_.version, + .status = asset_.status, + .timeStamp = asset_.expiresTime, .name = std::move(asset_.name), .uri = std::move(asset_.uri), .createTime = std::move(asset_.createTime), .modifyTime = std::move(asset_.modifyTime), .size = std::move(asset_.size), - .hash = std::move(asset_.hash) }; + .hash = std::move(asset_.hash), + .path = std::move(asset_.path)}; } ValueProxy::Asset::operator DistributedData::Asset() diff --git a/kv_store/frameworks/common/test/traits_test.cpp b/kv_store/frameworks/common/test/traits_test.cpp index dcaceb67..183ea911 100644 --- a/kv_store/frameworks/common/test/traits_test.cpp +++ b/kv_store/frameworks/common/test/traits_test.cpp @@ -28,6 +28,7 @@ public: }; class Convertible { public: + // Convertible is auto convert type, do not add explicit to stop the type convert. Convertible(const From &){}; Convertible(){} Convertible(Convertible &&) noexcept {}; @@ -206,7 +207,6 @@ HWTEST_F(TraitsTest, get_if_convertible_type, TestSize.Level0) value = int64_t(1); auto *fVal = Traits::get_if(&value); ASSERT_EQ(fVal, nullptr); - ASSERT_EQ(*fVal, 1); value = "test case"; auto *strVal = Traits::get_if(&value); diff --git a/kv_store/frameworks/common/traits.h b/kv_store/frameworks/common/traits.h index 34762ddb..4fa5a988 100644 --- a/kv_store/frameworks/common/traits.h +++ b/kv_store/frameworks/common/traits.h @@ -20,63 +20,63 @@ #include namespace OHOS { namespace Traits { -template +template struct index_of : std::integral_constant {}; -template +template inline constexpr size_t index_of_v = index_of::value; -template +template struct index_of : std::integral_constant ? 0 : index_of_v + 1> {}; // If there is one in the ...Types, that is equal to T. same_index_of_v is the index. // If there is no one in the ...Types, that is equal to T. same_index_of_v is sizeof ...(Types) -template +template inline constexpr size_t same_index_of_v = index_of::value; // There is one in the ...Types, that is equal to T. If not, the same_in_v will be false. -template +template inline constexpr bool same_in_v = (same_index_of_v < sizeof...(Types)); -template +template struct convertible_index_of : std::integral_constant {}; // If there is one in the ...Types that can convert to T implicitly, convertible_index_v is the index. // If there is no one in the ...Types that can convert to T implicitly, convertible_index_v is sizeof ...(Types) -template +template inline constexpr size_t convertible_index_of_v = convertible_index_of::value; -template +template struct convertible_index_of : std::integral_constant ? 0 : convertible_index_of_v + 1> {}; // There is one in the ...Types, that can convert to T implicitly. If not, the convertible_in_v will be false. -template +template inline constexpr bool convertible_in_v = (convertible_index_of_v < sizeof...(Types)); -template +template struct variant_size_of { static constexpr size_t value = sizeof...(Types); }; -template +template struct variant_index_of { static constexpr size_t value = same_index_of_v; }; -template +template variant_size_of variant_size_test(const std::variant &); -template +template variant_index_of variant_index_test(const T &, const std::variant &); // variant_index_of_v is the count of the variant V's types. -template +template inline constexpr size_t variant_size_of_v = decltype(variant_size_test(std::declval()))::value; // If T is one type of the variant V, variant_index_of_v is the index. If not, variant_index_of_v is the size. -template +template inline constexpr size_t variant_index_of_v = decltype(variant_index_test(std::declval(), std::declval()))::value; /* @@ -86,19 +86,19 @@ inline constexpr size_t variant_index_of_v = decltype(variant_index_test(std::de * the get_if will return it. * 3. When the _Tp is not a type in the ..._Types and can't convert, the get_if will return nullptr. * */ -template +template std::enable_if_t, T *> get_if(std::variant *input) { return std::get_if(input); } -template +template std::enable_if_t, const T *> get_if(const std::variant *input) { return std::get_if(input); } -template ? convertible_index_of_v : 0> +template ? convertible_index_of_v : 0> constexpr std::enable_if_t && (std::is_class_v && convertible_in_v), std::add_pointer_t>>> get_if(std::variant *input) @@ -106,7 +106,7 @@ get_if(std::variant *input) return std::get_if(input); } -template ? convertible_index_of_v : 0> +template ? convertible_index_of_v : 0> constexpr std::enable_if_t && (std::is_class_v && convertible_in_v), std::add_pointer_t>>> get_if(const std::variant *input) @@ -114,7 +114,7 @@ get_if(const std::variant *input) return std::get_if(input); } -template +template std::enable_if_t && (!std::is_class_v || !convertible_in_v), T *> get_if( std::variant *input) { @@ -122,7 +122,7 @@ std::enable_if_t && (!std::is_class_v || !convertible return nullptr; } -template +template std::enable_if_t && !convertible_in_v, const T *> get_if( const std::variant *input) { diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/include/store_observer.h b/kv_store/frameworks/libs/distributeddb/interfaces/include/store_observer.h index 3eebbb60..3cdb8d45 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/include/store_observer.h +++ b/kv_store/frameworks/libs/distributeddb/interfaces/include/store_observer.h @@ -29,6 +29,7 @@ enum ChangeType : uint32_t { }; struct ChangedData { std::string tableName; + int32_t type; // CLOUD_COOPERATION mode, primaryData store primary keys // primayData store row id if have no data std::vector> primaryData[OP_BUTT]; diff --git a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.cpp b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.cpp index 6da74a8e..f39b1e36 100644 --- a/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.cpp +++ b/kv_store/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_delegate_impl.cpp @@ -184,11 +184,14 @@ DBStatus RelationalStoreDelegateImpl::RemoveDeviceData() DBStatus RelationalStoreDelegateImpl::Sync(const std::vector &devices, SyncMode mode, const Query &query, const std::function&)> &onProcess, int64_t waitTime) { - std::map processes; - for (auto &device : devices) { - auto &process = processes[device]; - process.process = FINISHED; - process.errCode = OK; + if (onProcess) { + std::map processes; + for (auto &device : devices) { + auto &process = processes[device]; + process.process = FINISHED; + process.errCode = OK; + } + onProcess(processes); } return OK; } diff --git a/kv_store/test/unittest/distributedKVStore/DeviceKvStoreKVCallbackJsTest.js b/kv_store/test/unittest/distributedKVStore/DeviceKvStoreKVCallbackJsTest.js index 11bc52a6..b8c68db7 100644 --- a/kv_store/test/unittest/distributedKVStore/DeviceKvStoreKVCallbackJsTest.js +++ b/kv_store/test/unittest/distributedKVStore/DeviceKvStoreKVCallbackJsTest.js @@ -138,7 +138,7 @@ describe('DeviceKvStoreCallbackTest', function () { }); }); kvStore = null; - } catch (e) { + } catch (err) { console.error('afterEach closeKVStore err ' + `, error code is ${err.code}, message is ${err.message}`); } }) diff --git a/mock/sqlite/include/sqlite3.h b/mock/sqlite/include/sqlite3.h index 020b3ad8..c0a5e352 100644 --- a/mock/sqlite/include/sqlite3.h +++ b/mock/sqlite/include/sqlite3.h @@ -441,38 +441,38 @@ SQLITE_API int sqlite3_exec( ** ** See also: [extended result code definitions] */ -#define SQLITE_OK 0 /* Successful result */ -/* beginning-of-error-codes */ -#define SQLITE_ERROR 1 /* Generic error */ -#define SQLITE_INTERNAL 2 /* Internal logic error in SQLite */ -#define SQLITE_PERM 3 /* Access permission denied */ -#define SQLITE_ABORT 4 /* Callback routine requested an abort */ -#define SQLITE_BUSY 5 /* The database file is locked */ -#define SQLITE_LOCKED 6 /* A table in the database is locked */ -#define SQLITE_NOMEM 7 /* A malloc() failed */ -#define SQLITE_READONLY 8 /* Attempt to write a readonly database */ -#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/ -#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */ -#define SQLITE_CORRUPT 11 /* The database disk image is malformed */ -#define SQLITE_NOTFOUND 12 /* Unknown opcode in sqlite3_file_control() */ -#define SQLITE_FULL 13 /* Insertion failed because database is full */ -#define SQLITE_CANTOPEN 14 /* Unable to open the database file */ -#define SQLITE_PROTOCOL 15 /* Database lock protocol error */ -#define SQLITE_EMPTY 16 /* Internal use only */ -#define SQLITE_SCHEMA 17 /* The database schema changed */ -#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */ -#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */ -#define SQLITE_MISMATCH 20 /* Data type mismatch */ -#define SQLITE_MISUSE 21 /* Library used incorrectly */ -#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ -#define SQLITE_AUTH 23 /* Authorization denied */ -#define SQLITE_FORMAT 24 /* Not used */ -#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */ -#define SQLITE_NOTADB 26 /* File opened that is not a database file */ +#define SQLITE_OK 0 /* 成功 | Successful result */ +/* 错误码开始 */ +#define SQLITE_ERROR 1 /* SQL错误 或 丢失数据库 | SQL error or missing database */ +#define SQLITE_INTERNAL 2 /* SQLite 内部逻辑错误 | Internal logic error in SQLite */ +#define SQLITE_PERM 3 /* 拒绝访问 | Access permission denied */ +#define SQLITE_ABORT 4 /* 回调函数请求取消操作 | Callback routine requested an abort */ +#define SQLITE_BUSY 5 /* 数据库文件被锁定 | The database file is locked */ +#define SQLITE_LOCKED 6 /* 数据库中的一个表被锁定 | A table in the database is locked */ +#define SQLITE_NOMEM 7 /* 某次 malloc() 函数调用失败 | A malloc() failed */ +#define SQLITE_READONLY 8 /* 尝试写入一个只读数据库 | Attempt to write a readonly database */ +#define SQLITE_INTERRUPT 9 /* 操作被 sqlite3_interupt() 函数中断 | Operation terminated by sqlite3_interrupt() */ +#define SQLITE_IOERR 10 /* 发生某些磁盘 I/O 错误 | Some kind of disk I/O error occurred */ +#define SQLITE_CORRUPT 11 /* 数据库磁盘映像不正确 | The database disk image is malformed */ +#define SQLITE_NOTFOUND 12 /* sqlite3_file_control() 中出现未知操作数 | Unknown opcode in sqlite3_file_control() */ +#define SQLITE_FULL 13 /* 因为数据库满导致插入失败 | Insertion failed because database is full */ +#define SQLITE_CANTOPEN 14 /* 无法打开数据库文件 | Unable to open the database file */ +#define SQLITE_PROTOCOL 15 /* 数据库锁定协议错误 | Database lock protocol error */ +#define SQLITE_EMPTY 16 /* 数据库为空 | Database is empty */ +#define SQLITE_SCHEMA 17 /* 数据结构发生改变 | The database schema changed */ +#define SQLITE_TOOBIG 18 /* 字符串或二进制数据超过大小限制 | String or BLOB exceeds size limit */ +#define SQLITE_CONSTRAINT 19 /* 由于约束违例而取消 | Abort due to constraint violation */ +#define SQLITE_MISMATCH 20 /* 数据类型不匹配 | Data type mismatch */ +#define SQLITE_MISUSE 21 /* 不正确的库使用 | Library used incorrectly */ +#define SQLITE_NOLFS 22 /* 使用了操作系统不支持的功能 | Uses OS features not supported on host */ +#define SQLITE_AUTH 23 /* 授权失败 | Authorization denied */ +#define SQLITE_FORMAT 24 /* 附加数据库格式错误 | Auxiliary database format error */ +#define SQLITE_RANGE 25 /* 传递给sqlite3_bind()的第二个参数超出范围 | 2nd parameter to sqlite3_bind out of range */ +#define SQLITE_NOTADB 26 /* 被打开的文件不是一个数据库文件 | File opened that is not a database file */ #define SQLITE_NOTICE 27 /* Notifications from sqlite3_log() */ #define SQLITE_WARNING 28 /* Warnings from sqlite3_log() */ -#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */ -#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */ +#define SQLITE_ROW 100 /* sqlite3_step() 已经产生一个行结果 | sqlite3_step() has another row ready */ +#define SQLITE_DONE 101 /* sqlite3_step() 完成执行操作 | sqlite3_step() has finished executing */ /* end-of-error-codes */ /* diff --git a/mock/src/mock_device_manager.cpp b/mock/src/mock_device_manager.cpp index 4296e63a..05946456 100644 --- a/mock/src/mock_device_manager.cpp +++ b/mock/src/mock_device_manager.cpp @@ -41,7 +41,7 @@ int32_t DeviceManagerImpl::GetTrustedDeviceList(const std::string &pkgName, cons { DmDeviceInfo deviceInfo; GetLocalDeviceInfo(pkgName, deviceInfo); - for (int i = 0; i < 0; ++i) { + for (int i = 0; i < 5; ++i) { deviceInfo.networkId[0] = '0' + i; deviceInfo.deviceId[0] = '0' + i; deviceList.push_back(deviceInfo); diff --git a/relational_store/frameworks/js/napi/cloud_data/src/js_config.cpp b/relational_store/frameworks/js/napi/cloud_data/src/js_config.cpp index cb0dbd99..6c4309f2 100644 --- a/relational_store/frameworks/js/napi/cloud_data/src/js_config.cpp +++ b/relational_store/frameworks/js/napi/cloud_data/src/js_config.cpp @@ -176,7 +176,8 @@ napi_value JsConfig::ChangeAppCloudSwitch(napi_env env, napi_callback_info info) : napi_generic_failure; return; } - int32_t cStatus = proxy->ChangeAppSwitch(ctxt->accountId, ctxt->bundleName, ctxt->state); + int32_t cStatus = + proxy->ChangeAppSwitch(ctxt->accountId, ctxt->bundleName, ctxt->state ? CloudService::SWITCH_ON : CloudService::SWITCH_OFF); ZLOGD("ChangeAppCloudSwitch return %{public}d", cStatus); ctxt->status = (GenerateNapiError(cStatus, ctxt->jsCode, ctxt->error) == Status::SUCCESS) ? napi_ok diff --git a/relational_store/frameworks/js/napi/common/include/js_utils.h b/relational_store/frameworks/js/napi/common/include/js_utils.h index d003529d..1c7c7795 100644 --- a/relational_store/frameworks/js/napi/common/include/js_utils.h +++ b/relational_store/frameworks/js/napi/common/include/js_utils.h @@ -27,7 +27,6 @@ #include "napi/native_api.h" #include "napi/native_common.h" #include "napi/native_node_api.h" -#include "rdb_types.h" namespace OHOS { namespace AppDataMgrJsKit { @@ -41,13 +40,13 @@ constexpr int32_t ASYNC_RST_SIZE = 2; constexpr int32_t MAX_VALUE_LENGTH = 8 * 1024; constexpr int32_t SYNC_RESULT_ELEMNT_NUM = 2; -#ifndef AddJsProperty -#define AddJsProperty(env, object, value, member) \ +#ifndef ADD_JS_PROPERTY +#define ADD_JS_PROPERTY(env, object, value, member) \ napi_set_named_property((env), (object), #member, Convert2JSValue((env), (value).member)) #endif -#ifndef GetProperty -#define GetProperty(env, object, value, member) \ +#ifndef GET_PROPERTY +#define GET_PROPERTY(env, object, value, member) \ Convert2Value((env), GetNamedProperty((env), (object), #member), (value).member) #endif @@ -97,15 +96,10 @@ napi_value Convert2JSValue(napi_env env, int64_t value); napi_value Convert2JSValue(napi_env env, double value); napi_value Convert2JSValue(napi_env env, bool value); napi_value Convert2JSValue(napi_env env, const std::map &value); -napi_value Convert2JSValue(napi_env env, const DistributedRdb::Statistic &statistic); -napi_value Convert2JSValue(napi_env env, const DistributedRdb::TableDetail &tableDetail); -napi_value Convert2JSValue(napi_env env, const DistributedRdb::TableDetails &tableDetails); -napi_value Convert2JSValue(napi_env env, const DistributedRdb::ProgressDetail &progressDetail); -napi_value Convert2JSValue(napi_env env, const DistributedRdb::Details &details); napi_value Convert2JSValue(napi_env env, const std::monostate &value); template -napi_value Convert2JSValue(napi_env env, const T &value); +std::enable_if_t>, napi_value> Convert2JSValue(napi_env env, const T &value); template napi_value Convert2JSValue(napi_env env, const std::vector &value); diff --git a/relational_store/frameworks/js/napi/common/src/js_utils.cpp b/relational_store/frameworks/js/napi/common/src/js_utils.cpp index aaaef0ed..2da52015 100644 --- a/relational_store/frameworks/js/napi/common/src/js_utils.cpp +++ b/relational_store/frameworks/js/napi/common/src/js_utils.cpp @@ -17,6 +17,14 @@ #include "js_logger.h" +#define CHECK_RETURN_RET(assertion, message, revt) \ + do { \ + if (!(assertion)) { \ + LOG_WARN("assertion (" #assertion ") failed: " message); \ + return revt; \ + } \ + } while (0) + namespace OHOS { namespace AppDataMgrJsKit { static const std::map NAMESPACES = { @@ -282,24 +290,28 @@ int32_t JSUtils::Convert2Value(napi_env env, napi_value jsValue, std::map 0), "get_map failed!", ERR); + CHECK_RETURN_RET(status == napi_ok && jsCount > 0, "get_map failed", napi_invalid_arg); napi_value jsKey = nullptr; napi_value jsVal = nullptr; for (uint32_t index = 0; index < jsCount; index++) { status = napi_get_element(env, jsMapList, index, &jsKey); - NAPI_ASSERT_BASE(env, (jsKey != nullptr) && (status == napi_ok), "no element", ERR); + CHECK_RETURN_RET(status == napi_ok && jsKey != nullptr, "no element", napi_invalid_arg); std::string key; - Convert2Value(env, jsKey, key); + int ret = Convert2Value(env, jsKey, key); + CHECK_RETURN_RET(ret == napi_ok, "convert key failed", ret); status = napi_get_property(env, jsValue, jsKey, &jsVal); - NAPI_ASSERT_BASE(env, (jsVal != nullptr) && (status == napi_ok), "no element", ERR); + CHECK_RETURN_RET(status == napi_ok && jsVal != nullptr, "no element", napi_invalid_arg); int32_t val; - Convert2ValueExt(env, jsVal, val); + ret = Convert2ValueExt(env, jsVal, val); + CHECK_RETURN_RET(ret == napi_ok, "convert val failed", ret); output.insert(std::pair(key, val)); } - return OK; + return napi_ok; } + int32_t JSUtils::Convert2Value(napi_env env, napi_value jsValue, std::map &output) { LOG_DEBUG("napi_value -> std::map "); @@ -307,23 +319,26 @@ int32_t JSUtils::Convert2Value(napi_env env, napi_value jsValue, std::map 0), "get_map failed!", ERR); + CHECK_RETURN_RET(status == napi_ok && jsCount > 0, "get_map failed", napi_invalid_arg); napi_value jsKey = nullptr; napi_value jsVal = nullptr; for (uint32_t index = 0; index < jsCount; index++) { status = napi_get_element(env, jsMapList, index, &jsKey); - NAPI_ASSERT_BASE(env, (jsKey != nullptr) && (status == napi_ok), "no element", ERR); + CHECK_RETURN_RET(status == napi_ok && jsKey != nullptr, "no element", napi_invalid_arg); std::string key; - Convert2Value(env, jsKey, key); + int ret = Convert2Value(env, jsKey, key); + CHECK_RETURN_RET(ret == napi_ok, "convert key failed", ret); status = napi_get_property(env, jsValue, jsKey, &jsVal); - NAPI_ASSERT_BASE(env, (jsVal != nullptr) && (status == napi_ok), "no element", ERR); + CHECK_RETURN_RET(status == napi_ok && jsVal != nullptr, "no element", napi_invalid_arg); bool val; - Convert2Value(env, jsVal, val); + ret = Convert2Value(env, jsVal, val); + CHECK_RETURN_RET(ret == napi_ok, "convert val failed", ret); output.insert(std::pair(key, val)); } - return OK; + return napi_ok; } napi_value JSUtils::Convert2JSValue(napi_env env, const std::vector &value) @@ -441,82 +456,6 @@ napi_value JSUtils::Convert2JSValue(napi_env env, const std::map cont int errorCode = E_OK; std::string databaseName = context->config.GetName(); std::string databaseDir = context->abilitycontext->GetDatabaseDir(); - std::string realPath = SqliteDatabaseUtils::GetDefaultDatabasePath(databaseDir, databaseName, errorCode); + std::string realPath = RdbSqlUtils::GetDefaultDatabasePath(databaseDir, databaseName, errorCode); paramError = std::make_shared("config", "a StoreConfig."); RDB_CHECK_RETURN_CALL_RESULT(errorCode == E_OK, context->SetError(paramError)); context->config.SetPath(std::move(realPath)); @@ -394,7 +394,7 @@ int ParsePath(const napi_env &env, const napi_value &arg, std::shared_ptrabilitycontext->GetDatabaseDir(); int errorCode = E_OK; - std::string realPath = SqliteDatabaseUtils::GetDefaultDatabasePath(databaseDir, path, errorCode); + std::string realPath = RdbSqlUtils::GetDefaultDatabasePath(databaseDir, path, errorCode); RDB_CHECK_RETURN_CALL_RESULT(errorCode == E_OK, context->SetError(paramError)); context->config.SetPath(realPath); diff --git a/relational_store/frameworks/js/napi/relationalstore/include/napi_async_call.h b/relational_store/frameworks/js/napi/relationalstore/include/napi_async_call.h index 408f3a87..c1fa3427 100644 --- a/relational_store/frameworks/js/napi/relationalstore/include/napi_async_call.h +++ b/relational_store/frameworks/js/napi/relationalstore/include/napi_async_call.h @@ -34,6 +34,7 @@ using ExecuteAction = std::function; class Context { public: void SetAction(napi_env env, napi_callback_info info, InputAction input, ExecuteAction exec, OutputAction output); + void SetAll(napi_env env, napi_callback_info info, InputAction input, ExecuteAction exec, OutputAction output); void SetError(std::shared_ptr error); virtual ~Context(); diff --git a/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_js_utils.h b/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_js_utils.h index f7d95d29..6a0c5f4e 100644 --- a/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_js_utils.h +++ b/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_js_utils.h @@ -17,18 +17,38 @@ #define RDB_JSKIT_NAPI_RDB_JS_UTILS_H #include "asset_value.h" #include "js_utils.h" +#include "napi_rdb_store_observer.h" +#include "rdb_types.h" #include "result_set.h" #include "value_object.h" namespace OHOS::AppDataMgrJsKit { namespace JSUtils { using Asset = OHOS::NativeRdb::AssetValue; using RowEntity = OHOS::NativeRdb::RowEntity; +using JSChangeInfo = OHOS::RelationalStoreJsKit::NapiRdbStoreObserver::JSChangeInfo; template<> int32_t Convert2Value(napi_env env, napi_value input, Asset &output); +template<> +int32_t Convert2Value(napi_env env, napi_value input, DistributedRdb::DistributedConfig &output); + template<> napi_value Convert2JSValue(napi_env env, const Asset &value); template<> napi_value Convert2JSValue(napi_env env, const RowEntity &value); + +template<> +napi_value Convert2JSValue(napi_env env, const DistributedRdb::Statistic &statistic); +template<> +napi_value Convert2JSValue(napi_env env, const DistributedRdb::TableDetail &tableDetail); +template<> +napi_value Convert2JSValue(napi_env env, const DistributedRdb::TableDetails &tableDetails); +template<> +napi_value Convert2JSValue(napi_env env, const DistributedRdb::ProgressDetail &progressDetail); +template<> +napi_value Convert2JSValue(napi_env env, const DistributedRdb::Details &details); + +template<> +napi_value Convert2JSValue(napi_env env, const JSChangeInfo &value); }; // namespace JSUtils } // namespace OHOS::AppDataMgrJsKit #endif // RDB_JSKIT_NAPI_RDB_JS_UTILS_H diff --git a/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store.h b/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store.h index 5eac78f1..5a9eed60 100644 --- a/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store.h +++ b/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store.h @@ -81,7 +81,7 @@ private: explicit NapiCoudSyncCallback(napi_env env, napi_value callback) : NapiUvQueue(env, callback){} virtual ~NapiCoudSyncCallback() = default; - void OnSyncCompelete(const DistributedRdb::Details &details); + void OnSyncComplete(const DistributedRdb::Details &details); }; napi_value OnDataChangeEvent(napi_env env, size_t argc, napi_value *argv); diff --git a/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store_observer.h b/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store_observer.h index 1836eed3..0d193e25 100644 --- a/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store_observer.h +++ b/relational_store/frameworks/js/napi/relationalstore/include/napi_rdb_store_observer.h @@ -23,6 +23,14 @@ namespace OHOS::RelationalStoreJsKit { class NapiRdbStoreObserver : public DistributedRdb::RdbStoreObserver, public NapiUvQueue { public: using Origin = DistributedRdb::Origin; + struct JSChangeInfo { + JSChangeInfo(const Origin &origin, ChangeInfo::iterator info); + std::string table; + int32_t type; + std::vector inserted; + std::vector updated; + std::vector deleted; + }; explicit NapiRdbStoreObserver(napi_env env, napi_value callback, int32_t mode = DistributedRdb::REMOTE); virtual ~NapiRdbStoreObserver() noexcept; diff --git a/relational_store/frameworks/js/napi/relationalstore/include/napi_result_set.h b/relational_store/frameworks/js/napi/relationalstore/include/napi_result_set.h index 98c40e4e..3f6a0b55 100644 --- a/relational_store/frameworks/js/napi/relationalstore/include/napi_result_set.h +++ b/relational_store/frameworks/js/napi/relationalstore/include/napi_result_set.h @@ -18,6 +18,7 @@ #include +#include "asset_value.h" #include "napi/native_api.h" #include "napi/native_common.h" #include "napi/native_node_api.h" @@ -66,6 +67,8 @@ private: static napi_value IsAtFirstRow(napi_env env, napi_callback_info info); static napi_value IsAtLastRow(napi_env env, napi_callback_info info); static napi_value GetBlob(napi_env env, napi_callback_info info); + static napi_value GetAsset(napi_env env, napi_callback_info info); + static napi_value GetAssets(napi_env env, napi_callback_info info); static napi_value GetString(napi_env env, napi_callback_info info); static napi_value GetDouble(napi_env env, napi_callback_info info); static napi_value GetModifyTime(napi_env env, napi_callback_info info); diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_async_call.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_async_call.cpp index 4d71d664..9f33230a 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_async_call.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_async_call.cpp @@ -48,6 +48,25 @@ void Context::SetAction( napi_create_reference(env, self, 1, &self_); } +void Context::SetAll( + napi_env env, napi_callback_info info, InputAction input, ExecuteAction exec, OutputAction output) +{ + env_ = env; + size_t argc = MAX_INPUT_COUNT; + napi_value self = nullptr; + napi_value argv[MAX_INPUT_COUNT] = { nullptr }; + NAPI_CALL_RETURN_VOID(env, napi_get_cb_info(env, info, &argc, argv, &self, nullptr)); + + // int -->input_(env, argc, argv, self) + input(env, argc, argv, self); + + // if input return is not ok, then napi_throw_error context error + RDB_NAPI_ASSERT_BASE(env, error == nullptr, error, NAPI_RETVAL_NOTHING); + output_ = std::move(output); + exec_ = std::move(exec); + napi_create_reference(env, self, 1, &self_); +} + void Context::SetError(std::shared_ptr err) { error = err; diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_const_properties.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_const_properties.cpp index 7ef15430..709a59d4 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_const_properties.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_const_properties.cpp @@ -67,7 +67,8 @@ static napi_value ExportSubscribeType(napi_env env) napi_create_object(env, &subscribeType); SET_NAPI_PROPERTY(subscribeType, "SUBSCRIBE_TYPE_REMOTE", SubscribeMode::REMOTE); - SET_NAPI_PROPERTY(subscribeType, "SUBSCRIBE_TYPE_CLOUD", SubscribeMode::REMOTE); + SET_NAPI_PROPERTY(subscribeType, "SUBSCRIBE_TYPE_CLOUD", SubscribeMode::CLOUD); + SET_NAPI_PROPERTY(subscribeType, "SUBSCRIBE_TYPE_CLOUD_DETAIL", SubscribeMode::CLOUD_DETAIL); napi_object_freeze(env, subscribeType); return subscribeType; } diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_js_utils.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_js_utils.cpp index dd443b38..9301d508 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_js_utils.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_js_utils.cpp @@ -39,45 +39,65 @@ int32_t Convert2Value(napi_env env, napi_value jsValue, Asset &output) if (ret != napi_ok) { return napi_invalid_arg; } - ret = GetProperty(env, jsValue, output, name); + ret = GET_PROPERTY(env, jsValue, output, name); if (ret != napi_ok) { return napi_invalid_arg; } - ret = GetProperty(env, jsValue, output, uri); + ret = GET_PROPERTY(env, jsValue, output, uri); if (ret != napi_ok) { return napi_invalid_arg; } - ret = GetProperty(env, jsValue, output, createTime); + ret = GET_PROPERTY(env, jsValue, output, createTime); if (ret != napi_ok) { return napi_invalid_arg; } - ret = GetProperty(env, jsValue, output, modifyTime); + ret = GET_PROPERTY(env, jsValue, output, modifyTime); if (ret != napi_ok) { return napi_invalid_arg; } - ret = GetProperty(env, jsValue, output, size); + ret = GET_PROPERTY(env, jsValue, output, size); if (ret != napi_ok) { return napi_invalid_arg; } - ret = GetProperty(env, jsValue, output, hash); + ret = GET_PROPERTY(env, jsValue, output, hash); if (ret != napi_ok) { return napi_invalid_arg; } return napi_ok; } +template<> +int32_t Convert2Value(napi_env env, napi_value input, DistributedRdb::DistributedConfig &output) +{ + napi_valuetype type; + napi_status status = napi_typeof(env, input, &type); + if (status != napi_ok || type != napi_object) { + LOG_DEBUG("napi_typeof failed status = %{public}d type = %{public}d", status, type); + return napi_invalid_arg; + } + + auto ret = Convert2Value(env, GetNamedProperty(env, input, "autoSync"), output.autoSync); + if (ret != napi_ok) { + return napi_invalid_arg; + } + return ret; +} + template<> napi_value Convert2JSValue(napi_env env, const Asset &value) { napi_value object; - NAPI_CALL_BASE(env, napi_create_object(env, &object), object); - NAPI_CALL_BASE(env, AddJsProperty(env, object, value, version), object); - NAPI_CALL_BASE(env, AddJsProperty(env, object, value, name), object); - NAPI_CALL_BASE(env, AddJsProperty(env, object, value, uri), object); - NAPI_CALL_BASE(env, AddJsProperty(env, object, value, createTime), object); - NAPI_CALL_BASE(env, AddJsProperty(env, object, value, modifyTime), object); - NAPI_CALL_BASE(env, AddJsProperty(env, object, value, size), object); - NAPI_CALL_BASE(env, AddJsProperty(env, object, value, hash), object); + auto status = napi_create_object(env, &object); + if (status != napi_ok) { + return nullptr; + } + ADD_JS_PROPERTY(env, object, value, version); + ADD_JS_PROPERTY(env, object, value, name); + ADD_JS_PROPERTY(env, object, value, uri); + ADD_JS_PROPERTY(env, object, value, createTime); + ADD_JS_PROPERTY(env, object, value, modifyTime); + ADD_JS_PROPERTY(env, object, value, size); + ADD_JS_PROPERTY(env, object, value, hash); return object; } @@ -85,13 +105,132 @@ template<> napi_value Convert2JSValue(napi_env env, const RowEntity &rowEntity) { napi_value ret; - NAPI_CALL(env, napi_create_object(env, &ret)); + auto status = napi_create_object(env, &ret); + if (status != napi_ok) { + return nullptr; + } auto &values = rowEntity.Get(); for (auto const &[key, object] : values) { napi_value value = JSUtils::Convert2JSValue(env, object.value); - NAPI_CALL(env, napi_set_named_property(env, ret, key.c_str(), value)); + napi_set_named_property(env, ret, key.c_str(), value); } return ret; } + +template<> +napi_value Convert2JSValue(napi_env env, const DistributedRdb::Statistic &statistic) +{ + napi_value jsValue; + napi_status status = napi_create_object(env, &jsValue); + if (status != napi_ok) { + return nullptr; + } + napi_value total = Convert2JSValue(env, statistic.total); + napi_value success = Convert2JSValue(env, statistic.success); + napi_value failed = Convert2JSValue(env, statistic.failed); + napi_value untreated = Convert2JSValue(env, statistic.untreated); + + napi_set_named_property(env, jsValue, "total", total); + napi_set_named_property(env, jsValue, "success", success); + napi_set_named_property(env, jsValue, "failed", failed); + napi_set_named_property(env, jsValue, "untreated", untreated); + return jsValue; +} + +template<> +napi_value Convert2JSValue(napi_env env, const DistributedRdb::TableDetail &tableDetail) +{ + napi_value jsValue; + napi_status status = napi_create_object(env, &jsValue); + if (status != napi_ok) { + return nullptr; + } + napi_value upload = Convert2JSValue(env, tableDetail.upload); + napi_value download = Convert2JSValue(env, tableDetail.download); + napi_set_named_property(env, jsValue, "upload", upload); + napi_set_named_property(env, jsValue, "download", download); + return jsValue; +} + +template<> +napi_value Convert2JSValue(napi_env env, const DistributedRdb::TableDetails &tableDetails) +{ + napi_value jsValue; + napi_status status = napi_create_array_with_length(env, tableDetails.size(), &jsValue); + if (status != napi_ok) { + return nullptr; + } + + int index = 0; + for (const auto &[table, result] : tableDetails) { + napi_value jsElement = nullptr; + status = napi_create_array_with_length(env, 2, &jsElement); + napi_value key = Convert2JSValue(env, table); + napi_set_element(env, jsElement, 0, key); + napi_value value = Convert2JSValue(env, result); + napi_set_element(env, jsElement, 1, value); + napi_set_element(env, jsValue, index++, jsElement); + } + return jsValue; +} + +template<> +napi_value Convert2JSValue(napi_env env, const DistributedRdb::ProgressDetail &progressDetail) +{ + napi_value jsValue; + napi_status status = napi_create_object(env, &jsValue); + if (status != napi_ok) { + return nullptr; + } + napi_value schedule = Convert2JSValue(env, progressDetail.progress); + napi_value code = Convert2JSValue(env, progressDetail.code); + napi_value details = Convert2JSValue(env, progressDetail.details); + if (details == nullptr) { + return nullptr; + } + napi_set_named_property(env, jsValue, "schedule", schedule); + napi_set_named_property(env, jsValue, "code", code); + napi_set_named_property(env, jsValue, "details", details); + return jsValue; +} + +template<> +napi_value Convert2JSValue(napi_env env, const DistributedRdb::Details &details) +{ + napi_value jsValue; + napi_status status = napi_create_array_with_length(env, details.size(), &jsValue); + if (status != napi_ok) { + return nullptr; + } + + int index = 0; + for (const auto &[device, result] : details) { + napi_value jsElement; + status = napi_create_array_with_length(env, 2, &jsElement); + if (status != napi_ok) { + return nullptr; + } + napi_set_element(env, jsElement, 0, Convert2JSValue(env, device)); + napi_set_element(env, jsElement, 1, Convert2JSValue(env, result)); + napi_set_element(env, jsValue, index++, jsElement); + } + return nullptr; +} + +template<> +napi_value Convert2JSValue(napi_env env, const JSChangeInfo &value) +{ + napi_value object; + auto status = napi_create_object(env, &object); + if (status != napi_ok) { + return nullptr; + } + ADD_JS_PROPERTY(env, object, value, table); + ADD_JS_PROPERTY(env, object, value, type); + ADD_JS_PROPERTY(env, object, value, inserted); + ADD_JS_PROPERTY(env, object, value, updated); + ADD_JS_PROPERTY(env, object, value, deleted); + return object; +} }; // namespace JSUtils } // namespace OHOS::AppDataMgrJsKit \ No newline at end of file diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store.cpp index 5013c2ca..1efff5cb 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store.cpp @@ -74,7 +74,16 @@ struct RdbStoreContext : public Context { std::string pathName; std::string destName; std::string srcName; - int32_t enumArg; + union { + int32_t enumArg; + int32_t distributedType; + int32_t syncMode; + }; + + DistributedRdb::DistributedConfig distributedConfig; + + Details details; + NativeRdb::ConflictResolution conflictResolution; #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) DistributedRdb::SyncResult syncResult; @@ -275,17 +284,48 @@ int ParseSyncModeArg(const napi_env &env, const napi_value &arg, std::shared_ptr return OK; } +int ParseDistributedTableArg(const napi_env &env, size_t argc, napi_value * argv, std::shared_ptr context) +{ + context->distributedType = DistributedRdb::DISTRIBUTED_DEVICE; + if (argc > 1) { + auto status = JSUtils::Convert2ValueExt(env, argv[1], context->distributedType); + bool checked = (status == napi_ok && context->distributedType >= DistributedRdb::DISTRIBUTED_DEVICE + && context->distributedType <= DistributedRdb::DISTRIBUTED_CLOUD); + CHECK_RETURN_SET(checked, std::make_shared("mode", "a DistributedType")); + } + LOG_DEBUG("ParseDistributedTableArg end"); + return OK; +} + +int ParseDistributedConfigArg(const napi_env &env, size_t argc, napi_value * argv, std::shared_ptr context) +{ + context->distributedConfig = { false }; + if (argc > 2) { + auto status = JSUtils::Convert2Value(env, argv[2], context->distributedConfig); + CHECK_RETURN_SET(status == napi_ok, std::make_shared("distributedConfig", "a DistributedConfig type")); + } + LOG_DEBUG("ParseDistributedConfigArg end"); + return OK; +} + int ParseCloudSyncModeArg(const napi_env &env, const napi_value &arg, std::shared_ptr context) { - napi_valuetype type = napi_undefined; - napi_typeof(env, arg, &type); - CHECK_RETURN_SET(type == napi_number, std::make_shared("mode", "a SyncMode Type.")); - napi_status status = napi_get_value_int32(env, arg, &context->enumArg); - CHECK_RETURN_SET(status == napi_ok, std::make_shared("mode", "a SyncMode Type.")); - bool checked = (context->enumArg > 2 && context->enumArg <= 5); + auto status = JSUtils::Convert2ValueExt(env, arg, context->syncMode); + bool checked = (status == napi_ok && context->syncMode >= DistributedRdb::TIME_FIRST + && context->syncMode <= DistributedRdb::CLOUD_FIRST); CHECK_RETURN_SET(checked, std::make_shared("mode", "a SyncMode of cloud.")); + LOG_DEBUG("ParseCloudSyncModeArg end"); + return OK; +} - LOG_DEBUG("ParseSyncModeArg end"); +int ParseCloudSyncCallback(const napi_env &env, const napi_value &arg, std::shared_ptr context) +{ + napi_valuetype valueType = napi_undefined; + napi_typeof(env, arg, &valueType); + CHECK_RETURN_SET(valueType == napi_function, std::make_shared("a callback type")); + context->cloudSyncCallback = arg; + + LOG_DEBUG("ParseCloudSyncCallback end"); return OK; } @@ -1028,24 +1068,17 @@ napi_value RdbStoreProxy::SetDistributedTables(napi_env env, napi_callback_info LOG_DEBUG("RdbStoreProxy::SetDistributedTables start"); auto context = std::make_shared(); auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { - CHECK_RETURN_SET_E(argc == 1 || argc == 2, std::make_shared("1 - 3")); + CHECK_RETURN_SET_E(1 <= argc && argc <= 3, std::make_shared("1 - 4")); CHECK_RETURN(OK == ParserThis(env, self, context)); CHECK_RETURN(OK == ParseTablesName(env, argv[0], context)); - if (argc == 2) { - napi_valuetype type = napi_undefined; - napi_typeof(env, argv[1], &type); - CHECK_RETURN_SET_E(type == napi_number && napi_get_value_int32(env, argv[1], &context->enumArg) == napi_ok, - std::make_shared("mode", "a SyncMode Type.")); - bool checked = context->enumArg == 0 || context->enumArg == 1; - CHECK_RETURN_SET_E(checked, std::make_shared("mode", "a SyncMode of device.")); - } else { - context->enumArg = 0; - } + CHECK_RETURN(OK == ParseDistributedTableArg(env, argc, argv, context)); + CHECK_RETURN(OK == ParseDistributedConfigArg(env, argc, argv, context)); }; auto exec = [context]() -> int { LOG_DEBUG("RdbStoreProxy::SetDistributedTables Async"); RdbStoreProxy *obj = reinterpret_cast(context->boundObj); - return obj->rdbStore_->SetDistributedTables(context->tablesNames, context->enumArg); + return obj->rdbStore_->SetDistributedTables( + context->tablesNames, context->distributedType, context->distributedConfig); }; auto output = [context](napi_env env, napi_value &result) { napi_status status = napi_get_undefined(env, &result); @@ -1122,7 +1155,7 @@ napi_value RdbStoreProxy::CloudSync(napi_env env, napi_callback_info info) LOG_DEBUG("RdbStoreProxy::CloudSync start"); auto context = std::make_shared(); auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) { - CHECK_RETURN_SET_E(argc == 2 || argc == 3, std::make_shared("2 - 4")); + CHECK_RETURN_SET_E(1 < argc && argc < 5, std::make_shared("2 - 4")); CHECK_RETURN(OK == ParserThis(env, self, context)); CHECK_RETURN(OK == ParseCloudSyncModeArg(env, argv[0], context)); uint32_t index = 1; @@ -1132,21 +1165,29 @@ napi_value RdbStoreProxy::CloudSync(napi_env env, napi_callback_info info) CHECK_RETURN(OK == ParseTablesName(env, argv[index], context)); index++; } - napi_valuetype valueType = napi_undefined; - napi_typeof(env, argv[index], &valueType); - CHECK_RETURN_SET_E(valueType == napi_function, std::make_shared("a callback type")); - context->cloudSyncCallback = argv[index]; + CHECK_RETURN(OK == ParseCloudSyncCallback(env, argv[index++], context)); + CHECK_RETURN_SET_E(index == argc - 1 || index == argc, std::make_shared("2 - 4")); + if(index == argc - 1){ + //get callback + napi_valuetype valueType = napi_undefined; + napi_typeof(env, argv[index], &valueType); + if (valueType == napi_function) { + LOG_INFO("asyncCall set callback"); + NAPI_CALL_RETURN_VOID(env, napi_create_reference(env, argv[index], 1, &context->callback_)); + } + } + LOG_INFO("RdbStoreProxy::CloudSync 6"); }; auto exec = [context]() -> int { LOG_DEBUG("RdbStoreProxy::CloudSync Async"); auto *obj = reinterpret_cast(context->boundObj); SyncOption option; - option.mode = static_cast(context->enumArg); - option.isBlock = true; + option.mode = static_cast(context->syncMode); + option.isBlock = false; return obj->rdbStore_->Sync(option, context->tablesNames, [context](const Details &details) { auto callback = std::make_shared(context->env_, context->cloudSyncCallback); - callback->OnSyncCompelete(details); + callback->OnSyncComplete(context->details); }); }; @@ -1156,7 +1197,7 @@ napi_value RdbStoreProxy::CloudSync(napi_env env, napi_callback_info info) CHECK_RETURN_SET_E(status == napi_ok, std::make_shared(E_ERROR)); }; - context->SetAction(env, info, input, exec, output); + context->SetAll(env, info, input, exec, output); CHECK_RETURN_NULL(context->error == nullptr || context->error->GetCode() == OK); return AsyncCall::Call(env, context); @@ -1260,7 +1301,7 @@ napi_value RdbStoreProxy::OffEvent(napi_env env, napi_callback_info info) return nullptr; } -void RdbStoreProxy::NapiCoudSyncCallback::OnSyncCompelete(const DistributedRdb::Details &details) +void RdbStoreProxy::NapiCoudSyncCallback::OnSyncComplete(const DistributedRdb::Details &details) { LOG_DEBUG("NapiCoudSyncCallback::OnSyncCompelete begin"); CallFunction([details](napi_env env, int &argc, napi_value *argv) { diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store_helper.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store_helper.cpp index 8b02ac3b..a479a8c4 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store_helper.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store_helper.cpp @@ -26,8 +26,8 @@ #include "napi_rdb_trace.h" #include "rdb_errno.h" #include "rdb_open_callback.h" +#include "rdb_sql_utils.h" #include "rdb_store_config.h" -#include "sqlite_database_utils.h" #include "unistd.h" using namespace OHOS::NativeRdb; @@ -106,7 +106,7 @@ int ParseDatabaseDir(const napi_env &env, std::shared_ptr cont int errorCode = E_OK; std::string databaseName = context->config.GetName(); std::string databaseDir = context->abilitycontext->GetDatabaseDir(); - std::string realPath = SqliteDatabaseUtils::GetDefaultDatabasePath(databaseDir, databaseName, errorCode); + std::string realPath = RdbSqlUtils::GetDefaultDatabasePath(databaseDir, databaseName, errorCode); CHECK_RETURN_SET(errorCode == E_OK, std::make_shared("config", "a StoreConfig.")); context->config.SetPath(std::move(realPath)); return OK; @@ -156,7 +156,7 @@ int ParsePath(const napi_env &env, const napi_value &arg, std::shared_ptrabilitycontext->GetDatabaseDir(); int errorCode = E_OK; - std::string realPath = SqliteDatabaseUtils::GetDefaultDatabasePath(databaseDir, path, errorCode); + std::string realPath = RdbSqlUtils::GetDefaultDatabasePath(databaseDir, path, errorCode); CHECK_RETURN_SET(errorCode == E_OK, std::make_shared("path", "access")); context->config.SetPath(realPath); diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store_observer.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store_observer.cpp index c9d5f719..d95010d6 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store_observer.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_rdb_store_observer.cpp @@ -46,11 +46,25 @@ void NapiRdbStoreObserver::OnChange(const std::vector &devices) void NapiRdbStoreObserver::OnChange(const Origin &origin, const PrimaryFields &fields, ChangeInfo &&changeInfo) { if (mode_ == DistributedRdb::CLOUD_DETAIL) { - CallFunction([info = std::move(changeInfo)](napi_env env, int &argc, napi_value *argv) { + std::vector infos; + for (auto it = changeInfo.begin(); it != changeInfo.end(); ++it) { + infos.push_back(JSChangeInfo(origin, it)); + } + CallFunction([infos = std::move(infos)](napi_env env, int &argc, napi_value *argv) { argc = 1; - // todo argv[0] = JSUtils::Convert2JSValue(env, info); + argv[0] = JSUtils::Convert2JSValue(env, infos); }); + return; } RdbStoreObserver::OnChange(origin, fields, std::move(changeInfo)); } + +NapiRdbStoreObserver::JSChangeInfo::JSChangeInfo(const Origin &origin, ChangeInfo::iterator info) +{ + table = info->first; + type = origin.dataType; + inserted = std::move(info->second[CHG_TYPE_INSERT]); + updated = std::move(info->second[CHG_TYPE_UPDATE]); + deleted = std::move(info->second[CHG_TYPE_DELETE]); +} } // namespace OHOS::RelationalStoreJsKit \ No newline at end of file diff --git a/relational_store/frameworks/js/napi/relationalstore/src/napi_result_set.cpp b/relational_store/frameworks/js/napi/relationalstore/src/napi_result_set.cpp index 88a4f7cf..676dee96 100644 --- a/relational_store/frameworks/js/napi/relationalstore/src/napi_result_set.cpp +++ b/relational_store/frameworks/js/napi/relationalstore/src/napi_result_set.cpp @@ -32,6 +32,8 @@ using namespace OHOS::AppDataMgrJsKit; namespace OHOS { namespace RelationalStoreJsKit { +using Asset = AssetValue; +using Assets = std::vector; static napi_ref __thread ctorRef_ = nullptr; static const int E_OK = 0; @@ -89,6 +91,8 @@ napi_value ResultSetProxy::GetConstructor(napi_env env) DECLARE_NAPI_FUNCTION("goToPreviousRow", GoToPreviousRow), DECLARE_NAPI_FUNCTION("getInt", GetInt), DECLARE_NAPI_FUNCTION("getBlob", GetBlob), + DECLARE_NAPI_FUNCTION("getAsset", GetAsset), + DECLARE_NAPI_FUNCTION("getAssets", GetAssets), DECLARE_NAPI_FUNCTION("getString", GetString), DECLARE_NAPI_FUNCTION("getDouble", GetDouble), DECLARE_NAPI_FUNCTION("getModifyTime", GetModifyTime), @@ -440,6 +444,34 @@ napi_value ResultSetProxy::GetBlob(napi_env env, napi_callback_info info) return JSUtils::Convert2JSValue(env, result); } +napi_value ResultSetProxy::GetAsset(napi_env env, napi_callback_info info) +{ + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); + int32_t columnIndex; + auto resultSetProxy = ParseInt32FieldByName(env, info, columnIndex, "columnIndex"); + CHECK_RETURN_NULL(resultSetProxy && resultSetProxy->resultSet_); + + Asset result; + int errCode = resultSetProxy->resultSet_->GetAsset(columnIndex, result); + RDB_NAPI_ASSERT(env, errCode == E_OK, std::make_shared(errCode)); + + return JSUtils::Convert2JSValue(env, result); +} + +napi_value ResultSetProxy::GetAssets(napi_env env, napi_callback_info info) +{ + DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); + int32_t columnIndex; + auto resultSetProxy = ParseInt32FieldByName(env, info, columnIndex, "columnIndex"); + CHECK_RETURN_NULL(resultSetProxy && resultSetProxy->resultSet_); + + Assets result; + int errCode = resultSetProxy->resultSet_->GetAssets(columnIndex, result); + RDB_NAPI_ASSERT(env, errCode == E_OK, std::make_shared(errCode)); + + return JSUtils::Convert2JSValue(env, result); +} + napi_value ResultSetProxy::GetString(napi_env env, napi_callback_info info) { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); diff --git a/relational_store/frameworks/native/appdatafwk/src/general_endian.cpp b/relational_store/frameworks/native/appdatafwk/src/general_endian.cpp new file mode 100644 index 00000000..859013af --- /dev/null +++ b/relational_store/frameworks/native/appdatafwk/src/general_endian.cpp @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2023 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "multi_platform_endian.h" +#include + +namespace OHOS { +uint16_t Endian::LeToH(uint16_t value) +{ + return le16toh(value); +} +uint16_t Endian::HToLe(uint16_t value) +{ + return htole16(value); +} +} diff --git a/relational_store/frameworks/native/appdatafwk/src/mingw_endian.cpp b/relational_store/frameworks/native/appdatafwk/src/mingw_endian.cpp new file mode 100644 index 00000000..7642fa7f --- /dev/null +++ b/relational_store/frameworks/native/appdatafwk/src/mingw_endian.cpp @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2023 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "multi_platform_endian.h" + +namespace OHOS { +__attribute__((weak)) uint16_t Endian::LeToH(uint16_t value) +{ + return value; +} +__attribute__((weak)) uint16_t Endian::HToLe(uint16_t value) +{ + return value; +} +} diff --git a/relational_store/frameworks/native/appdatafwk/src/serializable.cpp b/relational_store/frameworks/native/appdatafwk/src/serializable.cpp new file mode 100644 index 00000000..a920c36b --- /dev/null +++ b/relational_store/frameworks/native/appdatafwk/src/serializable.cpp @@ -0,0 +1,208 @@ +/* + * 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 "serializable.h" +namespace OHOS { +Serializable::json Serializable::Marshall() const +{ + json root; + Marshal(root); + return root; +} + +bool Serializable::Unmarshall(const std::string &jsonStr) +{ + json jsonObj = json::parse(jsonStr, nullptr, false); + if (jsonObj.is_discarded()) { + // if the string size is less than 1, means the string is invalid. + if (jsonStr.empty()) { + return false; + } + jsonObj = json::parse(jsonStr.substr(1), nullptr, false); // drop first char to adapt A's value; + if (jsonObj.is_discarded()) { + return false; + } + } + return Unmarshal(jsonObj); +} + +Serializable::json Serializable::ToJson(const std::string &jsonStr) +{ + json jsonObj = json::parse(jsonStr, nullptr, false); + if (jsonObj.is_discarded()) { + // if the string size is less than 1, means the string is invalid. + if (jsonStr.empty()) { + return {}; + } + jsonObj = json::parse(jsonStr.substr(1), nullptr, false); // drop first char to adapt A's value; + if (jsonObj.is_discarded()) { + return {}; + } + } + return jsonObj; +} + +bool Serializable::IsJson(const std::string &jsonStr) +{ + if (!json::accept(jsonStr)) { + return json::accept(jsonStr.begin() + 1, jsonStr.end()); + } + return true; +} + +bool Serializable::GetValue(const json &node, const std::string &name, std::string &value) +{ + auto &subNode = GetSubNode(node, name); + if (subNode.is_null() || !subNode.is_string()) { + return false; + } + value = subNode; + return true; +} + +bool Serializable::GetValue(const json &node, const std::string &name, uint32_t &value) +{ + auto &subNode = GetSubNode(node, name); + if (subNode.is_null() || !subNode.is_number_unsigned()) { + return false; + } + subNode.get_to(value); + return true; +} + +bool Serializable::GetValue(const json &node, const std::string &name, int32_t &value) +{ + auto &subNode = GetSubNode(node, name); + if (subNode.is_null() || !subNode.is_number_integer()) { + return false; + } + subNode.get_to(value); + return true; +} + +bool Serializable::GetValue(const json &node, const std::string &name, uint64_t &value) +{ + auto &subNode = GetSubNode(node, name); + if (subNode.is_null() || !subNode.is_number_integer()) { + return false; + } + subNode.get_to(value); + return true; +} + +bool Serializable::GetValue(const json &node, const std::string &name, int64_t &value) +{ + auto &subNode = GetSubNode(node, name); + if (subNode.is_null() || !subNode.is_number_integer()) { + return false; + } + subNode.get_to(value); + return true; +} + +bool Serializable::GetValue(const json &node, const std::string &name, bool &value) +{ + auto &subNode = GetSubNode(node, name); + if (subNode.is_null() || !subNode.is_boolean()) { + return false; + } + subNode.get_to(value); + return true; +} + +bool Serializable::GetValue(const json &node, const std::string &name, std::vector &value) +{ + auto &subNode = GetSubNode(node, name); + if (subNode.is_null() || !subNode.is_array()) { + return false; + } + value = std::vector(subNode); + return true; +} + +bool Serializable::GetValue(const json &node, const std::string &name, Serializable &value) +{ + auto &subNode = GetSubNode(node, name); + if (subNode.is_null() || !subNode.is_object()) { + return false; + } + return value.Unmarshal(subNode); +} + +bool Serializable::SetValue(json &node, const std::string &value) +{ + node = value; + return true; +} + +bool Serializable::SetValue(json &node, const uint32_t &value) +{ + node = value; + return true; +} + +bool Serializable::SetValue(json &node, const int32_t &value) +{ + node = value; + return true; +} + +bool Serializable::SetValue(json &node, const uint64_t &value) +{ + node = value; + return true; +} + +bool Serializable::SetValue(json &node, const int64_t &value) +{ + node = value; + return true; +} + +bool Serializable::SetValue(json &node, const bool &value) +{ + node = value; + return true; +} + +bool Serializable::SetValue(json &node, const std::vector &value) +{ + node = value; + return true; +} + +bool Serializable::SetValue(json &node, const Serializable &value) +{ + return value.Marshal(node); +} + +const Serializable::json &Serializable::GetSubNode(const json &node, const std::string &name) +{ + static const json jsonNull = json::value_t::null; + if (node.is_discarded() || node.is_null()) { + return jsonNull; + } + + if (name.empty()) { + return node; + } + + auto it = node.find(name); + if (it == node.end()) { + return jsonNull; + } + return *it; +} +} // namespace OHOS diff --git a/relational_store/frameworks/native/rdb/include/raw_data_parser.h b/relational_store/frameworks/native/rdb/include/raw_data_parser.h index 94faaff7..e34047a1 100644 --- a/relational_store/frameworks/native/rdb/include/raw_data_parser.h +++ b/relational_store/frameworks/native/rdb/include/raw_data_parser.h @@ -15,6 +15,8 @@ #ifndef OHOS_DISTRIBUTED_DATA_RELATIONAL_STORE_FRAMEWORKS_NATIVE_RDB_PARSER_H #define OHOS_DISTRIBUTED_DATA_RELATIONAL_STORE_FRAMEWORKS_NATIVE_RDB_PARSER_H + +#include "serializable.h" #include "traits.h" #include "value_object.h" namespace OHOS::NativeRdb { @@ -30,6 +32,14 @@ public: static std::vector PackageRawData(const Assets &assets); private: + struct InnerAsset : public Serializable { + Asset &asset_; + explicit InnerAsset(Asset &asset) : asset_(asset) {} + + bool Marshal(json &node) const override; + bool Unmarshal(const json &node) override; + }; + template static bool Get(T &&input, O &output) { @@ -46,6 +56,8 @@ private: } return Get(std::move(input), output); } + static constexpr const uint32_t ASSET_MAGIC = 0x41534554; + static constexpr const uint32_t ASSETS_MAGIC = 0x41534553; }; template diff --git a/relational_store/frameworks/native/rdb/include/rdb_service_proxy.h b/relational_store/frameworks/native/rdb/include/rdb_service_proxy.h index 62dd8cf7..4d0af985 100644 --- a/relational_store/frameworks/native/rdb/include/rdb_service_proxy.h +++ b/relational_store/frameworks/native/rdb/include/rdb_service_proxy.h @@ -41,7 +41,7 @@ public: int32_t type = DISTRIBUTED_DEVICE) override; int32_t Sync(const RdbSyncerParam& param, const Option& option, - const RdbPredicates& predicates, const AsyncDetail &async) override; + const PredicatesMemo& predicates, const AsyncDetail &async) override; int32_t Subscribe(const RdbSyncerParam& param, const SubscribeOption& option, RdbStoreObserver *observer) override; @@ -55,20 +55,19 @@ public: void ImportObservers(ObserverMap& observers); - /*CLoudData*/ int32_t GetSchema(const RdbSyncerParam ¶m) override; private: using ChangeInfo = RdbStoreObserver::ChangeInfo; using PrimaryFields = RdbStoreObserver::PrimaryFields; std::pair DoSync(const RdbSyncerParam ¶m, const Option &option, - const RdbPredicates &predicates); + const PredicatesMemo &predicates); - int32_t DoAsync(const RdbSyncerParam ¶m, const Option &option, const RdbPredicates &predicates); + int32_t DoAsync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &predicates); - int32_t DoSync(const RdbSyncerParam ¶m, const Option &option, const RdbPredicates &predicates, + int32_t DoSync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &predicates, const AsyncDetail &async); - int32_t DoAsync(const RdbSyncerParam ¶m, const Option &option, const RdbPredicates &predicates, + int32_t DoAsync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &predicates, const AsyncDetail &async); int32_t DoSubscribe(const RdbSyncerParam& param, const SubscribeOption &option); diff --git a/relational_store/frameworks/native/rdb/include/rdb_store_impl.h b/relational_store/frameworks/native/rdb/include/rdb_store_impl.h index 2fc02854..d8862029 100644 --- a/relational_store/frameworks/native/rdb/include/rdb_store_impl.h +++ b/relational_store/frameworks/native/rdb/include/rdb_store_impl.h @@ -26,7 +26,6 @@ #include "rdb_store_config.h" #include "sqlite_connection_pool.h" #include "sqlite_statement.h" -#include "transaction_observer.h" namespace OHOS { class ExecutorPool; @@ -86,7 +85,7 @@ public: int Restore(const std::string &backupPath, const std::vector &newKey) override; int ChangeDbFileForRestore(const std::string &newPath, const std::string &backupPath, const std::vector &newKey) override; - void GetSchema(); + void GetSchema(const RdbStoreConfig &config); //std::string GetName(); std::string GetOrgPath(); @@ -104,7 +103,8 @@ public: std::shared_ptr RemoteQuery(const std::string &device, const AbsRdbPredicates &predicates, const std::vector &columns, int &errCode) override; - int SetDistributedTables(const std::vector& tables, int32_t type) override; + int SetDistributedTables(const std::vector &tables, int32_t type, + const DistributedRdb::DistributedConfig &distributedConfig) override; std::string ObtainDistributedTableName(const std::string& device, const std::string& table, int &errCode) override; @@ -129,6 +129,7 @@ private: int GetDataBasePath(const std::string &databasePath, std::string &backupFilePath); int ExecuteSqlInner(const std::string &sql, std::vector &&bindArgs); int ExecuteGetLongInner(const std::string &sql, std::vector &&bindArgs); + void DoCloudSync(const std::string &table); const RdbStoreConfig rdbStoreConfig; SqliteConnectionPool *connectionPool; @@ -142,6 +143,13 @@ private: DistributedRdb::RdbSyncerParam syncerParam_; bool isEncrypt_; std::shared_ptr pool_; + + mutable std::shared_mutex rwMutex_; + static inline constexpr uint32_t INTERVAL = 500; + std::set cloudTables_; + + std::mutex mutex_; + std::shared_ptr> syncTables_; }; } // namespace OHOS::NativeRdb #endif diff --git a/relational_store/frameworks/native/rdb/include/rdb_types_util.h b/relational_store/frameworks/native/rdb/include/rdb_types_util.h index ba0df675..60fe7b18 100644 --- a/relational_store/frameworks/native/rdb/include/rdb_types_util.h +++ b/relational_store/frameworks/native/rdb/include/rdb_types_util.h @@ -25,7 +25,7 @@ namespace OHOS::ITypesUtil { using SubOption = DistributedRdb::SubscribeOption; using SyncerParam = DistributedRdb::RdbSyncerParam; using Option = DistributedRdb::RdbService::Option; -using RdbPredicates = DistributedRdb::RdbPredicates; +using RdbPredicates = DistributedRdb::PredicatesMemo; using RdbOperation = DistributedRdb::RdbPredicateOperation; using ValueObject = NativeRdb::ValueObject; using ValuesBucket = NativeRdb::ValuesBucket; diff --git a/relational_store/frameworks/native/rdb/include/sqlite_shared_result_set.h b/relational_store/frameworks/native/rdb/include/sqlite_shared_result_set.h index e3c0999a..a4cdcd5e 100644 --- a/relational_store/frameworks/native/rdb/include/sqlite_shared_result_set.h +++ b/relational_store/frameworks/native/rdb/include/sqlite_shared_result_set.h @@ -60,7 +60,6 @@ private: bool isOnlyFillResultSetBlock; std::string qrySql; std::vector selectionArgVec; - std::shared_ptr sqliteStatement; // The number of rows in the cursor int rowNum; std::vector columnNames_; diff --git a/relational_store/frameworks/native/rdb/mock/include/rdb_store_impl.h b/relational_store/frameworks/native/rdb/mock/include/rdb_store_impl.h index 2cfc754d..0a066284 100644 --- a/relational_store/frameworks/native/rdb/mock/include/rdb_store_impl.h +++ b/relational_store/frameworks/native/rdb/mock/include/rdb_store_impl.h @@ -26,7 +26,6 @@ #include "rdb_store_config.h" #include "sqlite_connection_pool.h" #include "sqlite_statement.h" -#include "transaction_observer.h" namespace OHOS::NativeRdb { class RdbStoreImpl : public RdbStore, public std::enable_shared_from_this { @@ -105,6 +104,7 @@ private: int GetDataBasePath(const std::string &databasePath, std::string &backupFilePath); int ExecuteSqlInner(const std::string &sql, const std::vector &bindArgs); int ExecuteGetLongInner(const std::string &sql, const std::vector &bindArgs); + void DoCloudSync(const std::string &table); const RdbStoreConfig rdbStoreConfig; SqliteConnectionPool *connectionPool; diff --git a/relational_store/frameworks/native/rdb/src/abs_rdb_predicates.cpp b/relational_store/frameworks/native/rdb/src/abs_rdb_predicates.cpp index c892f201..1f7817ef 100644 --- a/relational_store/frameworks/native/rdb/src/abs_rdb_predicates.cpp +++ b/relational_store/frameworks/native/rdb/src/abs_rdb_predicates.cpp @@ -168,7 +168,7 @@ AbsRdbPredicates* AbsRdbPredicates::InAllDevices() return this; } -const DistributedRdb::RdbPredicates& AbsRdbPredicates::GetDistributedPredicates() const +const DistributedRdb::PredicatesMemo & AbsRdbPredicates::GetDistributedPredicates() const { int limit = GetLimit(); if (limit >= 0) { diff --git a/relational_store/frameworks/native/rdb/src/abs_result_set.cpp b/relational_store/frameworks/native/rdb/src/abs_result_set.cpp index 14eb4f9b..0059cd99 100644 --- a/relational_store/frameworks/native/rdb/src/abs_result_set.cpp +++ b/relational_store/frameworks/native/rdb/src/abs_result_set.cpp @@ -162,6 +162,18 @@ int AbsResultSet::GetRow(RowEntity &rowEntity) rowEntity.Put(columnNames[columnIndex], ValueObject(value)); break; } + case ColumnType::TYPE_ASSET: { + AssetValue value; + GetAsset(columnIndex, value); + rowEntity.Put(columnNames[columnIndex], ValueObject(value)); + break; + } + case ColumnType::TYPE_ASSETS: { + ValueObject::Assets value; + GetAssets(columnIndex, value); + rowEntity.Put(columnNames[columnIndex], ValueObject(value)); + break; + } default: { return E_ERROR; } diff --git a/relational_store/frameworks/native/rdb/src/abs_shared_result_set.cpp b/relational_store/frameworks/native/rdb/src/abs_shared_result_set.cpp index b3b8bdce..4f07bca4 100644 --- a/relational_store/frameworks/native/rdb/src/abs_shared_result_set.cpp +++ b/relational_store/frameworks/native/rdb/src/abs_shared_result_set.cpp @@ -333,7 +333,7 @@ int AbsSharedResultSet::GetAsset(int32_t col, ValueObject::Asset &value) } if (cellUnit->type != AppDataFwk::SharedBlock::CELL_UNIT_TYPE_ASSET) { - LOG_ERROR("GetAsset AppDataFwk::SharedBlock::nothing !"); + LOG_ERROR("GetAsset type:%{public}d col:%{public}d !", cellUnit->type, col); return E_INVALID_OBJECT_TYPE; } diff --git a/relational_store/frameworks/native/rdb/src/raw_data_parser.cpp b/relational_store/frameworks/native/rdb/src/raw_data_parser.cpp index ecb6ba33..0a524ae5 100644 --- a/relational_store/frameworks/native/rdb/src/raw_data_parser.cpp +++ b/relational_store/frameworks/native/rdb/src/raw_data_parser.cpp @@ -14,18 +14,48 @@ */ #include "raw_data_parser.h" -#include "value_object.h" + +#include +#include "multi_platform_endian.h" +#define UNMARSHAL_RETURN_ERR(theCall) \ + do { \ + if (!theCall) { \ + return false; \ + } \ + } while (0) + namespace OHOS::NativeRdb { size_t RawDataParser::ParserRawData(const uint8_t *data, size_t length, Asset &asset) { size_t used = 0; - if (used + sizeof(asset.version) > length) { - return used; + uint16_t size = 0; + + if (sizeof(ASSET_MAGIC) > length - used) { + return 0; } std::vector alignData; - alignData.assign(data, data + sizeof(asset.version)); - asset.version = *(reinterpret_cast(alignData.data())); - used += sizeof(asset.version); + alignData.assign(data, data + sizeof(ASSET_MAGIC)); + used += sizeof(ASSET_MAGIC); + if (*(reinterpret_cast(alignData.data())) != ASSET_MAGIC) { + return 0; + } + + if (sizeof(size) > length - used) { + return 0; + } + alignData.assign(data + used, data + used + sizeof(size)); + used += sizeof(size); + size = Endian::LeToH(*(reinterpret_cast(alignData.data()))); + + if (size > length - used) { + return 0; + } + auto rawData = std::string(reinterpret_cast(&data[used]), size); + InnerAsset innerAsset = InnerAsset(asset); + if (!innerAsset.Unmarshall(rawData)) { + return 0; + } + used += size; return used; } @@ -33,13 +63,23 @@ size_t RawDataParser::ParserRawData(const uint8_t *data, size_t length, Assets & { size_t used = 0; uint16_t num = 0; - if (used + sizeof(num) > length) { - return used; + + if (sizeof(ASSETS_MAGIC) > length - used) { + return 0; } std::vector alignData; + alignData.assign(data, data + sizeof (ASSETS_MAGIC)); + used += sizeof (ASSETS_MAGIC); + if (*(reinterpret_cast(alignData.data())) != ASSETS_MAGIC) { + return 0; + } + + if (sizeof(num) > length - used) { + return 0; + } alignData.assign(data, data + sizeof(num)); num = *(reinterpret_cast(alignData.data())); - used += sizeof(uint16_t); + used += sizeof(num); uint16_t count = 0; while (used < length && count < num) { Asset asset; @@ -57,8 +97,14 @@ size_t RawDataParser::ParserRawData(const uint8_t *data, size_t length, Assets & std::vector RawDataParser::PackageRawData(const Asset &asset) { std::vector rawData; - uint32_t version = asset.version; - rawData.assign(reinterpret_cast(&version), reinterpret_cast(&version) + sizeof(version)); + InnerAsset innerAsset(const_cast(asset)); + auto data = Serializable::Marshall(innerAsset); + uint16_t size; + size = Endian::HToLe((uint16_t)data.length()); + auto magicU8 = reinterpret_cast(const_cast(&ASSET_MAGIC)); + rawData.insert(rawData.end(), magicU8, magicU8 + sizeof(ASSET_MAGIC)); + rawData.insert(rawData.end(), reinterpret_cast(&size), reinterpret_cast(&size) + sizeof(size)); + rawData.insert(rawData.end(), data.begin(), data.end()); return rawData; } @@ -66,11 +112,46 @@ std::vector RawDataParser::PackageRawData(const Assets &assets) { std::vector rawData; uint16_t num = uint16_t(assets.size()); - rawData.assign(reinterpret_cast(&num), reinterpret_cast(&num)+ sizeof(num)); + auto magicU8 = reinterpret_cast(const_cast(&ASSETS_MAGIC)); + rawData.insert(rawData.end(), magicU8, magicU8 + sizeof(ASSETS_MAGIC)); + rawData.insert(rawData.end(), reinterpret_cast(&num), reinterpret_cast(&num) + sizeof(num)); for (auto &asset : assets) { auto data = PackageRawData(asset); rawData.insert(rawData.end(), data.begin(), data.end()); } return rawData; } + +bool RawDataParser::InnerAsset::Marshal(Serializable::json &node) const +{ + SetValue(node[GET_NAME(version)], asset_.version); + SetValue(node[GET_NAME(status)], asset_.status); + SetValue(node[GET_NAME(timeStamp)], asset_.timeStamp); + SetValue(node[GET_NAME(name)], asset_.name); + SetValue(node[GET_NAME(uri)], asset_.uri); + SetValue(node[GET_NAME(createTime)], asset_.createTime); + SetValue(node[GET_NAME(modifyTime)], asset_.modifyTime); + SetValue(node[GET_NAME(size)], asset_.size); + SetValue(node[GET_NAME(hash)], asset_.hash); + SetValue(node[GET_NAME(path)], asset_.path); + return true; +} +bool RawDataParser::InnerAsset::Unmarshal(const Serializable::json &node) +{ + UNMARSHAL_RETURN_ERR(GetValue(node, GET_NAME(version), asset_.version)); + UNMARSHAL_RETURN_ERR(GetValue(node, GET_NAME(status), asset_.status)); + UNMARSHAL_RETURN_ERR(GetValue(node, GET_NAME(timeStamp), asset_.timeStamp)); + if (asset_.status == AssetValue::STATUS_DOWNLOADING && + asset_.timeStamp < static_cast(std::chrono::steady_clock::now().time_since_epoch().count())) { + asset_.status = AssetValue::STATUS_ABNORMAL; + } + UNMARSHAL_RETURN_ERR(GetValue(node, GET_NAME(name), asset_.name)); + UNMARSHAL_RETURN_ERR(GetValue(node, GET_NAME(uri), asset_.uri)); + UNMARSHAL_RETURN_ERR(GetValue(node, GET_NAME(createTime), asset_.createTime)); + UNMARSHAL_RETURN_ERR(GetValue(node, GET_NAME(modifyTime), asset_.modifyTime)); + UNMARSHAL_RETURN_ERR(GetValue(node, GET_NAME(size), asset_.size)); + UNMARSHAL_RETURN_ERR(GetValue(node, GET_NAME(hash), asset_.hash)); + UNMARSHAL_RETURN_ERR(GetValue(node, GET_NAME(path), asset_.path)); + return true; +} } // namespace OHOS::NativeRdb \ No newline at end of file diff --git a/relational_store/frameworks/native/rdb/src/rdb_notifier_stub.cpp b/relational_store/frameworks/native/rdb/src/rdb_notifier_stub.cpp index 793e22d1..3267ec34 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_notifier_stub.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_notifier_stub.cpp @@ -80,7 +80,7 @@ int32_t RdbNotifierStub::OnChange(const Origin &origin, const PrimaryFields &pri if (changeNotifier_ != nullptr) { changeNotifier_(origin, primaries, std::move(changeInfo)); } - return 0; + return RDB_OK; } int32_t RdbNotifierStub::OnChangeInner(MessageParcel &data, MessageParcel &reply) diff --git a/relational_store/frameworks/native/rdb/src/rdb_security_manager.cpp b/relational_store/frameworks/native/rdb/src/rdb_security_manager.cpp index 439e2f53..586073af 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_security_manager.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_security_manager.cpp @@ -25,7 +25,7 @@ #include "hks_mem.h" #include "hks_param.h" #include "logger.h" -#include "sqlite_database_utils.h" +#include "rdb_sql_utils.h" #include "sqlite_utils.h" namespace OHOS { @@ -553,8 +553,8 @@ void RdbSecurityManager::DelRdbSecretDataFile(const std::string &path) LOG_INFO("Delete all key files begin."); std::lock_guard lock(mutex_); ParsePath(path); - SqliteDatabaseUtils::DeleteFile(keyPath_); - SqliteDatabaseUtils::DeleteFile(newKeyPath_); + SqliteUtils::DeleteFile(keyPath_); + SqliteUtils::DeleteFile(newKeyPath_); } bool RdbSecurityManager::IsKeyExpired(const time_t &createTime) @@ -611,12 +611,12 @@ void RdbSecurityManager::DelRdbSecretDataFile(RdbSecurityManager::KeyFileType ke { std::string keyPath; GetKeyPath(keyFile, keyPath); - SqliteDatabaseUtils::DeleteFile(keyPath); + SqliteUtils::DeleteFile(keyPath); } void RdbSecurityManager::UpdateKeyFile() { - if (!SqliteDatabaseUtils::RenameFile(newKeyPath_, keyPath_)) { + if (SqliteUtils::RenameFile(newKeyPath_, keyPath_) != E_OK) { LOG_ERROR("Rename key file failed."); return; } diff --git a/relational_store/frameworks/native/rdb/src/rdb_service_proxy.cpp b/relational_store/frameworks/native/rdb/src/rdb_service_proxy.cpp index 76d7e565..c6b217b8 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_service_proxy.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_service_proxy.cpp @@ -57,6 +57,7 @@ void RdbServiceProxy::OnSyncComplete(uint32_t seqNum, Details &&result) { syncCallbacks_.ComputeIfPresent(seqNum, [&result] (const auto& key, const AsyncDetail & callback) { auto finished = result.empty() || (result.begin()->second.progress == SYNC_FINISH); + ZLOGD("Sync complete, seqNum%{public}d, result size:%{public}zu", key, result.size()); callback(std::move(result)); return !finished; }); @@ -131,7 +132,7 @@ uint32_t RdbServiceProxy::GetSeqNum() } std::pair RdbServiceProxy::DoSync(const RdbSyncerParam& param, const Option &option, - const RdbPredicates &predicates) + const PredicatesMemo &predicates) { std::pair result{RDB_ERROR, {}}; MessageParcel reply; @@ -151,7 +152,7 @@ std::pair RdbServiceProxy::DoSync(const RdbSyncerParam& param, return result; } -int32_t RdbServiceProxy::DoSync(const RdbSyncerParam ¶m, const Option &option, const RdbPredicates &predicates, +int32_t RdbServiceProxy::DoSync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &predicates, const AsyncDetail &async) { auto [status, details] = DoSync(param, option, predicates); @@ -167,7 +168,7 @@ int32_t RdbServiceProxy::DoSync(const RdbSyncerParam ¶m, const Option &optio return RDB_OK; } -int32_t RdbServiceProxy::DoAsync(const RdbSyncerParam ¶m, const Option &option, const RdbPredicates &predicates) +int32_t RdbServiceProxy::DoAsync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &predicates) { MessageParcel reply; int32_t status = IPC_SEND(RDB_SERVICE_CMD_ASYNC, reply, param, option, predicates); @@ -179,7 +180,7 @@ int32_t RdbServiceProxy::DoAsync(const RdbSyncerParam ¶m, const Option &opti } int32_t RdbServiceProxy::DoAsync(const RdbSyncerParam& param, const Option &option, - const RdbPredicates &predicates, const AsyncDetail & callback) + const PredicatesMemo &predicates, const AsyncDetail & callback) { Option asyncOption = option; if (callback != nullptr) { @@ -190,9 +191,9 @@ int32_t RdbServiceProxy::DoAsync(const RdbSyncerParam& param, const Option &opti } } ZLOGI("num=%{public}u", asyncOption.seqNum); - if (DoAsync(param, option, predicates) != RDB_OK) { + if (DoAsync(param, asyncOption, predicates) != RDB_OK) { ZLOGE("failed"); - syncCallbacks_.Erase(option.seqNum); + syncCallbacks_.Erase(asyncOption.seqNum); return RDB_ERROR; } @@ -211,7 +212,7 @@ int32_t RdbServiceProxy::SetDistributedTables(const RdbSyncerParam& param, const return status; } -int32_t RdbServiceProxy::Sync(const RdbSyncerParam ¶m, const Option &option, const RdbPredicates &predicates, +int32_t RdbServiceProxy::Sync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &predicates, const AsyncDetail &async) { if (option.isAsync) { diff --git a/relational_store/frameworks/native/rdb/src/rdb_sql_utils.cpp b/relational_store/frameworks/native/rdb/src/rdb_sql_utils.cpp new file mode 100644 index 00000000..89caa5e0 --- /dev/null +++ b/relational_store/frameworks/native/rdb/src/rdb_sql_utils.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include +#include +#ifdef WINDOWS_PLATFORM +#include +#endif +#include + +#include "logger.h" +#include "rdb_errno.h" +#include "rdb_sql_utils.h" +#include "sqlite_sql_builder.h" + +#ifdef WINDOWS_PLATFORM +#define REALPATH(relPath, absPath, ...) (_fullpath(absPath, relPath, ##__VA_ARGS__)) +#define MKDIR(filePath) (mkdir(filePath)) +#else +#define REALPATH(absPath, relPath, ...) (realpath(absPath, relPath)) +#define MKDIR(filePath) (mkdir(filePath, 0771)) +#endif + +namespace OHOS { +namespace NativeRdb { +/** + * Get and Check default path. + */ +std::string RdbSqlUtils::GetDefaultDatabasePath(const std::string &baseDir, const std::string &name, int &errorCode) +{ + if (access(baseDir.c_str(), F_OK) != 0) { + if (MKDIR(baseDir.c_str())) { + errorCode = E_CREATE_FOLDER_FAIL; + } + } +#if defined(WINDOWS_PLATFORM) + std::string databasePath = baseDir + "\\rdb"; +#else + std::string databasePath = baseDir + "/rdb"; +#endif + if (access(databasePath.c_str(), F_OK) != 0) { + if (MKDIR(databasePath.c_str())) { + errorCode = E_CREATE_FOLDER_FAIL; + } + } + char canonicalPath[PATH_MAX + 1] = { 0 }; + if (REALPATH(databasePath.c_str(), canonicalPath, PATH_MAX) == nullptr) { + LOG_ERROR("Failed to obtain real path, errno:%{public}d", errno); + errorCode = E_INVALID_FILE_PATH; + return ""; + } + std::string realFilePath(canonicalPath); +#if defined(WINDOWS_PLATFORM) + realFilePath = realFilePath.append("\\").append(name); +#else + realFilePath = realFilePath.append("/").append(name); +#endif + return realFilePath; +} + +std::string RdbSqlUtils::BuildQueryString(const AbsRdbPredicates &predicates, const std::vector &columns) +{ + return SqliteSqlBuilder::BuildQueryString(predicates, columns); +} +} // namespace NativeRdb +} // namespace OHOS \ No newline at end of file diff --git a/relational_store/frameworks/native/rdb/src/rdb_store_impl.cpp b/relational_store/frameworks/native/rdb/src/rdb_store_impl.cpp index c125db00..495a481e 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_store_impl.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_store_impl.cpp @@ -26,7 +26,7 @@ #include "logger.h" #include "rdb_errno.h" #include "rdb_trace.h" -#include "sqlite_database_utils.h" +#include "rdb_sql_utils.h" #include "sqlite_global_config.h" #include "sqlite_sql_builder.h" #include "sqlite_utils.h" @@ -92,32 +92,36 @@ int RdbStoreImpl::InnerOpen(const RdbStoreConfig &config) syncerParam_.type_ = config.GetDistributedType(); syncerParam_.isEncrypt_ = config.IsEncrypt(); syncerParam_.password_ = {}; - GetSchema(); + GetSchema(config); #endif return E_OK; } #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) -void RdbStoreImpl::GetSchema() -{ - auto [err, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(syncerParam_); - if (err != E_OK || service == nullptr) { - LOG_WARN("GetRdbService failed, err is %{public}d.", err); - return; - } - if (isEncrypt_) { - RdbPassword key = - RdbSecurityManager::GetInstance().GetRdbPassword(RdbSecurityManager::KeyFileType::PUB_KEY_FILE); - syncerParam_.password_ = std::vector(key.GetData(), key.GetData() + key.GetSize()); - } +void RdbStoreImpl::GetSchema(const RdbStoreConfig &config) +{ + std::vector key = config.GetEncryptKey(); + RdbPassword rdbPwd; + if (config.IsEncrypt()) { + RdbSecurityManager::GetInstance().Init(config.GetBundleName(), config.GetPath()); + rdbPwd = RdbSecurityManager::GetInstance().GetRdbPassword(RdbSecurityManager::KeyFileType::PUB_KEY_FILE); + key.assign(key.size(), 0); + key = std::vector(rdbPwd.GetData(), rdbPwd.GetData() + rdbPwd.GetSize()); + } + syncerParam_.password_ = std::vector(key.data(), key.data() + key.size()); + key.assign(key.size(), 0); if (pool_ == nullptr) { pool_ = TaskExecutor::GetInstance().GetExecutor(); } if (pool_ != nullptr) { auto param = syncerParam_; - auto ser = service; - pool_->Execute([param, ser]() { - auto err = ser->GetSchema(param); + pool_->Execute([param]() { + auto [err, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(param); + if (err != E_OK || service == nullptr) { + LOG_WARN("GetRdbService failed, err is %{public}d.", err); + return; + } + err = service->GetSchema(param); if (err != E_OK) { LOG_ERROR("GetSchema failed, err is %{public}d.", err); } @@ -135,10 +139,6 @@ RdbStoreImpl::RdbStoreImpl(const RdbStoreConfig &config) RdbStoreImpl::~RdbStoreImpl() { delete connectionPool; -#if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) - syncerParam_.password_.assign(syncerParam_.password_.size(), 0); - syncerParam_.password_.clear(); -#endif } #ifdef WINDOWS_PLATFORM @@ -212,8 +212,11 @@ int RdbStoreImpl::BatchInsert(int64_t &outInsertNum, const std::string &table, s return FreeTransaction(connection, transaction.GetRollbackStr()); } } - - return FreeTransaction(connection, transaction.GetCommitStr()); + auto status = FreeTransaction(connection, transaction.GetCommitStr()); + if (status == E_OK) { + DoCloudSync(table); + } + return status; } std::pair> RdbStoreImpl::GetInsertParams( @@ -286,7 +289,9 @@ int RdbStoreImpl::InsertWithConflictResolution(int64_t &outRowId, const std::str errCode = connection->ExecuteForLastInsertedRowId(outRowId, sql.str(), std::move(bindArgs)); connectionPool->ReleaseConnection(connection); - + if (errCode == E_OK) { + DoCloudSync(table); + } return errCode; } @@ -348,7 +353,9 @@ int RdbStoreImpl::UpdateWithConflictResolution(int &changedRows, const std::stri errCode = connection->ExecuteForChangedRowCount(changedRows, sql.str(), std::move(bindArgs)); connectionPool->ReleaseConnection(connection); - + if (errCode == E_OK) { + DoCloudSync(table); + } return errCode; } @@ -383,7 +390,9 @@ int RdbStoreImpl::Delete(int &deletedRows, const std::string &table, const std:: int errCode = connection->ExecuteForChangedRowCount(deletedRows, sql.str(), std::move(bindArgs)); connectionPool->ReleaseConnection(connection); - + if (errCode == E_OK) { + DoCloudSync(table); + } return errCode; } @@ -406,7 +415,9 @@ int RdbStoreImpl::Delete(const std::string &table, const std::string &where, std int changedRows = 0; int errCode = connection->ExecuteForChangedRowCount(changedRows, sql.str(), std::move(args)); connectionPool->ReleaseConnection(connection); - + if (errCode == E_OK) { + DoCloudSync(table); + } return errCode == E_OK ? changedRows : -errCode; } @@ -523,6 +534,10 @@ int RdbStoreImpl::ExecuteSql(const std::string &sql, std::vector bi if (sqlType == SqliteUtils::STATEMENT_DDL) { errCode = connectionPool->ReOpenAvailableReadConnections(); } + + if (errCode == E_OK) { + DoCloudSync(""); + } return errCode; } @@ -939,14 +954,13 @@ int RdbStoreImpl::CheckAttach(const std::string &sql) if (sqlType != "ATT") { return E_OK; } - std::string journalMode; - bool isRead = SqliteDatabaseUtils::BeginExecuteSql(GlobalExpr::PRAGMA_JOUR_MODE_EXP); - SqliteConnection *connection = connectionPool->AcquireConnection(isRead); + SqliteConnection *connection = connectionPool->AcquireConnection(false); if (connection == nullptr) { return E_CON_OVER_LIMIT; } - + + std::string journalMode; int errCode = connection->ExecuteGetString(journalMode, GlobalExpr::PRAGMA_JOUR_MODE_EXP, std::vector()); connectionPool->ReleaseConnection(connection); @@ -1033,6 +1047,54 @@ bool RdbStoreImpl::IsMemoryRdb() const return isMemoryRdb; } +void RdbStoreImpl::DoCloudSync(const std::string &table) +{ + LOG_INFO("RdbStoreImpl DoCloudSync start: %{public}s", table.c_str()); +#if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) + if (pool_ == nullptr) { + return; + } + { + std::shared_lock lock(rwMutex_); + if (cloudTables_.empty() || (!table.empty() && cloudTables_.find(table) == cloudTables_.end())) { + return; + } + } + { + std::lock_guard lock(mutex_); + if (syncTables_ == nullptr) { + syncTables_ = std::make_shared>(); + } + auto empty = syncTables_->empty(); + if (table.empty()) { + syncTables_->insert(cloudTables_.begin(), cloudTables_.end()); + } else { + syncTables_->insert(table); + } + if (!empty) { + LOG_INFO("RdbStoreImpl DoCloudSync empty"); + return; + } + } + auto interval = + std::chrono::duration_cast(std::chrono::milliseconds(INTERVAL)); + pool_->Schedule(interval, [this]() { + std::shared_ptr> ptr; + { + std::lock_guard lock(mutex_); + ptr = syncTables_; + syncTables_ = nullptr; + } + if (ptr == nullptr) { + return; + } + LOG_INFO("RdbStoreImpl DoCloudSync start: %{public}s", ptr->begin()->c_str()); + SyncOption syncOption = { DistributedRdb::TIME_FIRST, false }; + Sync(syncOption, { ptr->begin(), ptr->end() }, nullptr); + }); +#endif +} + //std::string RdbStoreImpl::GetName() //{ // return name; @@ -1136,7 +1198,8 @@ std::shared_ptr RdbStoreImpl::QueryByStep(const std::string &sql, std } #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) -int RdbStoreImpl::SetDistributedTables(const std::vector &tables, int32_t type) +int RdbStoreImpl::SetDistributedTables(const std::vector &tables, int32_t type, + const DistributedRdb::DistributedConfig &distributedConfig) { DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__)); if (tables.empty()) { @@ -1152,6 +1215,13 @@ int RdbStoreImpl::SetDistributedTables(const std::vector &tables, i LOG_ERROR("Fail to set distributed tables, error=%{public}d", errorCode); return errorCode; } + + LOG_INFO("RdbStoreProxy::SetDistributedTables tablename:%{public}s, type:%{public}d, config:%{public}d", + tables.begin()->c_str(), type, distributedConfig.autoSync); + if (type == DistributedRdb::DISTRIBUTED_CLOUD && distributedConfig.autoSync) { + std::unique_lock lock(rwMutex_); + cloudTables_.insert(tables.begin(), tables.end()); + } return E_OK; } @@ -1193,7 +1263,9 @@ int RdbStoreImpl::Sync(const SyncOption &option, const AbsRdbPredicates &predica for (auto &[key, value] : details) { briefs.insert_or_assign(key, value.code); } - callback(briefs); + if (callback != nullptr) { + callback(briefs); + } }); if (errCode != E_OK) { LOG_ERROR("Sync is failed, err is %{public}d.", errCode); diff --git a/relational_store/frameworks/native/rdb/src/rdb_store_manager.cpp b/relational_store/frameworks/native/rdb/src/rdb_store_manager.cpp index 4458673d..28237ab1 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_store_manager.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_store_manager.cpp @@ -13,6 +13,8 @@ * limitations under the License. */ +#include + #include "logger.h" #include "rdb_errno.h" #include "rdb_store_impl.h" @@ -74,6 +76,7 @@ std::shared_ptr RdbStoreManager::GetRdbStore(const RdbStoreConfig &con pool_ = TaskExecutor::GetInstance().GetExecutor(); } if (pool_ != nullptr) { + LOG_INFO("config changed, taskId_: %{public}" PRIu64 "", storeCache_[path]->taskId_); pool_->Remove(storeCache_[path]->taskId_); } storeCache_.erase(path); @@ -134,6 +137,7 @@ void RdbStoreManager::Remove(const std::string &path) return; } if (pool_ != nullptr) { + LOG_INFO("remove taskId_: %{public}" PRIu64 "", it->second->taskId_); pool_->Remove(it->second->taskId_); } storeCache_.erase(it); diff --git a/relational_store/frameworks/native/rdb/src/rdb_types_util.cpp b/relational_store/frameworks/native/rdb/src/rdb_types_util.cpp index f3be9122..08dd8a12 100644 --- a/relational_store/frameworks/native/rdb/src/rdb_types_util.cpp +++ b/relational_store/frameworks/native/rdb/src/rdb_types_util.cpp @@ -149,21 +149,21 @@ bool Marshalling(const PrimaryKeys &input, MessageParcel &data) return Marshal(data, input[Observer::CHG_TYPE_INSERT], input[Observer::CHG_TYPE_UPDATE], input[Observer::CHG_TYPE_DELETE]); } - template<> bool Unmarshalling(PrimaryKeys &output, MessageParcel &data) { return Unmarshal(data, output[Observer::CHG_TYPE_INSERT], output[Observer::CHG_TYPE_UPDATE], output[Observer::CHG_TYPE_DELETE]); } + template<> -bool ITypesUtil::Marshalling(const Origin &input, MessageParcel &data) +bool Marshalling(const Origin &input, MessageParcel &data) { - return Marshal(data, input.origin, input.id, input.store); + return Marshal(data, input.origin, input.dataType, input.id, input.store); } template<> -bool ITypesUtil::Unmarshalling(Origin &output, MessageParcel &data) +bool Unmarshalling(Origin &output, MessageParcel &data) { - return Unmarshal(data, output.origin, output.id, output.store); + return Unmarshal(data, output.origin, output.dataType, output.id, output.store); } } diff --git a/relational_store/frameworks/native/rdb/src/share_block.cpp b/relational_store/frameworks/native/rdb/src/share_block.cpp index c98daf00..eeb31a80 100644 --- a/relational_store/frameworks/native/rdb/src/share_block.cpp +++ b/relational_store/frameworks/native/rdb/src/share_block.cpp @@ -302,9 +302,10 @@ FillOneRowResult FillOneRowOfBlob(AppDataFwk::SharedBlock *sharedBlock, sqlite3_ std::string type(declType); std::transform(type.begin(), type.end(), type.begin(), [](auto ch) { return std::toupper(ch); }); action = (type == ValueObject::DeclType()) ? &AppDataFwk::SharedBlock::PutAsset - : (type == ValueObject::DeclType()) ? &AppDataFwk::SharedBlock::PutAssets + : (type == ValueObject::DeclType()) ? &AppDataFwk::SharedBlock::PutAssets : &AppDataFwk::SharedBlock::PutBlob; } + LOG_DEBUG("row:%{public}d column:%{public}d declType:%{public}s", addedRows, pos, declType); const void *blob = sqlite3_column_blob(statement, pos); auto size = sqlite3_column_bytes(statement, pos); diff --git a/relational_store/frameworks/native/rdb/src/shared_block_serializer_info.cpp b/relational_store/frameworks/native/rdb/src/shared_block_serializer_info.cpp index 6510db30..020d2572 100644 --- a/relational_store/frameworks/native/rdb/src/shared_block_serializer_info.cpp +++ b/relational_store/frameworks/native/rdb/src/shared_block_serializer_info.cpp @@ -15,9 +15,8 @@ #include "shared_block_serializer_info.h" -#include "value_object.h" - #include "logger.h" +#include "value_object.h" namespace OHOS { namespace NativeRdb { @@ -114,6 +113,7 @@ int SharedBlockSerializerInfo::PutBlob(int row, int column, const void *blob, in : (type == ValueObject::DeclType()) ? &AppDataFwk::SharedBlock::PutAssets : &AppDataFwk::SharedBlock::PutBlob; } + LOG_DEBUG("row:%{public}d column:%{public}d declType:%{public}s", row, column, declType); int status = (sharedBlock_->*action)(row, column, blob, len); if (status != AppDataFwk::SharedBlock::SHARED_BLOCK_OK) { diff --git a/relational_store/frameworks/native/rdb/src/sqlite_connection.cpp b/relational_store/frameworks/native/rdb/src/sqlite_connection.cpp index eebfd64d..8f2271cb 100644 --- a/relational_store/frameworks/native/rdb/src/sqlite_connection.cpp +++ b/relational_store/frameworks/native/rdb/src/sqlite_connection.cpp @@ -294,20 +294,18 @@ int SqliteConnection::SetPageSize(const RdbStoreConfig &config) int SqliteConnection::SetEncryptKey(const RdbStoreConfig &config) { #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) - std::vector key; + std::vector key = config.GetEncryptKey(); RdbPassword rdbPwd; - int errCode = E_OK; - if (!config.GetEncryptKey().empty() && !config.IsEncrypt()) { - key = config.GetEncryptKey(); - } else if (config.IsEncrypt()) { + if (config.IsEncrypt()) { RdbSecurityManager::GetInstance().Init(config.GetBundleName(), config.GetPath()); rdbPwd = RdbSecurityManager::GetInstance().GetRdbPassword(RdbKeyFile::PUB_KEY_FILE); + key.assign(key.size(), 0); key = std::vector(rdbPwd.GetData(), rdbPwd.GetData() + rdbPwd.GetSize()); - } else { + } else if (key.empty()) { return E_OK; } - errCode = sqlite3_key(dbHandle, static_cast(key.data()), static_cast(key.size())); + int errCode = sqlite3_key(dbHandle, static_cast(key.data()), static_cast(key.size())); key.assign(key.size(), 0); if (errCode != SQLITE_OK) { LOG_ERROR("SqliteConnection SetEncryptKey fail, err = %{public}d", errCode); diff --git a/relational_store/frameworks/native/rdb/src/sqlite_connection_pool.cpp b/relational_store/frameworks/native/rdb/src/sqlite_connection_pool.cpp index ea7d601a..f1427888 100644 --- a/relational_store/frameworks/native/rdb/src/sqlite_connection_pool.cpp +++ b/relational_store/frameworks/native/rdb/src/sqlite_connection_pool.cpp @@ -293,6 +293,7 @@ int SqliteConnectionPool::ChangeDbFileForRestore(const std::string newPath, cons return E_ERROR; } + LOG_ERROR("restore."); CloseAllConnections(); std::string currentPath = config.GetPath(); diff --git a/relational_store/frameworks/native/rdb/src/sqlite_database_utils.cpp b/relational_store/frameworks/native/rdb/src/sqlite_database_utils.cpp deleted file mode 100644 index 8eb5a941..00000000 --- a/relational_store/frameworks/native/rdb/src/sqlite_database_utils.cpp +++ /dev/null @@ -1,231 +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. - */ - -#include "sqlite_database_utils.h" - -#include -#include -#include - -#include -#include -#ifdef WINDOWS_PLATFORM -#include -#endif -#include -#include - -#include "logger.h" -#include "rdb_errno.h" -#include "sqlite_utils.h" - -#ifdef WINDOWS_PLATFORM -#define REALPATH(relPath, absPath, ...) (_fullpath(absPath, relPath, ##__VA_ARGS__)) -#define MKDIR(filePath) (mkdir(filePath)) -#else -#define REALPATH(absPath, relPath, ...) (realpath(absPath, relPath)) -#define MKDIR(filePath) (mkdir(filePath, g_mkdirMode)) -#endif - -namespace OHOS { -namespace NativeRdb { -std::map SqliteDatabaseUtils::g_statementType = SqliteDatabaseUtils::MapInit(); -std::mutex SqliteDatabaseUtils::g_locker; -// Set the file access permissions is 777 -int SqliteDatabaseUtils::g_mkdirMode = 0771; -std::map SqliteDatabaseUtils::MapInit() -{ - std::map temp; - temp["SEL"] = STATEMENT_SELECT; - temp["INS"] = STATEMENT_UPDATE; - temp["UPD"] = STATEMENT_UPDATE; - temp["REP"] = STATEMENT_UPDATE; - temp["DEL"] = STATEMENT_UPDATE; - temp["ATT"] = STATEMENT_ATTACH; - temp["DET"] = STATEMENT_DETACH; - temp["COM"] = STATEMENT_COMMIT; - temp["END"] = STATEMENT_COMMIT; - temp["ROL"] = STATEMENT_ROLLBACK; - temp["BEG"] = STATEMENT_BEGIN; - temp["PRA"] = STATEMENT_PRAGMA; - temp["CRE"] = STATEMENT_DDL; - temp["DRO"] = STATEMENT_DDL; - temp["ALT"] = STATEMENT_DDL; - - return temp; -} - -/** - * Obtains the type of SQL statement. - */ -int SqliteDatabaseUtils::GetSqlStatementType(std::string sql) -{ - if (sql.empty()) { - return STATEMENT_OTHER; - } - sql.erase(0, sql.find_first_not_of(" ")); - sql.erase(sql.find_last_not_of(" ") + 1); - - if (sql.length() < SQL_FIRST_CHARACTER) { - return STATEMENT_OTHER; - } - sql = StrToUpper(sql.substr(0, SQL_FIRST_CHARACTER)); - auto iter = g_statementType.find(sql); - if (iter != g_statementType.end()) { - return iter->second; - } - return STATEMENT_OTHER; -} - -std::string SqliteDatabaseUtils::StrToUpper(std::string s) -{ - std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c) { return std::toupper(c); }); - return s; -} - -/** - * Delete the specified file. - */ -void SqliteDatabaseUtils::DeleteFile(std::string &fileName) -{ - if (access(fileName.c_str(), F_OK) != 0) { - LOG_ERROR("access %{public}s errno is %{public}d", SqliteUtils::Anonymous(fileName).c_str(), errno); - return; - } - - if (remove(fileName.c_str()) != 0) { - LOG_ERROR("remove %{public}s errno is %{public}d", SqliteUtils::Anonymous(fileName).c_str(), errno); - return; - } - LOG_INFO("remove %{public}s", SqliteUtils::Anonymous(fileName).c_str()); -} - -/** - * Rename file. - */ -bool SqliteDatabaseUtils::RenameFile(std::string &oldFileName, std::string &newFileName) -{ - if (access(oldFileName.c_str(), F_OK) != 0) { - LOG_ERROR("access %{public}s errno is %{public}d", SqliteUtils::Anonymous(oldFileName).c_str(), errno); - return false; - } - if (rename(oldFileName.c_str(), newFileName.c_str()) != 0) { - LOG_ERROR("Rename %{public}s to %{public}s errno %{public}d", SqliteUtils::Anonymous(oldFileName).c_str(), - SqliteUtils::Anonymous(newFileName).c_str(), errno); - return false; - } - return true; -} - -/** - * Get and Check default path. - */ -std::string SqliteDatabaseUtils::GetDefaultDatabasePath(const std::string &baseDir, const std::string &name, - int &errorCode) -{ - std::unique_lock lock(g_locker); - if (access(baseDir.c_str(), F_OK) != 0) { - if (MKDIR(baseDir.c_str())) { - errorCode = E_CREATE_FOLDER_FAIL; - } - } -#if defined(WINDOWS_PLATFORM) - std::string databasePath = baseDir + "\\rdb"; -#else - std::string databasePath = baseDir + "/rdb"; -#endif - if (access(databasePath.c_str(), F_OK) != 0) { - if (MKDIR(databasePath.c_str())) { - errorCode = E_CREATE_FOLDER_FAIL; - } - } - char canonicalPath[PATH_MAX + 1] = { 0 }; - if (REALPATH(databasePath.c_str(), canonicalPath, PATH_MAX) == nullptr) { - LOG_ERROR("Failed to obtain real path, errno:%{public}d", errno); - errorCode = E_INVALID_FILE_PATH; - return ""; - } - std::string realFilePath(canonicalPath); -#if defined(WINDOWS_PLATFORM) - realFilePath = realFilePath.append("\\").append(name); -#else - realFilePath = realFilePath.append("/").append(name); -#endif - return realFilePath; -} - -/** - * Get corrupt path from database path. - */ -std::string SqliteDatabaseUtils::GetCorruptPath(std::string &path, int &errorCode) -{ - std::string databaseFile = path; - std::string name = databaseFile.substr(databaseFile.find_last_of("/") + 1); - std::string parentFile = databaseFile.substr(0, databaseFile.find_last_of("/")); - std::string databaseTypeDir = parentFile.substr(parentFile.find_last_of("/") + 1); - size_t posDatabaseType = databaseTypeDir.find("_encrypt"); - - bool isEncrypt = false; - if (posDatabaseType != databaseTypeDir.npos) { - std::string databaseTypeDirStr = databaseTypeDir.substr(posDatabaseType); - std::string end = "_encrypt"; - if (databaseTypeDirStr.compare(end) == 0) { - isEncrypt = true; - } - } - - std::string databaseDir = parentFile.substr(0, parentFile.find_last_of("/")); - std::string encrypt = isEncrypt ? "_encrypt" : ""; - std::string corruptTypeDir = "corrupt" + encrypt; - std::string corruptPath = databaseDir + "/" + corruptTypeDir; - - if (access(corruptPath.c_str(), F_OK) != 0) { - if (MKDIR(corruptPath.c_str())) { - errorCode = E_CREATE_FOLDER_FAIL; - } - } - corruptPath = corruptPath + "/" + name; - return corruptPath; -} - -/** - * Get and Check no dbname path. - */ - -bool SqliteDatabaseUtils::BeginExecuteSql(const std::string &sql) -{ - int type = SqliteDatabaseUtils::GetSqlStatementType(sql); - if (IsSpecial(type)) { - return E_TRANSACTION_IN_EXECUTE; - } - - return (type == STATEMENT_SELECT) ? true : false; -} - -bool SqliteDatabaseUtils::IsReadOnlySql(std::string sql) -{ - int sqlType = GetSqlStatementType(sql); - return (sqlType == STATEMENT_SELECT) ? true : false; -} - -bool SqliteDatabaseUtils::IsSpecial(int sqlType) -{ - if (sqlType == STATEMENT_BEGIN || sqlType == STATEMENT_COMMIT || sqlType == STATEMENT_ROLLBACK) { - return true; - } - return false; -} -} // namespace NativeRdb -} // namespace OHOS \ No newline at end of file diff --git a/relational_store/frameworks/native/rdb/src/sqlite_shared_result_set.cpp b/relational_store/frameworks/native/rdb/src/sqlite_shared_result_set.cpp index 139e596a..9a6b69e0 100644 --- a/relational_store/frameworks/native/rdb/src/sqlite_shared_result_set.cpp +++ b/relational_store/frameworks/native/rdb/src/sqlite_shared_result_set.cpp @@ -17,7 +17,7 @@ #include #include #include -#include "sqlite_database_utils.h" +#include "rdb_sql_utils.h" #include "sqlite_utils.h" #include "logger.h" @@ -35,7 +35,7 @@ SqliteSharedResultSet::~SqliteSharedResultSet() {} std::shared_ptr SqliteSharedResultSet::PrepareStep(SqliteConnection* connection, int &errCode) { - if (SqliteDatabaseUtils::GetSqlStatementType(qrySql) != SqliteUtils::STATEMENT_SELECT) { + if (SqliteUtils::GetSqlStatementType(qrySql) != SqliteUtils::STATEMENT_SELECT) { LOG_ERROR("StoreSession BeginStepQuery fail : not select sql !"); errCode = E_EXECUTE_IN_STEP_QUERY; return nullptr; @@ -160,8 +160,7 @@ void SqliteSharedResultSet::FillSharedBlock(int requiredPos) bindArgs.push_back(vauObj); } - bool isRead = SqliteDatabaseUtils::BeginExecuteSql(qrySql); - SqliteConnection* connection = connectionPool_->AcquireConnection(isRead); + SqliteConnection* connection = connectionPool_->AcquireConnection(true); if (connection == nullptr) { return; } diff --git a/relational_store/frameworks/native/rdb/src/sqlite_statement.cpp b/relational_store/frameworks/native/rdb/src/sqlite_statement.cpp index 66f149ad..04f2cac8 100644 --- a/relational_store/frameworks/native/rdb/src/sqlite_statement.cpp +++ b/relational_store/frameworks/native/rdb/src/sqlite_statement.cpp @@ -141,6 +141,22 @@ int SqliteStatement::InnerBindArguments(const std::vector &bindArgs errCode = sqlite3_bind_int64(stmtHandle, index, boolVal ? 1 : 0); break; } + case ValueObjectType::TYPE_ASSET: { + Asset asset; + arg.GetAsset(asset); + auto rawData = RawDataParser::PackageRawData(asset); + errCode = sqlite3_bind_blob(stmtHandle, index, static_cast(rawData.data()), + rawData.size(), SQLITE_TRANSIENT); + break; + } + case ValueObjectType::TYPE_ASSETS: { + Assets assets; + arg.GetAssets(assets); + auto rawData = RawDataParser::PackageRawData(assets); + errCode = sqlite3_bind_blob(stmtHandle, index, static_cast(rawData.data()), + rawData.size(), SQLITE_TRANSIENT); + break; + } default: { std::string str; arg.GetString(str); diff --git a/relational_store/frameworks/native/rdb/src/step_result_set.cpp b/relational_store/frameworks/native/rdb/src/step_result_set.cpp index c9f13cce..6479b93e 100644 --- a/relational_store/frameworks/native/rdb/src/step_result_set.cpp +++ b/relational_store/frameworks/native/rdb/src/step_result_set.cpp @@ -23,7 +23,7 @@ #include "rdb_errno.h" #include "rdb_trace.h" #include "sqlite3sym.h" -#include "sqlite_database_utils.h" +#include "rdb_sql_utils.h" #include "sqlite_errno.h" #include "sqlite_utils.h" @@ -121,9 +121,19 @@ int StepResultSet::GetColumnType(int columnIndex, ColumnType &columnType) case SQLITE_FLOAT: columnType = ColumnType::TYPE_FLOAT; break; - case SQLITE_BLOB: - columnType = ColumnType::TYPE_BLOB; + case SQLITE_BLOB: { + const char *declType = sqlite3_column_decltype(sqliteStatement->GetSql3Stmt(), columnIndex); + std::string type((declType == nullptr) ? "" : declType); + std::transform(type.begin(), type.end(), type.begin(), [](auto ch) { + return std::toupper(ch); + }); + + auto AssetType = ValueObject::DeclType(); + auto AssetsType = ValueObject::DeclType(); + columnType = (type != AssetType) ? (type != AssetsType) ? ColumnType::TYPE_BLOB : ColumnType::TYPE_ASSETS + : ColumnType::TYPE_ASSET; break; + } case SQLITE_NULL: columnType = ColumnType::TYPE_NULL; break; @@ -261,7 +271,7 @@ int StepResultSet::PrepareStep() return E_CON_OVER_LIMIT; } - if (!SqliteDatabaseUtils::IsReadOnlySql(sql)) { + if (SqliteUtils::GetSqlStatementType(sql) != SqliteUtils::STATEMENT_SELECT) { LOG_ERROR("not a select sql!"); return E_EXECUTE_IN_STEP_QUERY; } diff --git a/relational_store/interfaces/inner_api/appdatafwk/BUILD.gn b/relational_store/interfaces/inner_api/appdatafwk/BUILD.gn index 17cc8ce7..5cde6ca0 100644 --- a/relational_store/interfaces/inner_api/appdatafwk/BUILD.gn +++ b/relational_store/interfaces/inner_api/appdatafwk/BUILD.gn @@ -18,6 +18,7 @@ config("appdatafwk_config") { include_dirs = [ "include", "//foundation/distributeddatamgr/relational_store/interfaces/inner_api/rdb/include", + "//third_party/json/single_include", ] if (!is_mingw && !is_mac) { cflags_cc = [ "-fvisibility=hidden" ] @@ -30,12 +31,23 @@ config("appdatafwk_public_config") { } ohos_shared_library("native_appdatafwk") { - sources = - [ "${relational_store_native_path}/appdatafwk/src/shared_block.cpp" ] + sources = [ + "${relational_store_native_path}/appdatafwk/src/serializable.cpp", + "${relational_store_native_path}/appdatafwk/src/shared_block.cpp", + ] + + if (is_mingw) { + sources += + [ "${relational_store_native_path}/appdatafwk/src/mingw_endian.cpp" ] + } else if (is_ohos || is_mac || is_ios || is_android) { + sources += + [ "${relational_store_native_path}/appdatafwk/src/general_endian.cpp" ] + } configs = [ ":appdatafwk_config" ] subsystem_name = "distributeddatamgr" + innerapi_tags = [ "platformsdk_indirect" ] part_name = "relational_store" public_deps = [ "${ipc_path}/ipc_single:ipc_single" ] diff --git a/relational_store/interfaces/inner_api/appdatafwk/include/multi_platform_endian.h b/relational_store/interfaces/inner_api/appdatafwk/include/multi_platform_endian.h new file mode 100644 index 00000000..bebeb295 --- /dev/null +++ b/relational_store/interfaces/inner_api/appdatafwk/include/multi_platform_endian.h @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2021 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef MULTI_PLATFORM_EDIAN +#define MULTI_PLATFORM_EDIAN + +#include +#include "rdb_visibility.h" +namespace OHOS { +class API_EXPORT Endian final { +public: + static uint16_t LeToH(uint16_t value); + static uint16_t HToLe(uint16_t value); +}; +} // namespace OHOS + +#endif // MULTI_PLATFORM_EDIAN diff --git a/relational_store/interfaces/inner_api/appdatafwk/include/serializable.h b/relational_store/interfaces/inner_api/appdatafwk/include/serializable.h new file mode 100644 index 00000000..b4fd7f8f --- /dev/null +++ b/relational_store/interfaces/inner_api/appdatafwk/include/serializable.h @@ -0,0 +1,123 @@ +/* + * 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 DISTRIBUTED_RDB_SERIALIZABLE_H +#define DISTRIBUTED_RDB_SERIALIZABLE_H +#include +#include + +#include "rdb_visibility.h" +#ifndef JSON_NOEXCEPTION +#define JSON_NOEXCEPTION +#endif +#include +namespace OHOS { +#ifndef GET_NAME +#define GET_NAME(value) #value +#endif +struct Serializable { +public: + using json = nlohmann::json; + using size_type = nlohmann::json::size_type; + using error_handler_t = nlohmann::detail::error_handler_t; + API_EXPORT json Marshall() const; + template + static std::string Marshall(T &values) + { + json root; + SetValue(root, values); + return root.dump(-1, ' ', false, error_handler_t::replace); + } + + API_EXPORT bool Unmarshall(const std::string &jsonStr); + template + static bool Unmarshall(const std::string &body, T &values) + { + return GetValue(ToJson(body), "", values); + } + API_EXPORT static json ToJson(const std::string &jsonStr); + API_EXPORT static bool IsJson(const std::string &jsonStr); + virtual bool Marshal(json &node) const = 0; + virtual bool Unmarshal(const json &node) = 0; + API_EXPORT static bool GetValue(const json &node, const std::string &name, std::string &value); + API_EXPORT static bool GetValue(const json &node, const std::string &name, uint32_t &value); + API_EXPORT static bool GetValue(const json &node, const std::string &name, int32_t &value); + API_EXPORT static bool GetValue(const json &node, const std::string &name, int64_t &value); + API_EXPORT static bool GetValue(const json &node, const std::string &name, uint64_t &value); + API_EXPORT static bool GetValue(const json &node, const std::string &name, bool &value); + API_EXPORT static bool GetValue(const json &node, const std::string &name, std::vector &value); + API_EXPORT static bool GetValue(const json &node, const std::string &name, Serializable &value); + API_EXPORT static bool SetValue(json &node, const std::string &value); + API_EXPORT static bool SetValue(json &node, const uint32_t &value); + API_EXPORT static bool SetValue(json &node, const int32_t &value); + API_EXPORT static bool SetValue(json &node, const int64_t &value); + API_EXPORT static bool SetValue(json &node, const uint64_t &value); + API_EXPORT static bool SetValue(json &node, const bool &value); + API_EXPORT static bool SetValue(json &node, const std::vector &value); + API_EXPORT static bool SetValue(json &node, const Serializable &value); + +protected: + API_EXPORT ~Serializable() = default; + + template + static bool GetValue(const json &node, const std::string &name, T *&value) + { + auto &subNode = GetSubNode(node, name); + if (subNode.is_null()) { + return false; + } + value = new (std::nothrow) T(); + if (value == nullptr) { + return false; + } + bool result = GetValue(subNode, "", *value); + if (!result) { + delete value; + value = nullptr; + } + return result; + } + template + static bool GetValue(const json &node, const std::string &name, std::vector &values) + { + auto &subNode = GetSubNode(node, name); + if (subNode.is_null() || !subNode.is_array()) { + return false; + } + bool result = true; + values.resize(subNode.size()); + for (size_type i = 0; i < subNode.size(); ++i) { + result = GetValue(subNode[i], "", values[i]) && result; + } + return result; + } + + template + static bool SetValue(json &node, const std::vector &values) + { + bool result = true; + size_type i = 0; + node = json::value_t::array; + for (const auto &value : values) { + result = SetValue(node[i], value) && result; + i++; + } + return result; + } + + API_EXPORT static const json &GetSubNode(const json &node, const std::string &name); +}; +} // namespace OHOS +#endif // DISTRIBUTED_RDB_SERIALIZABLE_H diff --git a/relational_store/interfaces/inner_api/js/@ohos.data.relationalStore.d.ts b/relational_store/interfaces/inner_api/js/@ohos.data.relationalStore.d.ts index b7759c14..20ca9b93 100644 --- a/relational_store/interfaces/inner_api/js/@ohos.data.relationalStore.d.ts +++ b/relational_store/interfaces/inner_api/js/@ohos.data.relationalStore.d.ts @@ -155,6 +155,16 @@ declare namespace relationalStore { download: Statistic; } + // todo new interface + enum ProcessCode { + SUCCESS, + UNKNOWN_ERROR, + NETWORK_ERROR, + CLOUD_UNOPENED, + LOCKED_BY_OTHERS, + RECORD_LIMIT_EXCEEDED, + } + /** * Describes the {@code RdbStore} type. * @@ -164,9 +174,9 @@ declare namespace relationalStore { */ interface ProgressDetail { schedule: Progress; - code: number; + code: number; // to see the ProcessCode details: { - [table: string]:TableDetail + [table: string]:TableDetail }; } @@ -215,6 +225,12 @@ declare namespace relationalStore { S4 = 4 } + // todo new interface + enum AssetStatus { + ASSET_NORMAL, + ASSET_ABNORMAL, + ASSET_DOWNLOADING, + } /** * Indicates possible value types * @@ -224,9 +240,11 @@ declare namespace relationalStore { interface Asset { name: string; uri: string; + path: string; // the sub path from the distributed dir // todo new interface createTime: string; modifyTime: string; size: string; + status?: AssetStatus; // todo new interface, the default value is ASSET_NORMAL } /** @@ -331,6 +349,11 @@ declare namespace relationalStore { SUBSCRIBE_TYPE_CLOUD_DETAIL, } + // todo new interface + enum ChangeType { + DATA_CHANGE, + ASSET_CHANGE, + } /** * Indicates the notify info * @@ -346,6 +369,9 @@ declare namespace relationalStore { */ table: string; + // todo new interface + type: ChangeType; + /** * Indicates if there is a string primary key, the inserted will keep data's primary keys * otherwise it will keep the data's rowid. @@ -403,6 +429,24 @@ declare namespace relationalStore { DISTRIBUTED_CLOUD } + /** + * Describes the distributed type of the tables. + * + * @enum { number } + * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core + * @since 10 + */ + interface DistributedConfig { + /** + * distributed table config info + * + * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core + * @since 10 + */ + // todo new interface + autoSync: boolean, + } + /** * Describes the conflict resolutions to insert data into the table. * @@ -1085,6 +1129,21 @@ declare namespace relationalStore { */ setDistributedTables(tables: Array, type: number, callback: AsyncCallback): void; + /** + * Set table to be distributed table. + * + * @permission ohos.permission.DISTRIBUTED_DATASYNC + * @param { Array } tables - indicates the tables name you want to set. + * @param { number } mode - indicates the tables distributed type {@link DistributedType}. + * @param { AsyncCallback } callback - the callback of setDistributedTables. + * @throws { BusinessError } 401 - if the parameter type is incorrect. + * @throws { BusinessError } 801 - Capability not supported. + * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core + * @since 10 + */ + // todo new interface + setDistributedTables(tables: Array, type: number, config: DistributedConfig, callback: AsyncCallback): void; + /** * Set table to be distributed table. * @@ -1097,7 +1156,7 @@ declare namespace relationalStore { * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core * @since 9 */ - setDistributedTables(tables: Array, type?: number): Promise; + setDistributedTables(tables: Array, type?: number, config?: DistributedConfig): Promise; /** * Obtain distributed table name of specified remote device according to local table name. diff --git a/relational_store/interfaces/inner_api/rdb/BUILD.gn b/relational_store/interfaces/inner_api/rdb/BUILD.gn index 6e643527..430d8dba 100644 --- a/relational_store/interfaces/inner_api/rdb/BUILD.gn +++ b/relational_store/interfaces/inner_api/rdb/BUILD.gn @@ -23,12 +23,12 @@ base_sources = [ "${relational_store_native_path}/rdb/src/raw_data_parser.cpp", "${relational_store_native_path}/rdb/src/rdb_helper.cpp", "${relational_store_native_path}/rdb/src/rdb_predicates.cpp", + "${relational_store_native_path}/rdb/src/rdb_sql_utils.cpp", "${relational_store_native_path}/rdb/src/rdb_store_config.cpp", "${relational_store_native_path}/rdb/src/rdb_store_impl.cpp", "${relational_store_native_path}/rdb/src/rdb_store_manager.cpp", "${relational_store_native_path}/rdb/src/sqlite_connection.cpp", "${relational_store_native_path}/rdb/src/sqlite_connection_pool.cpp", - "${relational_store_native_path}/rdb/src/sqlite_database_utils.cpp", "${relational_store_native_path}/rdb/src/sqlite_global_config.cpp", "${relational_store_native_path}/rdb/src/sqlite_sql_builder.cpp", "${relational_store_native_path}/rdb/src/sqlite_statement.cpp", @@ -44,6 +44,7 @@ if (is_ohos) { visibility = [ ":*" ] include_dirs = [ + "../appdatafwk/include", "include", "${relational_store_native_path}/rdb/include", "${relational_store_native_path}/rdb_device_manager_adapter/include", @@ -74,8 +75,10 @@ if (is_ohos) { visibility = [ ":*" ] include_dirs = [ + "../appdatafwk/include", "include", "${relational_store_native_path}/rdb/include", + "//third_party/json/single_include", ] } @@ -101,7 +104,6 @@ if (is_ohos) { sources += [ "${relational_store_native_path}/rdb/src/abs_shared_result_set.cpp", - "${relational_store_native_path}/rdb/src/rdb_manager.cpp", "${relational_store_native_path}/rdb/src/rdb_manager_impl.cpp", "${relational_store_native_path}/rdb/src/rdb_notifier_stub.cpp", "${relational_store_native_path}/rdb/src/rdb_security_manager.cpp", @@ -149,7 +151,6 @@ if (is_ohos) { sources += [ "${relational_store_native_path}/rdb/src/abs_shared_result_set.cpp", - "${relational_store_native_path}/rdb/src/rdb_manager.cpp", "${relational_store_native_path}/rdb/src/rdb_manager_impl.cpp", "${relational_store_native_path}/rdb/src/rdb_notifier_stub.cpp", "${relational_store_native_path}/rdb/src/rdb_security_manager.cpp", @@ -187,12 +188,15 @@ if (is_ohos) { visibility = [ ":*" ] include_dirs = [ + "../appdatafwk/include", "mock/include", "${relational_store_native_path}/rdb/mock/include", "//commonlibrary/c_utils/base/include", "include", "//foundation/communication/ipc/interfaces/innerkits/ipc_core/include", "${relational_store_native_path}/rdb/include", + "//third_party/json/single_include", + "//third_party/libuv/src/win", ] defines = [ @@ -221,8 +225,11 @@ if (is_ohos) { visibility = [ ":*" ] include_dirs = [ + "../appdatafwk/include", "mock/include", "include", + "//third_party/json/single_include", + "//third_party/libuv/src/win", ] } @@ -239,8 +246,11 @@ if (is_ohos) { deps = base_deps - sources += - [ "${relational_store_native_path}/rdb/mock/src/task_executor.cpp" ] + sources += [ + "${relational_store_native_path}/appdatafwk/src/mingw_endian.cpp", + "${relational_store_native_path}/appdatafwk/src/serializable.cpp", + "${relational_store_native_path}/rdb/mock/src/task_executor.cpp", + ] deps += [ "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog_windows", @@ -260,8 +270,11 @@ if (is_ohos) { deps = base_deps - sources += - [ "${relational_store_native_path}/rdb/mock/src/task_executor.cpp" ] + sources += [ + "${relational_store_native_path}/appdatafwk/src/mingw_endian.cpp", + "${relational_store_native_path}/appdatafwk/src/serializable.cpp", + "${relational_store_native_path}/rdb/mock/src/task_executor.cpp", + ] deps += [ "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog_windows", @@ -279,12 +292,14 @@ if (is_ohos) { visibility = [ ":*" ] include_dirs = [ + "../appdatafwk/include", "mock/include", "${relational_store_native_path}/rdb/mock/include", "//commonlibrary/c_utils/base/include", "include", "//foundation/communication/ipc/interfaces/innerkits/ipc_core/include", "${relational_store_native_path}/rdb/include", + "//third_party/json/single_include", ] defines = [ @@ -312,8 +327,10 @@ if (is_ohos) { visibility = [ ":*" ] include_dirs = [ + "../appdatafwk/include", "mock/include", "include", + "//third_party/json/single_include", ] } @@ -333,6 +350,7 @@ if (is_ohos) { sources += [ "${relational_store_native_path}/rdb/mock/src/task_executor.cpp" ] deps += [ + "${relational_store_innerapi_path}/appdatafwk:native_appdatafwk", "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog_mac", "//third_party/sqlite:sqlite_sdk", ] @@ -353,6 +371,7 @@ if (is_ohos) { sources += [ "${relational_store_native_path}/rdb/mock/src/task_executor.cpp" ] deps += [ + "${relational_store_innerapi_path}/appdatafwk:native_appdatafwk", "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog_mac", "//third_party/sqlite:sqlite_sdk", ] @@ -368,11 +387,13 @@ if (is_ohos) { visibility = [ ":*" ] include_dirs = [ + "../appdatafwk/include", "${relational_store_innerapi_path}/rdb/mock/include", "${relational_store_native_path}/rdb/mock/include", "${relational_store_innerapi_path}/rdb/include", "//foundation/distributeddatamgr/kv_store/frameworks/common", "${relational_store_native_path}/rdb/include", + "//third_party/json/single_include", ] defines = [ @@ -394,10 +415,12 @@ if (is_ohos) { visibility = [ ":*" ] include_dirs = [ + "../appdatafwk/include", "mock/include", "include", "${relational_store_native_path}/mock/rdb/include", "${relational_store_native_path}/rdb/include", + "//third_party/json/single_include", ] } @@ -416,6 +439,7 @@ if (is_ohos) { sources += [ "${relational_store_native_path}/rdb/mock/src/task_executor.cpp" ] deps += [ + "${relational_store_innerapi_path}/appdatafwk:native_appdatafwk", "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog_android", "//commonlibrary/c_utils/base:utils", "//third_party/sqlite:sqlite_static", @@ -430,10 +454,12 @@ if (is_ohos) { visibility = [ ":*" ] include_dirs = [ + "../appdatafwk/include", "${relational_store_innerapi_path}/rdb/mock/include", "${relational_store_native_path}/rdb/mock/include", "${relational_store_innerapi_path}/rdb/include", "${relational_store_native_path}/rdb/include", + "//third_party/json/single_include", ] defines = [ @@ -455,9 +481,11 @@ if (is_ohos) { visibility = [ ":*" ] include_dirs = [ + "../appdatafwk/include", "mock/include", "include", "${relational_store_native_path}/rdb/include", + "//third_party/json/single_include", ] } @@ -479,6 +507,7 @@ if (is_ohos) { sources += [ "${relational_store_native_path}/rdb/mock/src/task_executor.cpp" ] deps += [ + "${relational_store_innerapi_path}/appdatafwk:native_appdatafwk", "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog_ios", "//commonlibrary/c_utils/base:utilsbase", "//third_party/sqlite:sqlite_static", diff --git a/relational_store/interfaces/inner_api/rdb/include/abs_rdb_predicates.h b/relational_store/interfaces/inner_api/rdb/include/abs_rdb_predicates.h index 065cafb8..872019b6 100644 --- a/relational_store/interfaces/inner_api/rdb/include/abs_rdb_predicates.h +++ b/relational_store/interfaces/inner_api/rdb/include/abs_rdb_predicates.h @@ -141,7 +141,7 @@ public: /** * @brief Get predicates of remote device. */ - API_EXPORT const DistributedRdb::RdbPredicates& GetDistributedPredicates() const; + API_EXPORT const DistributedRdb::PredicatesMemo & GetDistributedPredicates() const; /** * @brief Initialize relevant parameters of the union table. @@ -202,7 +202,7 @@ protected: private: std::string tableName_; - mutable DistributedRdb::RdbPredicates predicates_; + mutable DistributedRdb::PredicatesMemo predicates_; }; } // namespace OHOS::NativeRdb diff --git a/relational_store/interfaces/inner_api/rdb/include/asset_value.h b/relational_store/interfaces/inner_api/rdb/include/asset_value.h index 41fa8841..f4cafeb7 100644 --- a/relational_store/interfaces/inner_api/rdb/include/asset_value.h +++ b/relational_store/interfaces/inner_api/rdb/include/asset_value.h @@ -18,13 +18,23 @@ #include namespace OHOS::NativeRdb { struct AssetValue { + enum Status : int32_t { + STATUS_NORMAL, + STATUS_ABNORMAL, + STATUS_DOWNLOADING, + STATUS_BUTT + }; + static constexpr uint64_t NO_EXPIRES_TIME = 0; uint32_t version = 0; + uint32_t status = STATUS_NORMAL; + uint64_t timeStamp = NO_EXPIRES_TIME; std::string name; std::string uri; std::string createTime; std::string modifyTime; std::string size; std::string hash; + std::string path; }; } #endif // OHOS_RELATIONAL_STORE_INNER_API_ASSET_VALUE_H diff --git a/relational_store/interfaces/inner_api/rdb/include/rdb_service.h b/relational_store/interfaces/inner_api/rdb/include/rdb_service.h index 91dde3bf..92427bcf 100644 --- a/relational_store/interfaces/inner_api/rdb/include/rdb_service.h +++ b/relational_store/interfaces/inner_api/rdb/include/rdb_service.h @@ -52,7 +52,7 @@ public: virtual int32_t SetDistributedTables( const RdbSyncerParam ¶m, const std::vector &tables, int32_t type = DISTRIBUTED_DEVICE) = 0; - virtual int32_t Sync(const RdbSyncerParam ¶m, const Option &option, const RdbPredicates &predicates, + virtual int32_t Sync(const RdbSyncerParam ¶m, const Option &option, const PredicatesMemo &predicates, const AsyncDetail &async) = 0; virtual int32_t Subscribe(const RdbSyncerParam ¶m, const SubscribeOption &option, diff --git a/relational_store/interfaces/inner_api/rdb/include/transaction_observer.h b/relational_store/interfaces/inner_api/rdb/include/rdb_sql_utils.h similarity index 53% rename from relational_store/interfaces/inner_api/rdb/include/transaction_observer.h rename to relational_store/interfaces/inner_api/rdb/include/rdb_sql_utils.h index 49d43bc5..c8d05716 100644 --- a/relational_store/interfaces/inner_api/rdb/include/transaction_observer.h +++ b/relational_store/interfaces/inner_api/rdb/include/rdb_sql_utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -13,40 +13,24 @@ * limitations under the License. */ - -#ifndef APPDATAMGR_TRANSACTION_OBSERVER_H -#define APPDATAMGR_TRANSACTION_OBSERVER_H - -#include "rdb_visibility.h" +#ifndef NATIVE_RDB_SQL_UTILS_H +#define NATIVE_RDB_SQL_UTILS_H +#include "abs_rdb_predicates.h" namespace OHOS { namespace NativeRdb { -/** - * The TransactionObserver class of RDB. - */ -class API_EXPORT TransactionObserver { +class API_EXPORT RdbSqlUtils { public: /** - * @brief Destructor. - */ - API_EXPORT virtual ~TransactionObserver() {} - - /** - * @brief Begin transaction. + * @brief get default data base path. */ - API_EXPORT virtual void OnBegin() const; - - /** - * @brief Commit transaction. - */ - API_EXPORT virtual void OnCommit() const; - + static std::string GetDefaultDatabasePath(const std::string &baseDir, const std::string &name, int &errorCode); /** - * @brief Rollback transaction. + * @brief build query sql string. */ - API_EXPORT virtual void OnRollback() const; + static std::string BuildQueryString(const AbsRdbPredicates &predicates, const std::vector &columns); }; } // namespace NativeRdb } // namespace OHOS -#endif \ No newline at end of file +#endif diff --git a/relational_store/interfaces/inner_api/rdb/include/rdb_store.h b/relational_store/interfaces/inner_api/rdb/include/rdb_store.h index 513b1016..139b6270 100644 --- a/relational_store/interfaces/inner_api/rdb/include/rdb_store.h +++ b/relational_store/interfaces/inner_api/rdb/include/rdb_store.h @@ -386,7 +386,8 @@ public: * @param tables Indicates the tables name you want to set. */ virtual int SetDistributedTables(const std::vector &tables, - int32_t type = DistributedRdb::DistributedTableType::DISTRIBUTED_DEVICE) = 0; + int32_t type = DistributedRdb::DistributedTableType::DISTRIBUTED_DEVICE, + const DistributedRdb::DistributedConfig &distributedConfig = { false }) = 0; /** * @brief Obtain distributed table name of specified remote device according to local table name. diff --git a/relational_store/interfaces/inner_api/rdb/include/rdb_types.h b/relational_store/interfaces/inner_api/rdb/include/rdb_types.h index 569b11e0..188e88dc 100644 --- a/relational_store/interfaces/inner_api/rdb/include/rdb_types.h +++ b/relational_store/interfaces/inner_api/rdb/include/rdb_types.h @@ -53,7 +53,7 @@ enum SyncMode { PUSH, PULL, PULL_PUSH, - TIME_FIRST, + TIME_FIRST = 4, NATIVE_FIRST, CLOUD_FIRST, }; @@ -68,6 +68,10 @@ enum DistributedTableType { DISTRIBUTED_CLOUD }; +struct DistributedConfig { + bool autoSync = false; +}; + enum Progress { SYNC_BEGIN, SYNC_IN_PROGRESS, @@ -118,7 +122,7 @@ struct RdbPredicateOperation { std::vector values_; }; -struct RdbPredicates { +struct PredicatesMemo { inline void AddOperation(const RdbPredicateOperator op, const std::string& field, const std::string& value) { @@ -154,7 +158,13 @@ struct Origin { ORIGIN_ALL, ORIGIN_BUTT, }; + enum DataType : int32_t { + BASIC_DATA, + ASSET_DATA, + TYPE_BUTT, + }; int32_t origin = ORIGIN_ALL; + int32_t dataType = BASIC_DATA; // origin is ORIGIN_LOCAL, the id is empty // origin is ORIGIN_NEARBY, the id is networkId; // origin is ORIGIN_CLOUD, the id is the cloud account id diff --git a/relational_store/interfaces/inner_api/rdb/include/remote_result_set.h b/relational_store/interfaces/inner_api/rdb/include/remote_result_set.h index 0c2ab95c..b8f21ea6 100644 --- a/relational_store/interfaces/inner_api/rdb/include/remote_result_set.h +++ b/relational_store/interfaces/inner_api/rdb/include/remote_result_set.h @@ -39,6 +39,10 @@ enum class ColumnType { TYPE_STRING, /** Indicates the column type is BLOB.*/ TYPE_BLOB, + /** Indicates the column type is ASSET.*/ + TYPE_ASSET, + /** Indicates the column type is ASSETS.*/ + TYPE_ASSETS, }; /** diff --git a/relational_store/interfaces/inner_api/rdb/include/sqlite_database_utils.h b/relational_store/interfaces/inner_api/rdb/include/sqlite_database_utils.h deleted file mode 100644 index 3de5e2a7..00000000 --- a/relational_store/interfaces/inner_api/rdb/include/sqlite_database_utils.h +++ /dev/null @@ -1,72 +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. - */ - -#ifndef NATIVE_RDB_SQLITE_DATABASE_UTILS_H -#define NATIVE_RDB_SQLITE_DATABASE_UTILS_H - -#include -#include -#include - -#include "rdb_store_config.h" - -namespace OHOS { -namespace NativeRdb { -enum Type { - STATEMENT_SELECT = 1, - STATEMENT_UPDATE = 2, - STATEMENT_ATTACH = 3, - STATEMENT_DETACH = 4, - STATEMENT_BEGIN = 5, - STATEMENT_COMMIT = 6, - STATEMENT_ROLLBACK = 7, - STATEMENT_PRAGMA = 8, - STATEMENT_DDL = 9, - STATEMENT_OTHER = 99, - DATA_TYPE_BOOLEAN = 5, - DATA_TYPE_BLOB = 4, - DATA_TYPE_STRING = 3, - DATA_TYPE_FLOAT = 2, - DATA_TYPE_INTEGER = 1, - DATA_TYPE_NULL = 0, - SQL_FIRST_CHARACTER = 3 -}; - -class API_EXPORT SqliteDatabaseUtils { -public: - API_EXPORT static std::map MapInit(); - API_EXPORT static int GetSqlStatementType(std::string sql); - API_EXPORT static void DeleteFile(std::string &fileName); - API_EXPORT static bool RenameFile(std::string &oldFileName, std::string &newFileName); - API_EXPORT static std::string GetDefaultDatabasePath(const std::string &baseDir, const std::string &name, - int &errorCode); - API_EXPORT static std::string GetCorruptPath(std::string &path, int &errorCode); - API_EXPORT static std::string StrToUpper(std::string s); - API_EXPORT static bool BeginExecuteSql(const std::string &sql); - API_EXPORT static bool IsReadOnlySql(std::string sql); - -private: - static std::map g_statementType; - static std::mutex g_locker; - static int g_mkdirMode; - - SqliteDatabaseUtils(); - ~SqliteDatabaseUtils(); - static bool IsSpecial(int sqlType); -}; -} // namespace NativeRdb -} // namespace OHOS - -#endif diff --git a/relational_store/interfaces/inner_api/rdb/mock/include/asset_value.h b/relational_store/interfaces/inner_api/rdb/mock/include/asset_value.h index 41fa8841..3827d53b 100644 --- a/relational_store/interfaces/inner_api/rdb/mock/include/asset_value.h +++ b/relational_store/interfaces/inner_api/rdb/mock/include/asset_value.h @@ -18,13 +18,22 @@ #include namespace OHOS::NativeRdb { struct AssetValue { + enum Status : int32_t { + STATUS_NORMAL, + STATUS_ABNORMAL, + STATUS_DOWNLOADING, + STATUS_BUTT + }; uint32_t version = 0; + uint32_t status = 0; + uint64_t timeStamp = 0; std::string name; std::string uri; std::string createTime; std::string modifyTime; std::string size; std::string hash; + std::string path; }; } #endif // OHOS_RELATIONAL_STORE_INNER_API_ASSET_VALUE_H diff --git a/relational_store/interfaces/inner_api/rdb/mock/include/sqlite_database_utils.h b/relational_store/interfaces/inner_api/rdb/mock/include/sqlite_database_utils.h deleted file mode 100644 index 2c699ba8..00000000 --- a/relational_store/interfaces/inner_api/rdb/mock/include/sqlite_database_utils.h +++ /dev/null @@ -1,70 +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. - */ - -#ifndef NATIVE_RDB_SQLITE_DATABASE_UTILS_H -#define NATIVE_RDB_SQLITE_DATABASE_UTILS_H - -#include -#include -#include - -#include "rdb_store_config.h" - -namespace OHOS { -namespace NativeRdb { -enum Type { - STATEMENT_SELECT = 1, - STATEMENT_UPDATE = 2, - STATEMENT_ATTACH = 3, - STATEMENT_DETACH = 4, - STATEMENT_BEGIN = 5, - STATEMENT_COMMIT = 6, - STATEMENT_ROLLBACK = 7, - STATEMENT_PRAGMA = 8, - STATEMENT_DDL = 9, - STATEMENT_OTHER = 99, - DATA_TYPE_BOOLEAN = 5, - DATA_TYPE_BLOB = 4, - DATA_TYPE_STRING = 3, - DATA_TYPE_FLOAT = 2, - DATA_TYPE_INTEGER = 1, - DATA_TYPE_NULL = 0, - SQL_FIRST_CHARACTER = 3 -}; - -class SqliteDatabaseUtils { -public: - static std::map MapInit(); - static int GetSqlStatementType(std::string sql); - static void DeleteFile(std::string &fileName); - static bool RenameFile(std::string &oldFileName, std::string &newFileName); - static std::string GetDefaultDatabasePath(std::string &baseDir, std::string &name, int &errorCode); - static std::string GetCorruptPath(std::string &path, int &errorCode); - static std::string StrToUpper(std::string s); - static bool BeginExecuteSql(const std::string &sql); - static bool IsReadOnlySql(std::string sql); -private: - static std::map g_statementType; - static std::mutex g_locker; - static int g_mkdirMode; - - SqliteDatabaseUtils(); - ~SqliteDatabaseUtils(); - static bool IsSpecial(int sqlType); -}; -} // namespace NativeRdb -} // namespace OHOS - -#endif diff --git a/relational_store/test/js/relationalstore/unittest/src/RdbStoreCloud.test.js b/relational_store/test/js/relationalstore/unittest/src/RdbStoreCloud.test.js new file mode 100644 index 00000000..c21bc4a3 --- /dev/null +++ b/relational_store/test/js/relationalstore/unittest/src/RdbStoreCloud.test.js @@ -0,0 +1,154 @@ +/* + * 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. + */ + +import {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from 'deccjsunit/index' +import data_relationalStore from '@ohos.data.relationalStore'; +import ability_featureAbility from '@ohos.ability.featureAbility' +import {DistributedType} from "../../../../../interfaces/inner_api/js/@ohos.data.relationalStore"; + +const TAG = "[RELATIONAL_STORE_JSKITS_TEST]" +const STORE_NAME = "cloud_rdb.db" +const E_NOT_SUPPORTED = 801; +var rdbStore = undefined; +var context = ability_featureAbility.getContext() + +describe('rdbStoreDistributedCloudTest', function () { + beforeAll(async function (done) { + console.info(TAG + 'beforeAll') + const config = { + "name": STORE_NAME, + securityLevel: data_relationalStore.SecurityLevel.S1, + } + try { + rdbStore = await data_relationalStore.getRdbStore(context, config); + console.log(TAG + "create rdb store success") + let sqlStatement = "CREATE TABLE IF NOT EXISTS employee (" + + "id INTEGER PRIMARY KEY AUTOINCREMENT," + + "name TEXT NOT NULL," + + "age INTEGER)" + try { + await rdbStore.executeSql(sqlStatement, null) + console.log(TAG + "create table employee success") + } catch (err) { + console.log(TAG + "create table employee failed") + expect(null).assertFail() + } + + sqlStatement = "CREATE TABLE IF NOT EXISTS product (" + + "id INTEGER PRIMARY KEY AUTOINCREMENT," + + "name TEXT NOT NULL," + + "price REAL," + + "vendor INTEGER," + + "describe TEXT)" + try { + await rdbStore.executeSql(sqlStatement, null) + console.log(TAG + "create table product success") + done() + } catch (err) { + console.log(TAG + "create table product failed") + expect(null).assertFail() + } + } catch (err) { + console.log(TAG + "create rdb store failed" + `, error code is ${err.code}, message is ${err.message}`) + expect(null).assertFail() + } + done() + }) + + beforeEach(async function () { + console.info(TAG + 'beforeEach') + }) + + afterEach(async function () { + console.info(TAG + 'afterEach') + }) + + afterAll(async function () { + console.info(TAG + 'afterAll') + rdbStore = null + await data_relationalStore.deleteRdbStore(context, STORE_NAME); + }) + + console.log(TAG + "*************Unit Test Begin*************"); + + /** + * @tc.name set distributed table cloud none table + * @tc.number SUB_DDM_AppDataFWK_JSRDB_CLOUD_0001 + * @tc.desc rdb set distributed table cloud using none table as argment + */ + it('testRdbStoreCloud0001', 0, async function (done) { + console.log(TAG + "************* testRdbStoreCloud0001 start *************"); + try { + let config = { + autoSync:false + } + await rdbStore.setDistributedTables([],rdbStore.DistributedType.DISTRIBUTED_CLOUD,config) + console.log(TAG + "set none to be distributed table cloud success"); + expect(false).assertTrue(); + } catch (err) { + console.log(TAG + `set none to be distributed table cloud failed, err code is ${err.code}, message is ${err.message}.`); + expect(E_NOT_SUPPORTED).assertEqual(err.code); + } + done() + console.log(TAG + "************* testRdbStoreCloud0001 end *************"); + }) + + /** + * @tc.name set distributed table cloud using one table name + * @tc.number SUB_DDM_AppDataFWK_JSRDB_CLOUD_0002 + * @tc.desc set distributed table cloud using one table name + */ + it('testRdbStoreCloud0002', 0, async function (done) { + console.log(TAG + "************* testRdbStoreCloud0002 start *************"); + try { + let config = { + autoSync:true + } + await rdbStore.setDistributedTables(['employee'],rdbStore.DistributedType.DISTRIBUTED_CLOUD,config) + console.log(TAG + "set employee to be distributed table cloud success"); + expect(true).assertTrue(); + } catch (err) { + console.log(TAG + `set employee to be distributed table cloud failed, err code is ${err.code}, message is ${err.message}.`); + expect(false).assertTrue(); + } + done() + console.log(TAG + "************* testRdbStoreCloud0002 end *************"); + }) + + /** + * @tc.name set distributed table cloud using two table name + * @tc.number SUB_DDM_AppDataFWK_JSRDB_CLOUD_0003 + * @tc.desc set distributed table cloud using two table name + */ + it('testRdbStoreCloud0003', 0, async function (done) { + console.log(TAG + "************* testRdbStoreCloud0003 start *************"); + try { + let config = { + autoSync:false + } + await rdbStore.setDistributedTables(['employee', 'product'], rdbStore.DistributedType.DISTRIBUTED_CLOUD, + config) + console.log(TAG + "set employee and product to be distributed cloud table success"); + expect(true).assertTrue(); + } catch (err) { + console.log(TAG + `set employee and product to be distributed table failed, err code is ${err.code}, message is ${err.message}.`); + expect(false).assertTrue(); + } + done() + console.log(TAG + "************* testRdbStoreCloud0003 end *************"); + }) + + console.log(TAG + "*************Unit Test End*************"); +}) diff --git a/relational_store/test/native/rdb/fuzztest/rdbimpl_fuzzer/rdbimpl_fuzzer.cpp b/relational_store/test/native/rdb/fuzztest/rdbimpl_fuzzer/rdbimpl_fuzzer.cpp index ac381ef3..1a133444 100644 --- a/relational_store/test/native/rdb/fuzztest/rdbimpl_fuzzer/rdbimpl_fuzzer.cpp +++ b/relational_store/test/native/rdb/fuzztest/rdbimpl_fuzzer/rdbimpl_fuzzer.cpp @@ -25,7 +25,7 @@ void RdbStoreImplFuzz(const uint8_t *data, size_t size) std::string rawString(reinterpret_cast(data), size); std::vector tables; tables.push_back(rawString); - rdbStoreImpl.SetDistributedTables(tables, size % 2); + rdbStoreImpl.SetDistributedTables(tables, size & 0x1, { size & 0x1 }); } } diff --git a/relational_store/test/native/rdb/unittest/common.h b/relational_store/test/native/rdb/unittest/common.h index e52e307f..47052b25 100644 --- a/relational_store/test/native/rdb/unittest/common.h +++ b/relational_store/test/native/rdb/unittest/common.h @@ -19,10 +19,9 @@ #include #include -#include "sqlite_database_utils.h" +#include "rdb_sql_utils.h" namespace OHOS { namespace NativeRdb { -using DBUtils = SqliteDatabaseUtils; #define RDB_TEST_PATH "/data/service/el1/public/database/relational_test/" #define RDB_TEST_C_PATH(subPath) RDB_TEST_PATH "rdb/" subPath #define RDB_TEST_BUNDLE_NAME "relational_test" @@ -33,7 +32,7 @@ static inline std::string CreateTestPath(const std::string &dbName) mkdir(RDB_TEST_PATH, 02771); chown(RDB_TEST_PATH, 0, 3012); } - return DBUtils::GetDefaultDatabasePath(RDB_TEST_PATH, dbName, errCode); + return RdbSqlUtils::GetDefaultDatabasePath(RDB_TEST_PATH, dbName, errCode); } // "com.example.distributed.rdb" diff --git a/relational_store/test/native/rdb/unittest/rdb_asset_test.cpp b/relational_store/test/native/rdb/unittest/rdb_asset_test.cpp new file mode 100644 index 00000000..8d8b4424 --- /dev/null +++ b/relational_store/test/native/rdb/unittest/rdb_asset_test.cpp @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "common.h" +#include "rdb_errno.h" +#include "rdb_helper.h" +#include "rdb_open_callback.h" + +using namespace testing::ext; +using namespace OHOS::NativeRdb; + +class RdbAssetTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + + static const std::string MAIN_DATABASE_NAME; + static constexpr const char *TABLE_NAME = "test"; + static std::shared_ptr store_; +}; +std::shared_ptr RdbAssetTest::store_; +const std::string RdbAssetTest::MAIN_DATABASE_NAME = CreateTestPath("asset_test.db"); + +class RdbAssetTestCallback : public RdbOpenCallback { +public: + int OnCreate(RdbStore &rdbStore) override; + int OnUpgrade(RdbStore &rdbStore, int oldVersion, int newVersion) override; + static const std::string CREATE_TABLE_TEST; +}; + +std::string const RdbAssetTestCallback::CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY " + "AUTOINCREMENT, data1 asset, data2 asset, data3 " + "assets )"; + +int RdbAssetTestCallback::OnCreate(RdbStore &store) +{ + return store.ExecuteSql(CREATE_TABLE_TEST); +} + +int RdbAssetTestCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion) +{ + return E_OK; +} + +void RdbAssetTest::SetUpTestCase(void) +{ + RdbHelper::ClearCache(); + RdbHelper::DeleteRdbStore(MAIN_DATABASE_NAME); +} + +void RdbAssetTest::TearDownTestCase(void) +{ + store_ = nullptr; + RdbHelper::ClearCache(); + RdbHelper::DeleteRdbStore(MAIN_DATABASE_NAME); +} + +void RdbAssetTest::SetUp(void) +{ + store_ = nullptr; + RdbHelper::ClearCache(); + RdbStoreConfig config(MAIN_DATABASE_NAME); + RdbAssetTestCallback callback; + int errCode = E_OK; + store_ = RdbHelper::GetRdbStore(config, 1, callback, errCode); + EXPECT_NE(store_, nullptr); + AssetValue asset1 = { + version: 1, + name: "name1", + uri: "uri1", + createTime: "createTime1", + modifyTime: "modifyTime1", + size: "size1", + hash: "hash1", + }; + AssetValue asset2 = { + version: 2, + name: "name2", + uri: "uri2", + createTime: "createTime2", + modifyTime: "modifyTime2", + size: "size2", + hash: "hash2", + }; + AssetValue asset3 = { + version: 3, + name: "name3", + uri: "uri3", + createTime: "createTime3", + modifyTime: "modifyTime3", + size: "size3", + hash: "hash3", + }; + int64_t rowId = -1; + ValuesBucket valueBucket; + valueBucket.Put("data1", asset1); + valueBucket.Put("data2", asset2); + valueBucket.Put("data3", { asset1 }); + store_->Insert(rowId, TABLE_NAME, std::move(valueBucket)); + valueBucket.Put("data1", asset2); + valueBucket.Put("data2", asset3); + valueBucket.Put("data3", std::vector{ asset1, asset2, asset3 }); + store_->Insert(rowId, TABLE_NAME, std::move(valueBucket)); + valueBucket.Put("data1", asset2); + valueBucket.Put("data3", ValueObject::Assets()); + store_->Insert(rowId, TABLE_NAME, std::move(valueBucket)); +} + +void RdbAssetTest::TearDown(void) +{ + store_ = nullptr; + RdbHelper::ClearCache(); +} + +/** + * @tc.name: RdbStore_Attach_001 + * @tc.desc: test attach, attach is not supported in wal mode + * @tc.type: FUNC + */ +HWTEST_F(RdbAssetTest, RdbStore_Attach_001, TestSize.Level1) +{ + RdbPredicates predicates("test"); + auto resultSet = store_->Query(predicates, {}); + while (resultSet->GoToNextRow()) { + int32_t index; + resultSet->GetColumnIndex("id", index); + int64_t value; + auto ret = resultSet->GetLong(index, value); + ASSERT_EQ(ret, E_OK); + resultSet->GetColumnIndex("data1", index); + AssetValue asset; + ret = resultSet->GetAsset(index, asset); + ASSERT_EQ(ret, E_OK); + resultSet->GetColumnIndex("data2", index); + ret = resultSet->GetAsset(index, asset); + ASSERT_EQ(ret, E_OK); + } +} diff --git a/relational_store/test/native/rdb/unittest/rdb_store_rekey_test.cpp b/relational_store/test/native/rdb/unittest/rdb_store_rekey_test.cpp index e3984107..291d5681 100644 --- a/relational_store/test/native/rdb/unittest/rdb_store_rekey_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_store_rekey_test.cpp @@ -23,7 +23,7 @@ #include "rdb_helper.h" #include "rdb_open_callback.h" #include "rdb_security_manager.h" -#include "sqlite_database_utils.h" +#include "sqlite_utils.h" using namespace testing::ext; using namespace OHOS::NativeRdb; @@ -275,7 +275,7 @@ HWTEST_F(RdbRekeyTest, Rdb_Rekey_03, TestSize.Level1) bool isFileExists = OHOS::FileExists(keyPath); ASSERT_TRUE(isFileExists); - SqliteDatabaseUtils::DeleteFile(keyPath); + SqliteUtils::DeleteFile(keyPath); isFileExists = OHOS::FileExists(keyPath); ASSERT_FALSE(isFileExists); isFileExists = OHOS::FileExists(newKeyPath); diff --git a/relational_store/test/native/rdb/unittest/rdb_store_subscribe_test.cpp b/relational_store/test/native/rdb/unittest/rdb_store_subscribe_test.cpp index 215fa706..c22fa1ae 100644 --- a/relational_store/test/native/rdb/unittest/rdb_store_subscribe_test.cpp +++ b/relational_store/test/native/rdb/unittest/rdb_store_subscribe_test.cpp @@ -1,28 +1,31 @@ /* -* Copyright (c) 2023 Huawei Device Co., Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -#include + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include #include +#include "block_data.h" #include "cloud_manager.h" #include "common.h" #include "rdb_errno.h" #include "rdb_helper.h" #include "rdb_open_callback.h" +#include "rdb_predicates.h" #include "rdb_store_manager.h" #include "rdb_types.h" +namespace OHOS::Test { using namespace testing::ext; using namespace OHOS::NativeRdb; using namespace OHOS::DistributedRdb; @@ -39,6 +42,8 @@ public: static std::shared_ptr store; static constexpr const char *CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test1(id INTEGER PRIMARY KEY, " "name TEXT NOT NULL, age INTEGER)"; + static constexpr const char *CREATE_CLOUD_TABLE = "CREATE TABLE IF NOT EXISTS cloud_test(id INTEGER PRIMARY KEY, " + "name TEXT NOT NULL, age INTEGER)"; }; const std::string RdbStoreSubTest::MAIN_DATABASE_NAME = CreateTestPath("subscribe.db"); @@ -48,11 +53,13 @@ void RdbStoreSubTest::SetUpTestCase(void) { auto [success, service] = CloudManager::GetInstance().GetCloudService(); if (service != nullptr) { - service->EnableCloud("default", { { "relational_test", CloudService::SWITCH_ON } }); + // service->EnableCloud("default", { { "relational_test", CloudService::SWITCH_ON } }); } RdbHelper::ClearCache(); RdbHelper::DeleteRdbStore(MAIN_DATABASE_NAME); store = CreateRDB(1); + store->SetDistributedTables({"test1"}); + store->SetDistributedTables({"cloud_test"}, DISTRIBUTED_CLOUD); } void RdbStoreSubTest::TearDownTestCase(void) @@ -62,13 +69,9 @@ void RdbStoreSubTest::TearDownTestCase(void) RdbHelper::DeleteRdbStore(MAIN_DATABASE_NAME); } -void RdbStoreSubTest::SetUp() -{ -} +void RdbStoreSubTest::SetUp() {} -void RdbStoreSubTest::TearDown() -{ -} +void RdbStoreSubTest::TearDown() {} class Callback : public RdbOpenCallback { public: @@ -78,7 +81,8 @@ public: int Callback::OnCreate(RdbStore &store) { - return store.ExecuteSql(RdbStoreSubTest::CREATE_TABLE_TEST); + store.ExecuteSql(RdbStoreSubTest::CREATE_TABLE_TEST); + return store.ExecuteSql(RdbStoreSubTest::CREATE_CLOUD_TABLE); } int Callback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion) @@ -88,15 +92,11 @@ int Callback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion) class SubObserver : public RdbStoreObserver { public: - virtual ~SubObserver() - { - } + virtual ~SubObserver() {} void OnChange(const std::vector &devices) override; }; -void SubObserver::OnChange(const std::vector &devices) -{ -} +void SubObserver::OnChange(const std::vector &devices) {} std::shared_ptr RdbStoreSubTest::CreateRDB(int version) { @@ -159,19 +159,100 @@ HWTEST_F(RdbStoreSubTest, RdbStoreSubscribeCloudDetail, TestSize.Level1) } /** -* @tc.name: RdbStoreSubscribeCloudDetail -* @tc.desc: RdbStoreSubscribe +* @tc.name: BlockSyncDetails +* @tc.desc: BlockSyncDetails * @tc.type: FUNC * @tc.require: * @tc.author: */ -HWTEST_F(RdbStoreSubTest, Sync, TestSize.Level1) +HWTEST_F(RdbStoreSubTest, BlockSyncDetails, TestSize.Level1) { EXPECT_NE(store, nullptr) << "store is nullptr"; SyncOption option; option.mode = TIME_FIRST; option.isBlock = true; Details details; - auto status = store->Sync(option, {}, [&details](Details &&result) { details = std::move(result); }); + auto status = store->Sync(option, {}, [&details](Details &&result) { + details = std::move(result); + }); EXPECT_EQ(status, E_OK); + EXPECT_NE(details.size(), 0); + auto &detail = details["default"]; + EXPECT_EQ(detail.progress, SYNC_FINISH); + EXPECT_EQ(detail.code, 0); +} + +/** +* @tc.name: BlockSyncBrief +* @tc.desc: BlockSyncBrief +* @tc.type: FUNC +* @tc.require: +* @tc.author: +*/ +HWTEST_F(RdbStoreSubTest, BlockSyncBrief, TestSize.Level1) +{ + EXPECT_NE(store, nullptr) << "store is nullptr"; + SyncOption option; + option.mode = PULL; + option.isBlock = true; + Briefs briefs; + NativeRdb::RdbPredicates predicates("test1"); + auto status = store->Sync(option, predicates, [&briefs](const Briefs &result) { briefs = result; }); + EXPECT_EQ(status, E_OK); + EXPECT_NE(briefs.size(), 0); + for (auto &[device, code] : briefs) { + EXPECT_EQ(code, 0); + } +} + +/** +* @tc.name: ASyncDetails +* @tc.desc: ASyncDetails +* @tc.type: FUNC +* @tc.require: +* @tc.author: +*/ +HWTEST_F(RdbStoreSubTest, ASyncDetails, TestSize.Level1) +{ + EXPECT_NE(store, nullptr) << "store is nullptr"; + SyncOption option; + option.mode = TIME_FIRST; + option.isBlock = false; + auto blocker = std::make_shared>(1); + auto status = store->Sync(option, {}, [blocker](Details &&result) { + blocker->SetValue(std::move(result)); + }); + EXPECT_EQ(status, E_OK); + auto details = blocker->GetValue(); + EXPECT_NE(details.size(), 0); + auto &detail = details["default"]; + EXPECT_EQ(detail.progress, SYNC_FINISH); + EXPECT_EQ(detail.code, 0); +} + +/** +* @tc.name: ASyncBrief +* @tc.desc: ASyncBrief +* @tc.type: FUNC +* @tc.require: +* @tc.author: +*/ +HWTEST_F(RdbStoreSubTest, ASyncBrief, TestSize.Level1) +{ + EXPECT_NE(store, nullptr) << "store is nullptr"; + SyncOption option; + option.mode = PULL; + option.isBlock = false; + auto blocker = std::make_shared>(1); + NativeRdb::RdbPredicates predicates("test1"); + auto status = store->Sync(option, predicates, [blocker](const Briefs& briefs) { + blocker->SetValue(briefs); + }); + EXPECT_EQ(status, E_OK); + auto briefs = blocker->GetValue(); + EXPECT_NE(briefs.size(), 0); + for (auto &[device, code] : briefs) { + EXPECT_EQ(code, 0); + } +} } \ No newline at end of file -- Gitee