From 83309c2f7bd4dc98069c59c92035d2cf53bf8ff7 Mon Sep 17 00:00:00 2001 From: Sven Wang Date: Wed, 1 Jun 2022 21:33:19 +0800 Subject: [PATCH 1/7] call ipc interface Signed-off-by: Sven Wang --- .../src/kvstore_observer_client.cpp | 24 +- .../src/kvstore_observer_client.h | 13 +- .../src/single_kvstore_client.cpp | 7 +- .../src/single_kvstore_client.h | 2 +- .../innerkitsimpl/kvdb/include/kvdb_service.h | 2 +- .../kvdb/include/kvdb_service_client.h | 2 +- .../kvdb/include/observer_bridge.h | 17 +- .../kvdb/include/single_store_impl.h | 28 +- .../kvdb/src/kvdb_service_client.cpp | 3 +- .../kvdb/src/observer_bridge.cpp | 47 +++- .../kvdb/src/single_store_impl.cpp | 263 ++++++++++++------ .../kvdb/test/single_store_impl_test.cpp | 129 ++++++++- .../distributeddata/include/single_kvstore.h | 2 +- .../innerkits/distributeddata/include/types.h | 2 +- .../app/distributed_data.cfg | 2 +- .../service/kvdb/kvdb_service_impl.cpp | 6 +- .../service/kvdb/kvdb_service_impl.h | 2 +- 17 files changed, 387 insertions(+), 164 deletions(-) diff --git a/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_observer_client.cpp b/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_observer_client.cpp index 38f7192de..2996c2093 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_observer_client.cpp +++ b/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_observer_client.cpp @@ -20,9 +20,8 @@ namespace OHOS { namespace DistributedKv { -KvStoreObserverClient::KvStoreObserverClient( - const StoreId &storeId, SubscribeType subscribeType, std::shared_ptr kvStoreObserver) - : storeId_(storeId), subscribeType_(subscribeType), kvStoreObserver_(kvStoreObserver) +KvStoreObserverClient::KvStoreObserverClient(std::shared_ptr kvStoreObserver) + : kvStoreObserver_(kvStoreObserver) { ZLOGI("start"); } @@ -40,20 +39,5 @@ void KvStoreObserverClient::OnChange(const ChangeNotification &changeNotificatio kvStoreObserver_->OnChange(changeNotification); } } - -const StoreId &KvStoreObserverClient::GetStoreId() const -{ - return storeId_; -} - -const SubscribeType &KvStoreObserverClient::GetSubscribeType() const -{ - return subscribeType_; -} - -const std::shared_ptr KvStoreObserverClient::GetKvStoreObserver() const -{ - return kvStoreObserver_; -} -} // namespace DistributedKv -} // namespace OHOS +} // namespace DistributedKv +} // namespace OHOS diff --git a/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_observer_client.h b/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_observer_client.h index c8035e331..a4c596100 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_observer_client.h +++ b/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_observer_client.h @@ -26,26 +26,15 @@ namespace OHOS { namespace DistributedKv { class KvStoreObserverClient : public KvStoreObserverStub { public: - KvStoreObserverClient( - const StoreId &storeId, SubscribeType subscribeType, std::shared_ptr kvStoreObserver); + KvStoreObserverClient(std::shared_ptr kvStoreObserver); ~KvStoreObserverClient(); void OnChange(const ChangeNotification &changeNotification) override; - const StoreId &GetStoreId() const; - - const SubscribeType &GetSubscribeType() const; - - const std::shared_ptr GetKvStoreObserver() const; - private: static const int MAX_TRY_COUNT = 10; - StoreId storeId_; - - SubscribeType subscribeType_; - // client is responsible for free it when call UnSubscribeKvStore. std::shared_ptr kvStoreObserver_; }; diff --git a/frameworks/innerkitsimpl/distributeddatafwk/src/single_kvstore_client.cpp b/frameworks/innerkitsimpl/distributeddatafwk/src/single_kvstore_client.cpp index 451cee858..415d1cf98 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/src/single_kvstore_client.cpp +++ b/frameworks/innerkitsimpl/distributeddatafwk/src/single_kvstore_client.cpp @@ -164,7 +164,7 @@ Status SingleKvStoreClient::GetCount(const DataQuery &query, int &count) const return kvStoreProxy_->GetCountWithQuery(query.ToString(), count); } -Status SingleKvStoreClient::Sync(const std::vector &devices, SyncMode mode, uint32_t allowedDelayMs) +Status SingleKvStoreClient::Sync(const std::vector &devices, SyncMode mode, uint32_t delay) { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__), true); if (kvStoreProxy_ == nullptr) { @@ -178,7 +178,7 @@ Status SingleKvStoreClient::Sync(const std::vector &devices, SyncMo uint64_t sequenceId = KvStoreUtils::GenerateSequenceId(); syncCallbackClient_->AddSyncCallback(syncObserver_, sequenceId); RegisterCallback(); - return kvStoreProxy_->Sync(devices, mode, allowedDelayMs, sequenceId); + return kvStoreProxy_->Sync(devices, mode, delay, sequenceId); } Status SingleKvStoreClient::RemoveDeviceData(const std::string &device) @@ -258,8 +258,7 @@ Status SingleKvStoreClient::SubscribeKvStore(SubscribeType subscribeType, std::s return Status::STORE_ALREADY_SUBSCRIBE; } // remove storeId after remove SubscribeKvStore function in manager. currently reserve for convenience. - sptr ipcObserver = new (std::nothrow) - KvStoreObserverClient(GetStoreId(), subscribeType, observer); + sptr ipcObserver = new (std::nothrow) KvStoreObserverClient(observer); if (ipcObserver == nullptr) { ZLOGW("new KvStoreObserverClient failed"); return Status::ERROR; diff --git a/frameworks/innerkitsimpl/distributeddatafwk/src/single_kvstore_client.h b/frameworks/innerkitsimpl/distributeddatafwk/src/single_kvstore_client.h index 492fe0178..32957a2b6 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/src/single_kvstore_client.h +++ b/frameworks/innerkitsimpl/distributeddatafwk/src/single_kvstore_client.h @@ -44,7 +44,7 @@ public: Status GetCount(const DataQuery &query, int &count) const override; - Status Sync(const std::vector &devices, SyncMode mode, uint32_t allowedDelayMs) override; + Status Sync(const std::vector &devices, SyncMode mode, uint32_t delay) override; Status RemoveDeviceData(const std::string &device) override; diff --git a/frameworks/innerkitsimpl/kvdb/include/kvdb_service.h b/frameworks/innerkitsimpl/kvdb/include/kvdb_service.h index c2210feff..8c00332e5 100644 --- a/frameworks/innerkitsimpl/kvdb/include/kvdb_service.h +++ b/frameworks/innerkitsimpl/kvdb/include/kvdb_service.h @@ -46,7 +46,7 @@ public: virtual Status AfterCreate( const AppId &appId, const StoreId &storeId, const Options &options, const std::vector &password) = 0; virtual Status Delete(const AppId &appId, const StoreId &storeId, const std::string &path) = 0; - virtual Status Sync(const AppId &appId, const StoreId &storeId, SyncInfo &syncInfo) = 0; + virtual Status Sync(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) = 0; virtual Status RegisterSyncCallback( const AppId &appId, const StoreId &storeId, sptr callback) = 0; virtual Status UnregisterSyncCallback(const AppId &appId, const StoreId &storeId) = 0; diff --git a/frameworks/innerkitsimpl/kvdb/include/kvdb_service_client.h b/frameworks/innerkitsimpl/kvdb/include/kvdb_service_client.h index 477ec964e..615099a1b 100644 --- a/frameworks/innerkitsimpl/kvdb/include/kvdb_service_client.h +++ b/frameworks/innerkitsimpl/kvdb/include/kvdb_service_client.h @@ -31,7 +31,7 @@ public: Status AfterCreate(const AppId &appId, const StoreId &storeId, const Options &options, const std::vector &password) override; Status Delete(const AppId &appId, const StoreId &storeId, const std::string &path) override; - Status Sync(const AppId &appId, const StoreId &storeId, SyncInfo &syncInfo) override; + Status Sync(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) override; Status RegisterSyncCallback( const AppId &appId, const StoreId &storeId, sptr callback) override; Status UnregisterSyncCallback(const AppId &appId, const StoreId &storeId) override; diff --git a/frameworks/innerkitsimpl/kvdb/include/observer_bridge.h b/frameworks/innerkitsimpl/kvdb/include/observer_bridge.h index 113471330..d1510fdc5 100644 --- a/frameworks/innerkitsimpl/kvdb/include/observer_bridge.h +++ b/frameworks/innerkitsimpl/kvdb/include/observer_bridge.h @@ -15,20 +15,31 @@ #ifndef OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_OBSERVER_BRIDGE_H #define OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_OBSERVER_BRIDGE_H +#include "kv_store_nb_delegate.h" #include "kv_store_observer.h" #include "kvstore_observer.h" #include "visibility.h" namespace OHOS::DistributedKv { +class IKvStoreObserver; class API_EXPORT ObserverBridge : public DistributedDB::KvStoreObserver { public: using Convert = std::function; + using Observer = DistributedKv::KvStoreObserver; + using DBEntry = DistributedDB::Entry; + using DBChangedData = DistributedDB::KvStoreChangedData; - ObserverBridge(std::shared_ptr observer, Convert convert = nullptr); - void OnChange(const DistributedDB::KvStoreChangedData &data) override; + ObserverBridge(const AppId &app, const StoreId &store, std::shared_ptr observer, Convert cvt = nullptr); + ~ObserverBridge(); + Status RegisterRemoteObserver(); + Status UnregisterRemoteObserver(); + void OnChange(const DBChangedData &data) override; private: - std::vector ConvertDB(const std::list &dbEntries, std::string &deviceId) const; + std::vector ConvertDB(const std::list &dbEntries, std::string &deviceId) const; std::shared_ptr observer_; + sptr remote_; + AppId appId_; + StoreId storeId_; Convert convert_; }; } // namespace OHOS::DistributedKv diff --git a/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h b/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h index 515a5804c..f0e6c6f40 100644 --- a/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h +++ b/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h @@ -12,28 +12,26 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #ifndef OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_SINGLE_STORE_IMPL_H #define OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_SINGLE_STORE_IMPL_H - -#include - #include #include + +#include "concurrent_map.h" #include "kv_store_nb_delegate.h" +#include "kvdb_service.h" +#include "kvstore_sync_callback_client.h" #include "observer_bridge.h" #include "single_kvstore.h" #include "sync_observer.h" -#include "ikvstore_observer.h" - namespace OHOS::DistributedKv { class API_EXPORT SingleStoreImpl : public SingleKvStore { public: using Observer = KvStoreObserver; - using IPCObserver = IKvStoreObserver; using SyncCallback = KvStoreSyncCallback; using ResultSet = KvStoreResultSet; using DBStore = DistributedDB::KvStoreNbDelegate; + using SyncInfo = KVDBService::SyncInfo; SingleStoreImpl(const AppId &appId, std::shared_ptr dbStore); ~SingleStoreImpl() = default; StoreId GetStoreId() const override; @@ -58,7 +56,7 @@ public: Status Close(); // IPC interface - Status Sync(const std::vector &devices, SyncMode mode, uint32_t allowedDelayMs) override; + Status Sync(const std::vector &devices, SyncMode mode, uint32_t delay) override; Status Sync(const std::vector &devices, SyncMode mode, const DataQuery &query, std::shared_ptr syncCallback) override; Status RegisterSyncCallback(std::shared_ptr callback) override; @@ -73,23 +71,25 @@ public: protected: static constexpr size_t MAX_KEY_LENGTH = 1024; - int ConvertMode(SubscribeType type) const; virtual std::vector ConvertDBKey(const Key &key) const; virtual Key ConvertKey(DistributedDB::Key &&key) const; - virtual sptr GetIPCObserver(std::shared_ptr observer) const; - std::function BridgeReleaser(SubscribeType type); + std::function BridgeReleaser(); private: Status GetResultSet(const DistributedDB::Query &query, std::shared_ptr &resultSet) const; Status GetEntries(const DistributedDB::Query &query, std::vector &entries) const; std::vector GetPrefix(const DataQuery &query) const; + sptr GetIPCSyncClient(); + Status DoSync(const SyncInfo &syncInfo, std::shared_ptr observer); - mutable std::shared_mutex mutex_; + std::string appId_; std::string storeId_; - AppId appId_; + mutable std::shared_mutex rwMutex_; + mutable std::mutex mutex_; std::shared_ptr dbStore_ = nullptr; std::shared_ptr syncObserver_ = nullptr; - ConcurrentMap>> observers_; + sptr syncCallback_ = nullptr; + ConcurrentMap>> observers_; }; } // namespace OHOS::DistributedKv #endif // OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_SINGLE_STORE_IMPL_H diff --git a/frameworks/innerkitsimpl/kvdb/src/kvdb_service_client.cpp b/frameworks/innerkitsimpl/kvdb/src/kvdb_service_client.cpp index eea276587..f8286e5bb 100644 --- a/frameworks/innerkitsimpl/kvdb/src/kvdb_service_client.cpp +++ b/frameworks/innerkitsimpl/kvdb/src/kvdb_service_client.cpp @@ -139,7 +139,8 @@ Status KVDBServiceClient::Delete(const AppId &appId, const StoreId &storeId, con } return StoreFactory::GetInstance().Delete(appId, storeId, path); } -Status KVDBServiceClient::Sync(const AppId &appId, const StoreId &storeId, KVDBService::SyncInfo &syncInfo) + +Status KVDBServiceClient::Sync(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) { MessageParcel reply; int32_t status = IPC_SEND(TRANS_SYNC, reply, appId, storeId, syncInfo.seqId, syncInfo.mode, syncInfo.devices, diff --git a/frameworks/innerkitsimpl/kvdb/src/observer_bridge.cpp b/frameworks/innerkitsimpl/kvdb/src/observer_bridge.cpp index 7827d280b..34ce0d076 100644 --- a/frameworks/innerkitsimpl/kvdb/src/observer_bridge.cpp +++ b/frameworks/innerkitsimpl/kvdb/src/observer_bridge.cpp @@ -12,10 +12,45 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #include "observer_bridge.h" + +#include "kvdb_service_client.h" +#include "kvstore_observer_client.h" namespace OHOS::DistributedKv { -void ObserverBridge::OnChange(const DistributedDB::KvStoreChangedData &data) +ObserverBridge::ObserverBridge(const AppId &app, const StoreId &store, std::shared_ptr observer, Convert cvt) + : appId_(app), storeId_(store), observer_(std::move(observer)), convert_(std::move(cvt)) +{ +} + +ObserverBridge::~ObserverBridge() +{ + if (remote_ != nullptr) { + KVDBServiceClient::GetInstance()->Unsubscribe(appId_, storeId_, remote_); + } +} + +Status ObserverBridge::RegisterRemoteObserver() +{ + if (remote_ != nullptr) { + return SUCCESS; + } + + remote_ = new (std::nothrow) KvStoreObserverClient(observer_); + return KVDBServiceClient::GetInstance()->Subscribe(appId_, storeId_, remote_); +} + +Status ObserverBridge::UnregisterRemoteObserver() +{ + if (remote_ == nullptr) { + return SUCCESS; + } + + auto status = KVDBServiceClient::GetInstance()->Unsubscribe(appId_, storeId_, remote_); + remote_ = nullptr; + return status; +} + +void ObserverBridge::OnChange(const DBChangedData &data) { std::string deviceId; ChangeNotification notification(ConvertDB(data.GetEntriesInserted(), deviceId), @@ -24,13 +59,7 @@ void ObserverBridge::OnChange(const DistributedDB::KvStoreChangedData &data) observer_->OnChange(notification); } -ObserverBridge::ObserverBridge(std::shared_ptr observer, Convert convert) - : observer_(std::move(observer)), convert_(std::move(convert)) -{ -} - -std::vector ObserverBridge::ConvertDB( - const std::list &dbEntries, std::string &deviceId) const +std::vector ObserverBridge::ConvertDB(const std::list &dbEntries, std::string &deviceId) const { std::vector entries(dbEntries.size()); auto it = entries.begin(); diff --git a/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp b/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp index 87309765f..d55b43ba1 100644 --- a/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp +++ b/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp @@ -17,32 +17,28 @@ #include "dds_trace.h" #include "dev_manager.h" -#include "kvstore_observer_client.h" +#include "kvdb_service_client.h" +#include "kvstore_utils.h" #include "log_print.h" #include "store_result_set.h" #include "store_util.h" - namespace OHOS::DistributedKv { SingleStoreImpl::SingleStoreImpl(const AppId &appId, std::shared_ptr dbStore) - : appId_(appId), dbStore_(std::move(dbStore)) + : appId_(appId.appId), dbStore_(std::move(dbStore)) { + storeId_ = dbStore_->GetStoreId(); syncObserver_ = std::make_shared(); } StoreId SingleStoreImpl::GetStoreId() const { - std::shared_lock lock; - if (dbStore_ == nullptr) { - ZLOGE("db:%{public}s already closed!", storeId_.c_str()); - return { storeId_ }; - } - return { dbStore_->GetStoreId() }; + return { storeId_ }; } Status SingleStoreImpl::Put(const Key &key, const Value &value) { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); - std::shared_lock lock; + std::shared_lock lock(rwMutex_); if (dbStore_ == nullptr) { ZLOGE("db:%{public}s already closed!", storeId_.c_str()); return ALREADY_CLOSED; @@ -53,6 +49,7 @@ Status SingleStoreImpl::Put(const Key &key, const Value &value) ZLOGE("invalid key:%{public}s, size:%{public}zu", StoreUtil::Anonymous(key.ToString()).c_str(), key.Size()); return INVALID_ARGUMENT; } + auto dbStatus = dbStore_->Put(dbKey, value); auto status = StoreUtil::ConvertStatus(dbStatus); if (status != SUCCESS) { @@ -66,7 +63,7 @@ Status SingleStoreImpl::Put(const Key &key, const Value &value) Status SingleStoreImpl::PutBatch(const std::vector &entries) { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); - std::shared_lock lock; + std::shared_lock lock(rwMutex_); if (dbStore_ == nullptr) { ZLOGE("db:%{public}s already closed!", storeId_.c_str()); return ALREADY_CLOSED; @@ -96,7 +93,7 @@ Status SingleStoreImpl::PutBatch(const std::vector &entries) Status SingleStoreImpl::Delete(const Key &key) { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); - std::shared_lock lock; + std::shared_lock lock(rwMutex_); if (dbStore_ == nullptr) { ZLOGE("db:%{public}s already closed!", storeId_.c_str()); return ALREADY_CLOSED; @@ -112,13 +109,14 @@ Status SingleStoreImpl::Delete(const Key &key) if (status != SUCCESS) { ZLOGE("status:0x%{public}x, key:%{public}s", status, StoreUtil::Anonymous(key.ToString()).c_str()); } + // do auto sync process return status; } Status SingleStoreImpl::DeleteBatch(const std::vector &keys) { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); - std::shared_lock lock; + std::shared_lock lock(rwMutex_); if (dbStore_ == nullptr) { ZLOGE("db:%{public}s already closed!", storeId_.c_str()); return ALREADY_CLOSED; @@ -133,6 +131,7 @@ Status SingleStoreImpl::DeleteBatch(const std::vector &keys) } dbKeys.push_back(std::move(dbKey)); } + auto dbStatus = dbStore_->DeleteBatch(dbKeys); auto status = StoreUtil::ConvertStatus(dbStatus); if (status != SUCCESS) { @@ -145,7 +144,7 @@ Status SingleStoreImpl::DeleteBatch(const std::vector &keys) Status SingleStoreImpl::StartTransaction() { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); - std::shared_lock lock; + std::shared_lock lock(rwMutex_); if (dbStore_ == nullptr) { ZLOGE("db:%{public}s already closed!", storeId_.c_str()); return ALREADY_CLOSED; @@ -154,7 +153,7 @@ Status SingleStoreImpl::StartTransaction() auto dbStatus = dbStore_->StartTransaction(); auto status = StoreUtil::ConvertStatus(dbStatus); if (status != SUCCESS) { - ZLOGE("status:0x%{public}x storeId:%{public}s", status, dbStore_->GetStoreId().c_str()); + ZLOGE("status:0x%{public}x storeId:%{public}s", status, storeId_.c_str()); } return status; } @@ -162,7 +161,7 @@ Status SingleStoreImpl::StartTransaction() Status SingleStoreImpl::Commit() { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); - std::shared_lock lock; + std::shared_lock lock(rwMutex_); if (dbStore_ == nullptr) { ZLOGE("db:%{public}s already closed!", storeId_.c_str()); return ALREADY_CLOSED; @@ -179,7 +178,7 @@ Status SingleStoreImpl::Commit() Status SingleStoreImpl::Rollback() { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); - std::shared_lock lock; + std::shared_lock lock(rwMutex_); if (dbStore_ == nullptr) { ZLOGE("db:%{public}s already closed!", storeId_.c_str()); return ALREADY_CLOSED; @@ -188,7 +187,7 @@ Status SingleStoreImpl::Rollback() auto dbStatus = dbStore_->Rollback(); auto status = StoreUtil::ConvertStatus(dbStatus); if (status != SUCCESS) { - ZLOGE("status:0x%{public}x storeId:%{public}s", status, dbStore_->GetStoreId().c_str()); + ZLOGE("status:0x%{public}x storeId:%{public}s", status, storeId_.c_str()); } return status; } @@ -196,31 +195,48 @@ Status SingleStoreImpl::Rollback() Status SingleStoreImpl::SubscribeKvStore(SubscribeType type, std::shared_ptr observer) { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); - std::shared_lock lock; + std::shared_lock lock(rwMutex_); if (dbStore_ == nullptr) { ZLOGE("db:%{public}s already closed!", storeId_.c_str()); return ALREADY_CLOSED; } - Status status = SUCCESS; + if (observer == nullptr) { + ZLOGE("invalid observer is null"); + return INVALID_ARGUMENT; + } + + uint32_t realType = type; std::shared_ptr bridge = nullptr; - auto release = BridgeReleaser(type); observers_.Compute(uintptr_t(observer.get()), - [type, observer, &bridge, &release](const auto &, std::map> &bridges) { - if (bridges.find(int32_t(type)) != bridges.end()) { - return true; + [this, &realType, observer, &bridge](const auto &, std::pair> &pair) { + if ((pair.first & realType) == realType) { + return (pair.first != 0); } - bridge = std::shared_ptr(new ObserverBridge(observer), release); - bridges.emplace(int32_t(type), bridge); - return true; + if (pair.first == 0) { + auto release = BridgeReleaser(); + StoreId storeId{ storeId_ }; + AppId appId{ appId_ }; + pair.second = std::shared_ptr(new ObserverBridge(appId, storeId, observer), release); + } + bridge = pair.second; + realType = (realType & (~pair.first)); + pair.first = pair.first | realType; + return (pair.first != 0); }); - if (type == SubscribeType::SUBSCRIBE_TYPE_LOCAL || type == SubscribeType::SUBSCRIBE_TYPE_ALL) { - auto dbStatus = dbStore_->RegisterObserver({}, ConvertMode(type), bridge.get()); + if (bridge == nullptr) { + return STORE_ALREADY_SUBSCRIBE; + } + + Status status = SUCCESS; + if ((realType & SUBSCRIBE_TYPE_LOCAL) == SUBSCRIBE_TYPE_LOCAL) { + auto dbStatus = dbStore_->RegisterObserver({}, DistributedDB::OBSERVER_CHANGES_NATIVE, bridge.get()); status = StoreUtil::ConvertStatus(dbStatus); } - if (type == SubscribeType::SUBSCRIBE_TYPE_REMOTE || type == SubscribeType::SUBSCRIBE_TYPE_ALL) { + if ((realType & SUBSCRIBE_TYPE_REMOTE) == SUBSCRIBE_TYPE_REMOTE) { + bridge->RegisterRemoteObserver(); } if (status != SUCCESS) { @@ -232,24 +248,54 @@ Status SingleStoreImpl::SubscribeKvStore(SubscribeType type, std::shared_ptr observer) { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); + std::shared_lock lock(rwMutex_); + if (dbStore_ == nullptr) { + ZLOGE("db:%{public}s already closed!", storeId_.c_str()); + return ALREADY_CLOSED; + } + + if (observer == nullptr) { + ZLOGE("invalid observer is null"); + return INVALID_ARGUMENT; + } + + uint32_t realType = type; std::shared_ptr bridge = nullptr; observers_.ComputeIfPresent(uintptr_t(observer.get()), - [type, observer, &bridge](const auto &, std::map> &bridges) { - auto it = bridges.find(int32_t(type)); - if (it != bridges.end()) { - bridge = it->second; - bridges.erase(it); + [&realType, observer, &bridge](const auto &, std::pair> &pair) { + if ((pair.first & realType) == 0) { + return (pair.first != 0); } - return !bridges.empty(); + realType = (realType & pair.first); + pair.first = (pair.first & (~realType)); + bridge = pair.second; + return (pair.first != 0); }); - bridge = nullptr; - return SUCCESS; + + if (bridge == nullptr) { + return STORE_NOT_SUBSCRIBE; + } + + Status status = SUCCESS; + if ((realType & SUBSCRIBE_TYPE_LOCAL) == SUBSCRIBE_TYPE_LOCAL) { + auto dbStatus = dbStore_->UnRegisterObserver(bridge.get()); + status = StoreUtil::ConvertStatus(dbStatus); + } + + if ((realType & SUBSCRIBE_TYPE_REMOTE) == SUBSCRIBE_TYPE_REMOTE) { + bridge->UnregisterRemoteObserver(); + } + + if (status != SUCCESS) { + ZLOGE("status:0x%{public}x, type:%{public}d, observer:0x%x", status, type, StoreUtil::Anonymous(bridge.get())); + } + return status; } Status SingleStoreImpl::Get(const Key &key, Value &value) { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); - std::shared_lock lock; + std::shared_lock lock(rwMutex_); if (dbStore_ == nullptr) { ZLOGE("db:%{public}s already closed!", storeId_.c_str()); return ALREADY_CLOSED; @@ -260,6 +306,7 @@ Status SingleStoreImpl::Get(const Key &key, Value &value) ZLOGE("invalid key:%{public}s, size:%{public}zu", key.ToString().c_str(), key.Size()); return INVALID_ARGUMENT; } + DistributedDB::Value dbValue; auto dbStatus = dbStore_->Get(dbKey, dbValue); value = std::move(dbValue); @@ -278,6 +325,7 @@ Status SingleStoreImpl::GetEntries(const Key &prefix, std::vector &entrie ZLOGE("invalid prefix:%{public}s, size:%{public}zu", prefix.ToString().c_str(), prefix.Size()); return INVALID_ARGUMENT; } + DistributedDB::Query dbQuery = DistributedDB::Query::Select(); dbQuery.PrefixKey(dbPrefix); auto status = GetEntries(dbQuery, entries); @@ -335,9 +383,10 @@ Status SingleStoreImpl::CloseResultSet(std::shared_ptr &resultSet) ZLOGE("input is nullptr"); return INVALID_ARGUMENT; } + auto status = resultSet->Close(); if (status != SUCCESS) { - ZLOGE("status:0x%{public}x storeId:%{public}s", status, dbStore_->GetStoreId().c_str()); + ZLOGE("status:0x%{public}x storeId:%{public}s", status, storeId_.c_str()); } resultSet = nullptr; return status; @@ -346,11 +395,12 @@ Status SingleStoreImpl::CloseResultSet(std::shared_ptr &resultSet) Status SingleStoreImpl::GetCount(const DataQuery &query, int &result) const { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); - std::shared_lock lock; + std::shared_lock lock(rwMutex_); if (dbStore_ == nullptr) { ZLOGE("db:%{public}s already closed!", storeId_.c_str()); return ALREADY_CLOSED; } + DistributedDB::Query dbQuery = *(query.query_); dbQuery.PrefixKey(GetPrefix(query)); auto dbStatus = dbStore_->GetCount(dbQuery, result); @@ -364,11 +414,12 @@ Status SingleStoreImpl::GetCount(const DataQuery &query, int &result) const Status SingleStoreImpl::GetSecurityLevel(SecurityLevel &securityLevel) const { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); - std::shared_lock lock; + std::shared_lock lock(rwMutex_); if (dbStore_ == nullptr) { ZLOGE("db:%{public}s already closed!", storeId_.c_str()); return ALREADY_CLOSED; } + DistributedDB::SecurityOption option; auto dbStatus = dbStore_->GetSecurityOption(option); auto status = StoreUtil::ConvertStatus(dbStatus); @@ -382,7 +433,7 @@ Status SingleStoreImpl::GetSecurityLevel(SecurityLevel &securityLevel) const Status SingleStoreImpl::RemoveDeviceData(const std::string &device) { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); - std::shared_lock lock; + std::shared_lock lock(rwMutex_); if (dbStore_ == nullptr) { ZLOGE("db:%{public}s already closed!", storeId_.c_str()); return ALREADY_CLOSED; @@ -398,14 +449,24 @@ Status SingleStoreImpl::RemoveDeviceData(const std::string &device) Status SingleStoreImpl::Sync(const std::vector &devices, SyncMode mode, uint32_t allowedDelayMs) { - // do immediately full sync process - return NOT_SUPPORT; + DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); + KVDBService::SyncInfo syncInfo; + syncInfo.seqId = KvStoreUtils::GenerateSequenceId(); + syncInfo.mode = mode; + syncInfo.delay = mode; + return DoSync(syncInfo, syncObserver_); } Status SingleStoreImpl::Sync(const std::vector &devices, SyncMode mode, const DataQuery &query, std::shared_ptr syncCallback) { - return NOT_SUPPORT; + DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); + KVDBService::SyncInfo syncInfo; + syncInfo.seqId = KvStoreUtils::GenerateSequenceId(); + syncInfo.mode = mode; + syncInfo.devices = devices; + syncInfo.query = query.ToString(); + return DoSync(syncInfo, syncCallback); } Status SingleStoreImpl::RegisterSyncCallback(std::shared_ptr callback) @@ -429,44 +490,58 @@ Status SingleStoreImpl::UnRegisterSyncCallback() Status SingleStoreImpl::SetSyncParam(const KvSyncParam &syncParam) { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__), true); - return NOT_SUPPORT; + return KVDBServiceClient::GetInstance()->SetSyncParam({ appId_ }, { storeId_ }, syncParam); } Status SingleStoreImpl::GetSyncParam(KvSyncParam &syncParam) { - return NOT_SUPPORT; + DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__), true); + return KVDBServiceClient::GetInstance()->GetSyncParam({ appId_ }, { storeId_ }, syncParam); } Status SingleStoreImpl::SetCapabilityEnabled(bool enabled) const { - return NOT_SUPPORT; + DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__), true); + if (enabled) { + return KVDBServiceClient::GetInstance()->EnableCapability({ appId_ }, { storeId_ }); + } + return KVDBServiceClient::GetInstance()->DisableCapability({ appId_ }, { storeId_ }); } Status SingleStoreImpl::SetCapabilityRange( const std::vector &localLabels, const std::vector &remoteLabels) const { - return NOT_SUPPORT; + DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__), true); + return KVDBServiceClient::GetInstance()->SetCapability({ appId_ }, { storeId_ }, localLabels, remoteLabels); } Status SingleStoreImpl::SubscribeWithQuery(const std::vector &devices, const DataQuery &query) { - return NOT_SUPPORT; + DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__), true); + return KVDBServiceClient::GetInstance()->AddSubscribeInfo({ appId_ }, { storeId_ }, devices, query.ToString()); } Status SingleStoreImpl::UnsubscribeWithQuery(const std::vector &devices, const DataQuery &query) { - return NOT_SUPPORT; + DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__), true); + return KVDBServiceClient::GetInstance()->RmvSubscribeInfo({ appId_ }, { storeId_ }, devices, query.ToString()); } Status SingleStoreImpl::Close() { observers_.Clear(); syncObserver_->Clean(); - std::unique_lock lock; - if (dbStore_ != nullptr) { - storeId_ = dbStore_->GetStoreId(); - dbStore_ = nullptr; + bool isFirstClose; + { + std::lock_guard lock(mutex_); + isFirstClose = syncCallback_ != nullptr; + syncCallback_ = nullptr; + } + if (isFirstClose) { + KVDBServiceClient::GetInstance()->UnregisterSyncCallback({ appId_ }, { storeId_ }); } + std::unique_lock lock(rwMutex_); + dbStore_ = nullptr; return SUCCESS; } @@ -488,55 +563,33 @@ Key SingleStoreImpl::ConvertKey(DistributedDB::Key &&key) const return std::move(key); } -sptr SingleStoreImpl::GetIPCObserver(std::shared_ptr observer) const -{ - sptr ipcObserver = - new KvStoreObserverClient({ dbStore_->GetStoreId() }, SUBSCRIBE_TYPE_REMOTE, observer); - return sptr(); -} - -int SingleStoreImpl::ConvertMode(SubscribeType type) const -{ - int mode; - if (type == SubscribeType::SUBSCRIBE_TYPE_LOCAL) { - mode = DistributedDB::OBSERVER_CHANGES_NATIVE; - } else if (type == SubscribeType::SUBSCRIBE_TYPE_REMOTE) { - mode = DistributedDB::OBSERVER_CHANGES_FOREIGN; - } else { - mode = DistributedDB::OBSERVER_CHANGES_FOREIGN | DistributedDB::OBSERVER_CHANGES_NATIVE; - } - return mode; -} - -std::function SingleStoreImpl::BridgeReleaser(SubscribeType type) +std::function SingleStoreImpl::BridgeReleaser() { - return [this, type](ObserverBridge *obj) { - Status status = SUCCESS; + return [this](ObserverBridge *obj) { if (obj == nullptr) { return; } - - if (type == SubscribeType::SUBSCRIBE_TYPE_LOCAL || type == SubscribeType::SUBSCRIBE_TYPE_ALL) { - std::shared_lock lock; - status = ALREADY_CLOSED; + Status status = ALREADY_CLOSED; + { + std::shared_lock lock(rwMutex_); if (dbStore_ != nullptr) { auto dbStatus = dbStore_->UnRegisterObserver(obj); status = StoreUtil::ConvertStatus(dbStatus); } } - if (type == SubscribeType::SUBSCRIBE_TYPE_REMOTE || type == SubscribeType::SUBSCRIBE_TYPE_ALL) { - // status = proxy_->UnregisterObserver({}, ConvertMode(type), bridge); - } - if (status != SUCCESS) { - ZLOGE("status:0x%{public}x type:%{public}d,, observer:0x%x", status, type, StoreUtil::Anonymous(obj)); + Status remote = obj->UnregisterRemoteObserver(); + if (status != SUCCESS || remote != SUCCESS) { + ZLOGE("status:0x%{public}x remote:0x%{public}x observer:0x%{public}x", status, remote, + StoreUtil::Anonymous(obj)); } + delete obj; }; } Status SingleStoreImpl::GetResultSet(const DistributedDB::Query &query, std::shared_ptr &resultSet) const { - std::shared_lock lock; + std::shared_lock lock(rwMutex_); if (dbStore_ == nullptr) { ZLOGE("db:%{public}s already closed!", storeId_.c_str()); return ALREADY_CLOSED; @@ -553,7 +606,7 @@ Status SingleStoreImpl::GetResultSet(const DistributedDB::Query &query, std::sha Status SingleStoreImpl::GetEntries(const DistributedDB::Query &query, std::vector &entries) const { - std::shared_lock lock; + std::shared_lock lock(rwMutex_); if (dbStore_ == nullptr) { ZLOGE("db:%{public}s already closed!", storeId_.c_str()); return ALREADY_CLOSED; @@ -576,4 +629,34 @@ std::vector SingleStoreImpl::GetPrefix(const DataQuery &query) const std::string prefix = DevManager::GetInstance().ToUUID(query.deviceId_) + query.prefix_; return { prefix.begin(), prefix.end() }; } + +sptr SingleStoreImpl::GetIPCSyncClient() +{ + sptr callback; + { + std::lock_guard lock(mutex_); + if (syncCallback_ != nullptr) { + return syncCallback_; + } + syncCallback_ = new (std::nothrow) KvStoreSyncCallbackClient(); + callback = syncCallback_; + } + + if (callback != nullptr) { + KVDBServiceClient::GetInstance()->RegisterSyncCallback({ appId_ }, { storeId_ }, callback); + } + + return callback; +} + +Status SingleStoreImpl::DoSync(const SyncInfo &syncInfo, std::shared_ptr observer) +{ + auto syncClient = GetIPCSyncClient(); + if (syncClient == nullptr) { + ZLOGE("db:%{public}s already closed!", storeId_.c_str()); + return ILLEGAL_STATE; + } + syncClient->AddSyncCallback(observer, syncInfo.seqId); + return KVDBServiceClient::GetInstance()->Sync({ appId_ }, { storeId_ }, syncInfo); +} } // namespace OHOS::DistributedKv \ No newline at end of file diff --git a/frameworks/innerkitsimpl/kvdb/test/single_store_impl_test.cpp b/frameworks/innerkitsimpl/kvdb/test/single_store_impl_test.cpp index 5baa2aec4..609f95b4a 100644 --- a/frameworks/innerkitsimpl/kvdb/test/single_store_impl_test.cpp +++ b/frameworks/innerkitsimpl/kvdb/test/single_store_impl_test.cpp @@ -14,7 +14,7 @@ */ #include -#include +#include #include #include "kvdb_service_client.h" @@ -23,6 +23,41 @@ using namespace testing::ext; using namespace OHOS::DistributedKv; class SingleStoreImplTest : public testing::Test { public: + class TestObserver : public KvStoreObserver { + public: + bool IsChanged() + { + std::unique_lock lock(mutex_); + cv_.wait(lock, [this]() { return isChanged_; }); + bool current = isChanged_; + isChanged_ = false; + cv_.notify_one(); + return current; + } + + void OnChange(const ChangeNotification ¬ification) override + { + insert_ = notification.GetInsertEntries(); + update_ = notification.GetUpdateEntries(); + delete_ = notification.GetDeleteEntries(); + deviceId_ = notification.GetDeviceId(); + { + std::lock_guard lock(mutex_); + isChanged_ = true; + cv_.notify_one(); + } + } + std::vector insert_; + std::vector update_; + std::vector delete_; + std::string deviceId_; + + private: + std::mutex mutex_; + std::condition_variable cv_; + bool isChanged_ = false; + }; + static void SetUpTestCase(void); static void TearDownTestCase(void); void SetUp(); @@ -189,4 +224,96 @@ HWTEST_F(SingleStoreImplTest, Transaction, TestSize.Level0) ASSERT_EQ(status, SUCCESS); status = kvStore_->Commit(); ASSERT_EQ(status, SUCCESS); + + status = kvStore_->StartTransaction(); + ASSERT_EQ(status, SUCCESS); + status = kvStore_->Rollback(); + ASSERT_EQ(status, SUCCESS); +} + +/** +* @tc.name: SubscribeKvStore +* @tc.desc: subscribe local +* @tc.type: FUNC +* @tc.require: I4XVQQ +* @tc.author: Sven Wang +*/ +HWTEST_F(SingleStoreImplTest, SubscribeKvStore, TestSize.Level0) +{ + ASSERT_NE(kvStore_, nullptr); + auto observer = std::make_shared(); + auto status = kvStore_->SubscribeKvStore(SUBSCRIBE_TYPE_LOCAL, observer); + ASSERT_EQ(status, SUCCESS); + status = kvStore_->SubscribeKvStore(SUBSCRIBE_TYPE_REMOTE, observer); + ASSERT_EQ(status, SUCCESS); + status = kvStore_->SubscribeKvStore(SUBSCRIBE_TYPE_LOCAL, observer); + ASSERT_EQ(status, STORE_ALREADY_SUBSCRIBE); + status = kvStore_->SubscribeKvStore(SUBSCRIBE_TYPE_REMOTE, observer); + ASSERT_EQ(status, STORE_ALREADY_SUBSCRIBE); + status = kvStore_->SubscribeKvStore(SUBSCRIBE_TYPE_ALL, observer); + ASSERT_EQ(status, STORE_ALREADY_SUBSCRIBE); + status = kvStore_->SubscribeKvStore(DEFAULT, observer); + ASSERT_EQ(status, STORE_ALREADY_SUBSCRIBE); + status = kvStore_->Put({ "Put Test" }, { "Put Value" }); + ASSERT_EQ(status, SUCCESS); + ASSERT_TRUE(observer->IsChanged()); + ASSERT_EQ(observer->insert_.size(), 1); + ASSERT_EQ(observer->update_.size(), 0); + ASSERT_EQ(observer->delete_.size(), 0); + status = kvStore_->Put({ "Put Test" }, { "Put Value1" }); + ASSERT_EQ(status, SUCCESS); + ASSERT_TRUE(observer->IsChanged()); + ASSERT_EQ(observer->insert_.size(), 0); + ASSERT_EQ(observer->update_.size(), 1); + ASSERT_EQ(observer->delete_.size(), 0); + status = kvStore_->Delete({ "Put Test" }); + ASSERT_EQ(status, SUCCESS); + ASSERT_TRUE(observer->IsChanged()); + ASSERT_EQ(observer->insert_.size(), 0); + ASSERT_EQ(observer->update_.size(), 0); + ASSERT_EQ(observer->delete_.size(), 1); +} + +/** +* @tc.name: UnsubscribeKvStore +* @tc.desc: unsubscribe +* @tc.type: FUNC +* @tc.require: I4XVQQ +* @tc.author: Sven Wang +*/ +HWTEST_F(SingleStoreImplTest, UnsubscribeKvStore, TestSize.Level0) +{ + ASSERT_NE(kvStore_, nullptr); + auto observer = std::make_shared(); + auto status = kvStore_->SubscribeKvStore(SUBSCRIBE_TYPE_ALL, observer); + ASSERT_EQ(status, SUCCESS); + status = kvStore_->UnSubscribeKvStore(SUBSCRIBE_TYPE_REMOTE, observer); + ASSERT_EQ(status, SUCCESS); + status = kvStore_->UnSubscribeKvStore(SUBSCRIBE_TYPE_REMOTE, observer); + ASSERT_EQ(status, STORE_NOT_SUBSCRIBE); + status = kvStore_->UnSubscribeKvStore(SUBSCRIBE_TYPE_LOCAL, observer); + ASSERT_EQ(status, SUCCESS); + status = kvStore_->UnSubscribeKvStore(SUBSCRIBE_TYPE_LOCAL, observer); + ASSERT_EQ(status, STORE_NOT_SUBSCRIBE); + status = kvStore_->UnSubscribeKvStore(SUBSCRIBE_TYPE_ALL, observer); + ASSERT_EQ(status, STORE_NOT_SUBSCRIBE); + status = kvStore_->SubscribeKvStore(SUBSCRIBE_TYPE_LOCAL, observer); + ASSERT_EQ(status, SUCCESS); + status = kvStore_->UnSubscribeKvStore(SUBSCRIBE_TYPE_ALL, observer); + ASSERT_EQ(status, SUCCESS); +} + +/** +* @tc.name: GetEntries +* @tc.desc: unsubscribe +* @tc.type: FUNC +* @tc.require: I4XVQQ +* @tc.author: Sven Wang +*/ +HWTEST_F(SingleStoreImplTest, GetEntries_Prefix, TestSize.Level0) +{ + ASSERT_NE(kvStore_, nullptr); + std::vector entries; + auto status = kvStore_->GetEntries({ "" }, entries); + ASSERT_EQ(status, SUCCESS); } \ No newline at end of file diff --git a/interfaces/innerkits/distributeddata/include/single_kvstore.h b/interfaces/innerkits/distributeddata/include/single_kvstore.h index 3f8a09447..661873a74 100644 --- a/interfaces/innerkits/distributeddata/include/single_kvstore.h +++ b/interfaces/innerkits/distributeddata/include/single_kvstore.h @@ -107,7 +107,7 @@ public: // allowedDelayMs: allowed delay milli-second to sync. // Return: // Status of this Sync operation. - virtual Status Sync(const std::vector &devices, SyncMode mode, uint32_t allowedDelayMs) = 0; + virtual Status Sync(const std::vector &devices, SyncMode mode, uint32_t delay) = 0; /* * Sync store with other devices only syncing the data which is satisfied with the condition. diff --git a/interfaces/innerkits/distributeddata/include/types.h b/interfaces/innerkits/distributeddata/include/types.h index 7d3c5a784..c6828bf18 100644 --- a/interfaces/innerkits/distributeddata/include/types.h +++ b/interfaces/innerkits/distributeddata/include/types.h @@ -112,7 +112,7 @@ struct AppThreadInfo { std::int32_t uid; }; -enum SubscribeType : int32_t { +enum SubscribeType : uint32_t { DEFAULT = 0, // default let bms delete SUBSCRIBE_TYPE_LOCAL = 1, // local changes of syncable kv store SUBSCRIBE_TYPE_REMOTE = 2, // synced data changes from remote devices diff --git a/services/distributeddataservice/app/distributed_data.cfg b/services/distributeddataservice/app/distributed_data.cfg index 80f178f30..61d23a0e2 100644 --- a/services/distributeddataservice/app/distributed_data.cfg +++ b/services/distributeddataservice/app/distributed_data.cfg @@ -37,7 +37,7 @@ "permission" : [ "ohos.permission.DISTRIBUTED_DATASYNC", "ohos.permission.MANAGE_LOCAL_ACCOUNTS" - ] + ] } ] } diff --git a/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp b/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp index 71a36845d..c5ffac9dc 100644 --- a/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp +++ b/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp @@ -49,7 +49,7 @@ Status KVDBServiceImpl::Delete(const AppId &appId, const StoreId &storeId, const return NOT_SUPPORT; } -Status KVDBServiceImpl::Sync(const AppId &appId, const StoreId &storeId, KVDBService::SyncInfo &syncInfo) +Status KVDBServiceImpl::Sync(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) { return NOT_SUPPORT; } @@ -105,12 +105,12 @@ Status KVDBServiceImpl::RmvSubscribeInfo( Status KVDBServiceImpl::Subscribe(const AppId &appId, const StoreId &storeId, sptr observer) { - return NOT_SUPPORT; + return SUCCESS; } Status KVDBServiceImpl::Unsubscribe(const AppId &appId, const StoreId &storeId, sptr observer) { - return NOT_SUPPORT; + return SUCCESS; } Status KVDBServiceImpl::BeforeCreate(const AppId &appId, const StoreId &storeId, const Options &options) diff --git a/services/distributeddataservice/service/kvdb/kvdb_service_impl.h b/services/distributeddataservice/service/kvdb/kvdb_service_impl.h index 8cb992dc2..e18b8f7a9 100644 --- a/services/distributeddataservice/service/kvdb/kvdb_service_impl.h +++ b/services/distributeddataservice/service/kvdb/kvdb_service_impl.h @@ -26,7 +26,7 @@ public: Status AfterCreate(const AppId &appId, const StoreId &storeId, const Options &options, const std::vector &password) override; Status Delete(const AppId &appId, const StoreId &storeId, const std::string &path) override; - Status Sync(const AppId &appId, const StoreId &storeId, SyncInfo &syncInfo) override; + Status Sync(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) override; Status RegisterSyncCallback( const AppId &appId, const StoreId &storeId, sptr callback) override; Status UnregisterSyncCallback(const AppId &appId, const StoreId &storeId) override; -- Gitee From 08745e1d4a164eb194c146bfbf886fa6f42ad039 Mon Sep 17 00:00:00 2001 From: Sven Wang Date: Wed, 1 Jun 2022 21:48:40 +0800 Subject: [PATCH 2/7] update Signed-off-by: Sven Wang --- frameworks/innerkitsimpl/kvdb/include/observer_bridge.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frameworks/innerkitsimpl/kvdb/include/observer_bridge.h b/frameworks/innerkitsimpl/kvdb/include/observer_bridge.h index d1510fdc5..584eca638 100644 --- a/frameworks/innerkitsimpl/kvdb/include/observer_bridge.h +++ b/frameworks/innerkitsimpl/kvdb/include/observer_bridge.h @@ -36,10 +36,10 @@ public: private: std::vector ConvertDB(const std::list &dbEntries, std::string &deviceId) const; - std::shared_ptr observer_; - sptr remote_; AppId appId_; StoreId storeId_; + std::shared_ptr observer_; + sptr remote_; Convert convert_; }; } // namespace OHOS::DistributedKv -- Gitee From 1972f8a399ebd0b28d98c3bef9bf3b227d2bf63e Mon Sep 17 00:00:00 2001 From: Sven Wang Date: Thu, 2 Jun 2022 16:58:18 +0800 Subject: [PATCH 3/7] add kv store test case and fixed the bugs Signed-off-by: Sven Wang --- .../distributeddatafwk/src/data_query.cpp | 1 + .../src/single_kvstore_client.cpp | 4 +- .../src/single_kvstore_client.h | 2 +- .../innerkitsimpl/kvdb/include/kvdb_service.h | 2 +- .../kvdb/include/kvdb_service_client.h | 8 +- .../kvdb/include/single_store_impl.h | 2 +- .../kvdb/include/store_factory.h | 2 + .../kvdb/include/store_manager.h | 32 +++ .../innerkitsimpl/kvdb/include/system_api.h | 34 +++ .../kvdb/src/kvdb_service_client.cpp | 39 +-- .../kvdb/src/observer_bridge.cpp | 13 +- .../kvdb/src/single_store_impl.cpp | 51 +++- .../innerkitsimpl/kvdb/src/store_factory.cpp | 6 + .../innerkitsimpl/kvdb/src/store_manager.cpp | 78 +++++ .../kvdb/src/store_result_set.cpp | 64 +++-- .../innerkitsimpl/kvdb/src/system_api.cpp | 108 +++++++ .../kvdb/test/single_store_impl_test.cpp | 271 +++++++++++++++++- interfaces/innerkits/distributeddata/BUILD.gn | 2 + .../include/kvstore_result_set.h | 2 + .../distributeddata/include/single_kvstore.h | 2 +- .../service/kvdb/kvdb_service_impl.cpp | 2 +- .../service/kvdb/kvdb_service_impl.h | 2 +- .../service/kvdb/kvdb_service_stub.cpp | 7 +- 23 files changed, 629 insertions(+), 105 deletions(-) create mode 100644 frameworks/innerkitsimpl/kvdb/include/store_manager.h create mode 100644 frameworks/innerkitsimpl/kvdb/include/system_api.h create mode 100644 frameworks/innerkitsimpl/kvdb/src/store_manager.cpp create mode 100644 frameworks/innerkitsimpl/kvdb/src/system_api.cpp diff --git a/frameworks/innerkitsimpl/distributeddatafwk/src/data_query.cpp b/frameworks/innerkitsimpl/distributeddatafwk/src/data_query.cpp index 6152fe61d..c6151fedc 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/src/data_query.cpp +++ b/frameworks/innerkitsimpl/distributeddatafwk/src/data_query.cpp @@ -70,6 +70,7 @@ DataQuery& DataQuery::Reset() inkeysFlag_ = false; deviceId_ = ""; prefix_ = ""; + query_ = std::make_shared(); return *this; } diff --git a/frameworks/innerkitsimpl/distributeddatafwk/src/single_kvstore_client.cpp b/frameworks/innerkitsimpl/distributeddatafwk/src/single_kvstore_client.cpp index 415d1cf98..cb82af432 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/src/single_kvstore_client.cpp +++ b/frameworks/innerkitsimpl/distributeddatafwk/src/single_kvstore_client.cpp @@ -455,10 +455,10 @@ Status SingleKvStoreClient::SetCapabilityRange(const std::vector &l return Status::SERVER_UNAVAILABLE; } -Status SingleKvStoreClient::GetSecurityLevel(SecurityLevel &securityLevel) const +Status SingleKvStoreClient::GetSecurityLevel(SecurityLevel &secLevel) const { if (kvStoreProxy_ != nullptr) { - return kvStoreProxy_->GetSecurityLevel(securityLevel); + return kvStoreProxy_->GetSecurityLevel(secLevel); } ZLOGE("singleKvstore proxy is nullptr."); return Status::SERVER_UNAVAILABLE; diff --git a/frameworks/innerkitsimpl/distributeddatafwk/src/single_kvstore_client.h b/frameworks/innerkitsimpl/distributeddatafwk/src/single_kvstore_client.h index 32957a2b6..a4d62ae78 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/src/single_kvstore_client.h +++ b/frameworks/innerkitsimpl/distributeddatafwk/src/single_kvstore_client.h @@ -81,7 +81,7 @@ public: Status SetCapabilityRange(const std::vector &localLabels, const std::vector &remoteLabels) const override; - Status GetSecurityLevel(SecurityLevel &securityLevel) const override; + Status GetSecurityLevel(SecurityLevel &secLevel) const override; Status Sync(const std::vector &devices, SyncMode mode, const DataQuery &query, std::shared_ptr syncCallback) override; diff --git a/frameworks/innerkitsimpl/kvdb/include/kvdb_service.h b/frameworks/innerkitsimpl/kvdb/include/kvdb_service.h index 8c00332e5..ab29e3be2 100644 --- a/frameworks/innerkitsimpl/kvdb/include/kvdb_service.h +++ b/frameworks/innerkitsimpl/kvdb/include/kvdb_service.h @@ -45,7 +45,7 @@ public: virtual Status BeforeCreate(const AppId &appId, const StoreId &storeId, const Options &options) = 0; virtual Status AfterCreate( const AppId &appId, const StoreId &storeId, const Options &options, const std::vector &password) = 0; - virtual Status Delete(const AppId &appId, const StoreId &storeId, const std::string &path) = 0; + virtual Status Delete(const AppId &appId, const StoreId &storeId) = 0; virtual Status Sync(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) = 0; virtual Status RegisterSyncCallback( const AppId &appId, const StoreId &storeId, sptr callback) = 0; diff --git a/frameworks/innerkitsimpl/kvdb/include/kvdb_service_client.h b/frameworks/innerkitsimpl/kvdb/include/kvdb_service_client.h index 615099a1b..674f5eef5 100644 --- a/frameworks/innerkitsimpl/kvdb/include/kvdb_service_client.h +++ b/frameworks/innerkitsimpl/kvdb/include/kvdb_service_client.h @@ -30,7 +30,7 @@ public: Status BeforeCreate(const AppId &appId, const StoreId &storeId, const Options &options) override; Status AfterCreate(const AppId &appId, const StoreId &storeId, const Options &options, const std::vector &password) override; - Status Delete(const AppId &appId, const StoreId &storeId, const std::string &path) override; + Status Delete(const AppId &appId, const StoreId &storeId) override; Status Sync(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) override; Status RegisterSyncCallback( const AppId &appId, const StoreId &storeId, sptr callback) override; @@ -48,12 +48,6 @@ public: Status Subscribe(const AppId &appId, const StoreId &storeId, sptr observer) override; Status Unsubscribe(const AppId &appId, const StoreId &storeId, sptr observer) override; - std::shared_ptr GetKVStore( - const AppId &appId, const StoreId &storeId, const Options &options, const std::string &path, Status &status); - Status CloseKVStore(const AppId &appId, const StoreId &storeId); - Status CloseKVStore(const AppId &appId, std::shared_ptr &kvStore); - Status CloseAllKVStore(const AppId &appId); - private: explicit KVDBServiceClient(const sptr &object); virtual ~KVDBServiceClient() = default; diff --git a/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h b/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h index f0e6c6f40..45fe2383c 100644 --- a/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h +++ b/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h @@ -51,7 +51,7 @@ public: Status GetResultSet(const DataQuery &query, std::shared_ptr &resultSet) const override; Status CloseResultSet(std::shared_ptr &resultSet) override; Status GetCount(const DataQuery &query, int &count) const override; - Status GetSecurityLevel(SecurityLevel &securityLevel) const override; + Status GetSecurityLevel(SecurityLevel &secLevel) const override; Status RemoveDeviceData(const std::string &device) override; Status Close(); diff --git a/frameworks/innerkitsimpl/kvdb/include/store_factory.h b/frameworks/innerkitsimpl/kvdb/include/store_factory.h index 64064d28f..0588fcfa1 100644 --- a/frameworks/innerkitsimpl/kvdb/include/store_factory.h +++ b/frameworks/innerkitsimpl/kvdb/include/store_factory.h @@ -36,6 +36,8 @@ private: using DBStore = DistributedDB::KvStoreNbDelegate; using DBPassword = DistributedDB::CipherPassword; + StoreFactory(); + std::shared_ptr GetDBManager(const std::string &path, const AppId &appId); DBOption GetDBOption(const Options &options, const DBPassword &password) const; ConcurrentMap> dbManagers_; diff --git a/frameworks/innerkitsimpl/kvdb/include/store_manager.h b/frameworks/innerkitsimpl/kvdb/include/store_manager.h new file mode 100644 index 000000000..5e90d3820 --- /dev/null +++ b/frameworks/innerkitsimpl/kvdb/include/store_manager.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_STORE_MANAGER_H +#define OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_STORE_MANAGER_H +#include "single_kvstore.h" +namespace OHOS::DistributedKv { +class StoreManager { +public: + static StoreManager &GetInstance(); + std::shared_ptr GetKVStore( + const AppId &appId, const StoreId &storeId, const Options &options, const std::string &path, Status &status); + Status CloseKVStore(const AppId &appId, const StoreId &storeId); + Status CloseKVStore(const AppId &appId, std::shared_ptr &kvStore); + Status CloseAllKVStore(const AppId &appId); + Status Delete(const AppId &appId, const StoreId &storeId, const std::string &path); +}; +} + +#endif // OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_STORE_MANAGER_H diff --git a/frameworks/innerkitsimpl/kvdb/include/system_api.h b/frameworks/innerkitsimpl/kvdb/include/system_api.h new file mode 100644 index 000000000..75e2b3fa0 --- /dev/null +++ b/frameworks/innerkitsimpl/kvdb/include/system_api.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_SYSTEM_API_H +#define OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_SYSTEM_API_H +#include "iprocess_system_api_adapter.h" +namespace OHOS::DistributedKv { +class SystemApi : public DistributedDB::IProcessSystemApiAdapter { +public: + using AccessEventHanle = DistributedDB::OnAccessControlledEvent; + using DBStatus = DistributedDB::DBStatus; + using DBOption = DistributedDB::SecurityOption; + SystemApi(); + ~SystemApi(); + DBStatus RegOnAccessControlledEvent(const AccessEventHanle &callback) override; + bool IsAccessControlled() const override; + DBStatus SetSecurityOption(const std::string &filePath, const DBOption &option) override; + DBStatus GetSecurityOption(const std::string &filePath, DBOption &option) const override; + bool CheckDeviceSecurityAbility(const std::string &devId, const DBOption &option) const override; +}; +} +#endif // OHOS_DISTRIBUTED_DATA_FRAMEWORKS_KVDB_SYSTEM_API_H diff --git a/frameworks/innerkitsimpl/kvdb/src/kvdb_service_client.cpp b/frameworks/innerkitsimpl/kvdb/src/kvdb_service_client.cpp index f8286e5bb..794eb1ead 100644 --- a/frameworks/innerkitsimpl/kvdb/src/kvdb_service_client.cpp +++ b/frameworks/innerkitsimpl/kvdb/src/kvdb_service_client.cpp @@ -129,15 +129,15 @@ Status KVDBServiceClient::AfterCreate( return static_cast(status); } -Status KVDBServiceClient::Delete(const AppId &appId, const StoreId &storeId, const std::string &path) +Status KVDBServiceClient::Delete(const AppId &appId, const StoreId &storeId) { MessageParcel reply; - int32_t status = IPC_SEND(TRANS_DELETE, reply, appId, storeId, path); + int32_t status = IPC_SEND(TRANS_DELETE, reply, appId, storeId); if (status != SUCCESS) { ZLOGE("status:0x%{public}x appId:%{public}s, storeId:%{public}s", status, appId.appId.c_str(), storeId.storeId.c_str()); } - return StoreFactory::GetInstance().Delete(appId, storeId, path); + return static_cast(status); } Status KVDBServiceClient::Sync(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) @@ -278,37 +278,4 @@ Status KVDBServiceClient::Unsubscribe(const AppId &appId, const StoreId &storeId } return static_cast(status); } - -std::shared_ptr KVDBServiceClient::GetKVStore( - const AppId &appId, const StoreId &storeId, const Options &options, const std::string &path, Status &status) -{ - bool isExits = StoreFactory::GetInstance().IsExits(appId, storeId); - if (isExits) { - return StoreFactory::GetInstance().Create(appId, storeId, options, path, status); - } - BeforeCreate(appId, storeId, options); - auto kvStore = StoreFactory::GetInstance().Create(appId, storeId, options, path, status); - auto password = SecurityManager::GetInstance().GetDBPassword(appId, storeId, path); - std::vector pwd(password.GetData(), password.GetData() + password.GetSize()); - AfterCreate(appId, storeId, options, pwd); - pwd.assign(pwd.size(), 0); - return kvStore; -} - -Status KVDBServiceClient::CloseKVStore(const AppId &appId, const StoreId &storeId) -{ - return StoreFactory::GetInstance().Close(appId, storeId); -} - -Status KVDBServiceClient::CloseKVStore(const AppId &appId, std::shared_ptr &kvStore) -{ - auto status = StoreFactory::GetInstance().Close(appId, { kvStore->GetStoreId() }); - kvStore = nullptr; - return status; -} - -Status KVDBServiceClient::CloseAllKVStore(const AppId &appId) -{ - return StoreFactory::GetInstance().Close(appId, { "" }); -} } // namespace OHOS::DistributedKv \ No newline at end of file diff --git a/frameworks/innerkitsimpl/kvdb/src/observer_bridge.cpp b/frameworks/innerkitsimpl/kvdb/src/observer_bridge.cpp index 34ce0d076..263c7da13 100644 --- a/frameworks/innerkitsimpl/kvdb/src/observer_bridge.cpp +++ b/frameworks/innerkitsimpl/kvdb/src/observer_bridge.cpp @@ -35,8 +35,13 @@ Status ObserverBridge::RegisterRemoteObserver() return SUCCESS; } + auto service = KVDBServiceClient::GetInstance(); + if (service == nullptr) { + return SERVER_UNAVAILABLE; + } + remote_ = new (std::nothrow) KvStoreObserverClient(observer_); - return KVDBServiceClient::GetInstance()->Subscribe(appId_, storeId_, remote_); + return service->Subscribe(appId_, storeId_, remote_); } Status ObserverBridge::UnregisterRemoteObserver() @@ -44,8 +49,12 @@ Status ObserverBridge::UnregisterRemoteObserver() if (remote_ == nullptr) { return SUCCESS; } + auto service = KVDBServiceClient::GetInstance(); + if (service == nullptr) { + return SERVER_UNAVAILABLE; + } - auto status = KVDBServiceClient::GetInstance()->Unsubscribe(appId_, storeId_, remote_); + auto status = service->Unsubscribe(appId_, storeId_, remote_); remote_ = nullptr; return status; } diff --git a/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp b/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp index d55b43ba1..b8eedb6ce 100644 --- a/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp +++ b/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp @@ -411,7 +411,7 @@ Status SingleStoreImpl::GetCount(const DataQuery &query, int &result) const return status; } -Status SingleStoreImpl::GetSecurityLevel(SecurityLevel &securityLevel) const +Status SingleStoreImpl::GetSecurityLevel(SecurityLevel &secLevel) const { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); std::shared_lock lock(rwMutex_); @@ -422,6 +422,7 @@ Status SingleStoreImpl::GetSecurityLevel(SecurityLevel &securityLevel) const DistributedDB::SecurityOption option; auto dbStatus = dbStore_->GetSecurityOption(option); + secLevel = static_cast(StoreUtil::GetSecLevel(option)); auto status = StoreUtil::ConvertStatus(dbStatus); if (status != SUCCESS) { ZLOGE("status:0x%{public}x, security:[%{public}d, %{public}d]", status, option.securityFlag, @@ -490,55 +491,79 @@ Status SingleStoreImpl::UnRegisterSyncCallback() Status SingleStoreImpl::SetSyncParam(const KvSyncParam &syncParam) { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__), true); - return KVDBServiceClient::GetInstance()->SetSyncParam({ appId_ }, { storeId_ }, syncParam); + auto service = KVDBServiceClient::GetInstance(); + if (service == nullptr) { + return SERVER_UNAVAILABLE; + } + return service->SetSyncParam({ appId_ }, { storeId_ }, syncParam); } Status SingleStoreImpl::GetSyncParam(KvSyncParam &syncParam) { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__), true); - return KVDBServiceClient::GetInstance()->GetSyncParam({ appId_ }, { storeId_ }, syncParam); + auto service = KVDBServiceClient::GetInstance(); + if (service == nullptr) { + return SERVER_UNAVAILABLE; + } + return service->GetSyncParam({ appId_ }, { storeId_ }, syncParam); } Status SingleStoreImpl::SetCapabilityEnabled(bool enabled) const { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__), true); + auto service = KVDBServiceClient::GetInstance(); + if (service == nullptr) { + return SERVER_UNAVAILABLE; + } if (enabled) { - return KVDBServiceClient::GetInstance()->EnableCapability({ appId_ }, { storeId_ }); + return service->EnableCapability({ appId_ }, { storeId_ }); } - return KVDBServiceClient::GetInstance()->DisableCapability({ appId_ }, { storeId_ }); + return service->DisableCapability({ appId_ }, { storeId_ }); } Status SingleStoreImpl::SetCapabilityRange( const std::vector &localLabels, const std::vector &remoteLabels) const { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__), true); - return KVDBServiceClient::GetInstance()->SetCapability({ appId_ }, { storeId_ }, localLabels, remoteLabels); + auto service = KVDBServiceClient::GetInstance(); + if (service == nullptr) { + return SERVER_UNAVAILABLE; + } + return service->SetCapability({ appId_ }, { storeId_ }, localLabels, remoteLabels); } Status SingleStoreImpl::SubscribeWithQuery(const std::vector &devices, const DataQuery &query) { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__), true); - return KVDBServiceClient::GetInstance()->AddSubscribeInfo({ appId_ }, { storeId_ }, devices, query.ToString()); + auto service = KVDBServiceClient::GetInstance(); + if (service == nullptr) { + return SERVER_UNAVAILABLE; + } + return service->AddSubscribeInfo({ appId_ }, { storeId_ }, devices, query.ToString()); } Status SingleStoreImpl::UnsubscribeWithQuery(const std::vector &devices, const DataQuery &query) { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__), true); - return KVDBServiceClient::GetInstance()->RmvSubscribeInfo({ appId_ }, { storeId_ }, devices, query.ToString()); + auto service = KVDBServiceClient::GetInstance(); + if (service == nullptr) { + return SERVER_UNAVAILABLE; + } + return service->RmvSubscribeInfo({ appId_ }, { storeId_ }, devices, query.ToString()); } Status SingleStoreImpl::Close() { observers_.Clear(); syncObserver_->Clean(); - bool isFirstClose; + std::shared_ptr service; { std::lock_guard lock(mutex_); - isFirstClose = syncCallback_ != nullptr; + service = (syncCallback_ != nullptr) ? KVDBServiceClient::GetInstance() : nullptr; syncCallback_ = nullptr; } - if (isFirstClose) { - KVDBServiceClient::GetInstance()->UnregisterSyncCallback({ appId_ }, { storeId_ }); + if (service != nullptr) { + service->UnregisterSyncCallback({ appId_ }, { storeId_ }); } std::unique_lock lock(rwMutex_); dbStore_ = nullptr; @@ -617,7 +642,7 @@ Status SingleStoreImpl::GetEntries(const DistributedDB::Query &query, std::vecto entries.resize(dbEntries.size()); auto it = entries.begin(); for (auto &dbEntry : dbEntries) { - auto &entry = *it; + auto &entry = *it++; entry.key = ConvertKey(std::move(dbEntry.key)); entry.value = std::move(dbEntry.value); } diff --git a/frameworks/innerkitsimpl/kvdb/src/store_factory.cpp b/frameworks/innerkitsimpl/kvdb/src/store_factory.cpp index b9ca11102..2cd4f3d33 100644 --- a/frameworks/innerkitsimpl/kvdb/src/store_factory.cpp +++ b/frameworks/innerkitsimpl/kvdb/src/store_factory.cpp @@ -19,6 +19,7 @@ #include "security_manager.h" #include "single_store_impl.h" #include "store_util.h" +#include "system_api.h" namespace OHOS::DistributedKv { using namespace DistributedDB; StoreFactory &StoreFactory::GetInstance() @@ -27,6 +28,11 @@ StoreFactory &StoreFactory::GetInstance() return instance; } +StoreFactory::StoreFactory() +{ + (void)DBManager::SetProcessSystemAPIAdapter(std::make_shared()); +} + std::shared_ptr StoreFactory::Create( const AppId &appId, const StoreId &storeId, const Options &options, const std::string &path, Status &status) { diff --git a/frameworks/innerkitsimpl/kvdb/src/store_manager.cpp b/frameworks/innerkitsimpl/kvdb/src/store_manager.cpp new file mode 100644 index 000000000..77cb2cbdf --- /dev/null +++ b/frameworks/innerkitsimpl/kvdb/src/store_manager.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "store_manager.h" + +#include "kvdb_service_client.h" +#include "security_manager.h" +#include "store_factory.h" +namespace OHOS::DistributedKv { +StoreManager &StoreManager::GetInstance() +{ + static StoreManager instance; + return instance; +} + +std::shared_ptr StoreManager::GetKVStore( + const AppId &appId, const StoreId &storeId, const Options &options, const std::string &path, Status &status) +{ + if (StoreFactory::GetInstance().IsExits(appId, storeId)) { + return StoreFactory::GetInstance().Create(appId, storeId, options, path, status); + } + + auto service = KVDBServiceClient::GetInstance(); + if (service != nullptr) { + service->BeforeCreate(appId, storeId, options); + } + auto kvStore = StoreFactory::GetInstance().Create(appId, storeId, options, path, status); + auto password = SecurityManager::GetInstance().GetDBPassword(appId, storeId, path); + std::vector pwd(password.GetData(), password.GetData() + password.GetSize()); + if (service != nullptr) { + // delay notify + service->AfterCreate(appId, storeId, options, pwd); + } + pwd.assign(pwd.size(), 0); + return kvStore; +} + +Status StoreManager::CloseKVStore(const AppId &appId, const StoreId &storeId) +{ + return StoreFactory::GetInstance().Close(appId, storeId); +} + +Status StoreManager::CloseKVStore(const AppId &appId, std::shared_ptr &kvStore) +{ + if (kvStore == nullptr) { + return INVALID_ARGUMENT; + } + StoreId storeId{ kvStore->GetStoreId() }; + kvStore = nullptr; + return StoreFactory::GetInstance().Close(appId, storeId); +} + +Status StoreManager::CloseAllKVStore(const AppId &appId) +{ + return StoreFactory::GetInstance().Close(appId, { "" }); +} + +Status StoreManager::Delete(const AppId &appId, const StoreId &storeId, const std::string &path) +{ + auto service = KVDBServiceClient::GetInstance(); + if (service != nullptr) { + service->Delete(appId, storeId); + } + return StoreFactory::GetInstance().Delete(appId, storeId, path); +} +} // namespace OHOS::DistributedKv \ No newline at end of file diff --git a/frameworks/innerkitsimpl/kvdb/src/store_result_set.cpp b/frameworks/innerkitsimpl/kvdb/src/store_result_set.cpp index fc8a17bb2..105e3d80a 100644 --- a/frameworks/innerkitsimpl/kvdb/src/store_result_set.cpp +++ b/frameworks/innerkitsimpl/kvdb/src/store_result_set.cpp @@ -34,129 +34,142 @@ StoreResultSet::~StoreResultSet() int StoreResultSet::GetCount() const { - DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); std::shared_lock lock(mutex_); if (impl_ == nullptr) { - return ALREADY_CLOSED; + ZLOGW("already closed"); + return INVALID_COUNT; } + return impl_->GetCount(); } int StoreResultSet::GetPosition() const { - DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); std::shared_lock lock(mutex_); if (impl_ == nullptr) { - return ALREADY_CLOSED; + ZLOGW("already closed"); + return INVALID_POSITION; } + return impl_->GetPosition(); } bool StoreResultSet::MoveToFirst() { - DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); std::shared_lock lock(mutex_); if (impl_ == nullptr) { - return ALREADY_CLOSED; + ZLOGW("already closed"); + return false; } + return impl_->MoveToFirst(); } bool StoreResultSet::MoveToLast() { - DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); std::shared_lock lock(mutex_); if (impl_ == nullptr) { - return ALREADY_CLOSED; + ZLOGW("already closed"); + return false; } + return impl_->MoveToLast(); } bool StoreResultSet::MoveToNext() { - DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); std::shared_lock lock(mutex_); if (impl_ == nullptr) { - return ALREADY_CLOSED; + ZLOGW("already closed"); + return false; } + return impl_->MoveToNext(); } bool StoreResultSet::MoveToPrevious() { - DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); std::shared_lock lock(mutex_); if (impl_ == nullptr) { - return ALREADY_CLOSED; + ZLOGW("already closed"); + return false; } + return impl_->MoveToPrevious(); } bool StoreResultSet::Move(int offset) { - DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); std::shared_lock lock(mutex_); if (impl_ == nullptr) { - return ALREADY_CLOSED; + ZLOGW("already closed"); + return false; } + return impl_->Move(offset); } bool StoreResultSet::MoveToPosition(int position) { - DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); std::shared_lock lock(mutex_); if (impl_ == nullptr) { - return ALREADY_CLOSED; + ZLOGW("already closed"); + return false; } + return impl_->MoveToPosition(position); } bool StoreResultSet::IsFirst() const { - DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); std::shared_lock lock(mutex_); if (impl_ == nullptr) { - return ALREADY_CLOSED; + ZLOGW("already closed"); + return false; } + return impl_->IsFirst(); } bool StoreResultSet::IsLast() const { - DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); std::shared_lock lock(mutex_); if (impl_ == nullptr) { - return ALREADY_CLOSED; + ZLOGW("already closed"); + return false; } + return impl_->IsLast(); } bool StoreResultSet::IsBeforeFirst() const { - DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); std::shared_lock lock(mutex_); if (impl_ == nullptr) { - return ALREADY_CLOSED; + ZLOGW("already closed"); + return false; } + return impl_->IsBeforeFirst(); } bool StoreResultSet::IsAfterLast() const { - DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); std::shared_lock lock(mutex_); if (impl_ == nullptr) { - return ALREADY_CLOSED; + ZLOGW("already closed"); + return false; } + return impl_->IsAfterLast(); } Status StoreResultSet::GetEntry(Entry &entry) const { - DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); std::shared_lock lock(mutex_); if (impl_ == nullptr) { + ZLOGW("already closed"); return ALREADY_CLOSED; } + DistributedDB::Entry dbEntry; auto dbStatus = impl_->GetEntry(dbEntry); auto status = StoreUtil::ConvertStatus(dbStatus); @@ -171,7 +184,6 @@ Status StoreResultSet::GetEntry(Entry &entry) const Status StoreResultSet::Close() { - DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); std::unique_lock lock(mutex_); if (impl_ == nullptr || dbStore_ == nullptr) { return SUCCESS; diff --git a/frameworks/innerkitsimpl/kvdb/src/system_api.cpp b/frameworks/innerkitsimpl/kvdb/src/system_api.cpp new file mode 100644 index 000000000..e6d95db72 --- /dev/null +++ b/frameworks/innerkitsimpl/kvdb/src/system_api.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define LOG_TAG "SystemApi" +#include "system_api.h" + +#include +#include +#include +#include "log_print.h" +#include "security_label.h" +#include "store_util.h" +namespace OHOS::DistributedKv { +using Label = DistributedDB::SecurityLabel; +using Flag = DistributedDB::SecurityFlag; +using SecurityLabel = DistributedFS::ModuleSecurityLabel::SecurityLabel; +SystemApi::SystemApi() +{ +} + +SystemApi::~SystemApi() +{ +} + +SystemApi::DBStatus SystemApi::RegOnAccessControlledEvent(const AccessEventHanle &callback) +{ + return DBStatus::NOT_SUPPORT; +} + +bool SystemApi::IsAccessControlled() const +{ + return false; +} + +SystemApi::DBStatus SystemApi::SetSecurityOption(const std::string &filePath, const DBOption &option) +{ + if (filePath.empty() || Label::NOT_SET < option.securityLabel || option.securityLabel > Label::S4) { + return DBStatus::INVALID_ARGS; + } + + struct stat curStat; + stat(filePath.c_str(), &curStat); + if (S_ISDIR(curStat.st_mode)) { + return DBStatus::NOT_SUPPORT; + } + + if (access(filePath.c_str(), F_OK) != 0) { + return DBStatus::INVALID_ARGS; + } + + if (option.securityLabel == Label::NOT_SET) { + return DBStatus::OK; + } + + auto secLevel = std::string("s") + std::to_string(option.securityLabel - 1); + bool result = SecurityLabel::SetSecurityLabel(filePath, secLevel); + if (!result) { + ZLOGE("set label failed! level:%{public}s, file:%{public}s", secLevel.c_str(), + StoreUtil::Anonymous(filePath).c_str()); + return DBStatus::DB_ERROR; + } + + return DBStatus::OK; + +} + +SystemApi::DBStatus SystemApi::GetSecurityOption(const std::string &filePath, DBOption &option) const +{ + if (filePath.empty()) { + return DBStatus::INVALID_ARGS; + } + + struct stat curStat; + stat(filePath.c_str(), &curStat); + if (S_ISDIR(curStat.st_mode)) { + return DBStatus::NOT_SUPPORT; + } + + if (access(filePath.c_str(), F_OK) != 0) { + option = {Label::NOT_SET, Flag::ECE}; + return DBStatus::OK; + } + + std::string value = SecurityLabel::GetSecurityLabel(filePath); + if (!std::regex_match(value, std::regex("s([01234])"))) { + option = {Label::NOT_SET, Flag::ECE}; + return DBStatus::OK; + } + option = { (value[1] - '0') + 1, value[1] == '3' ? Flag::SECE : Flag::ECE}; + return DBStatus::OK; +} + +bool SystemApi::CheckDeviceSecurityAbility(const std::string &devId, const DBOption &option) const +{ + return false; +} +} // namespace OHOS::DistributedKv \ No newline at end of file diff --git a/frameworks/innerkitsimpl/kvdb/test/single_store_impl_test.cpp b/frameworks/innerkitsimpl/kvdb/test/single_store_impl_test.cpp index 609f95b4a..d95b57f26 100644 --- a/frameworks/innerkitsimpl/kvdb/test/single_store_impl_test.cpp +++ b/frameworks/innerkitsimpl/kvdb/test/single_store_impl_test.cpp @@ -17,7 +17,8 @@ #include #include -#include "kvdb_service_client.h" +#include "dev_manager.h" +#include "store_manager.h" #include "types.h" using namespace testing::ext; using namespace OHOS::DistributedKv; @@ -83,8 +84,8 @@ void SingleStoreImplTest::SetUp(void) AppId appId = { "LocalSingleKVStore" }; StoreId storeId = { "LocalSingleKVStore" }; std::string path = ""; - Status status = KVDBServiceClient::GetInstance()->Delete(appId, storeId, path); - kvStore_ = KVDBServiceClient::GetInstance()->GetKVStore(appId, storeId, options, path, status); + Status status = StoreManager::GetInstance().Delete(appId, storeId, path); + kvStore_ = StoreManager::GetInstance().GetKVStore(appId, storeId, options, path, status); ASSERT_EQ(status, SUCCESS); } @@ -93,7 +94,7 @@ void SingleStoreImplTest::TearDown(void) AppId appId = { "LocalSingleKVStore" }; StoreId storeId = { "LocalSingleKVStore" }; std::string path = ""; - Status status = KVDBServiceClient::GetInstance()->Delete(appId, storeId, path); + Status status = StoreManager::GetInstance().Delete(appId, storeId, path); ASSERT_EQ(status, SUCCESS); } @@ -305,7 +306,7 @@ HWTEST_F(SingleStoreImplTest, UnsubscribeKvStore, TestSize.Level0) /** * @tc.name: GetEntries -* @tc.desc: unsubscribe +* @tc.desc: get entries by prefix * @tc.type: FUNC * @tc.require: I4XVQQ * @tc.author: Sven Wang @@ -313,7 +314,263 @@ HWTEST_F(SingleStoreImplTest, UnsubscribeKvStore, TestSize.Level0) HWTEST_F(SingleStoreImplTest, GetEntries_Prefix, TestSize.Level0) { ASSERT_NE(kvStore_, nullptr); - std::vector entries; - auto status = kvStore_->GetEntries({ "" }, entries); + std::vector input; + for (int i = 0; i < 10; ++i) { + Entry entry; + entry.key = std::to_string(i).append("_k"); + entry.value = std::to_string(i).append("_v"); + input.push_back(entry); + } + auto status = kvStore_->PutBatch(input); + ASSERT_EQ(status, SUCCESS); + std::vector output; + status = kvStore_->GetEntries({ "" }, output); + ASSERT_EQ(status, SUCCESS); + std::sort(output.begin(), output.end(), + [](const Entry &entry, const Entry &sentry) { return entry.key.Data() < sentry.key.Data(); }); + for (int i = 0; i < 10; ++i) { + ASSERT_TRUE(input[i].key == output[i].key); + ASSERT_TRUE(input[i].value == output[i].value); + } +} + +/** +* @tc.name: GetEntries +* @tc.desc: get entries by query +* @tc.type: FUNC +* @tc.require: I4XVQQ +* @tc.author: Sven Wang +*/ +HWTEST_F(SingleStoreImplTest, GetEntries_DataQuery, TestSize.Level0) +{ + ASSERT_NE(kvStore_, nullptr); + std::vector input; + for (int i = 0; i < 10; ++i) { + Entry entry; + entry.key = std::to_string(i).append("_k"); + entry.value = std::to_string(i).append("_v"); + input.push_back(entry); + } + auto status = kvStore_->PutBatch(input); + ASSERT_EQ(status, SUCCESS); + DataQuery query; + query.InKeys({"0_k", "1_k"}); + std::vector output; + status = kvStore_->GetEntries(query, output); + ASSERT_EQ(status, SUCCESS); + std::sort(output.begin(), output.end(), + [](const Entry &entry, const Entry &sentry) { return entry.key.Data() < sentry.key.Data(); }); + ASSERT_LE(output.size(), 2); + for (size_t i = 0; i < output.size(); ++i) { + ASSERT_TRUE(input[i].key == output[i].key); + ASSERT_TRUE(input[i].value == output[i].value); + } +} + +/** +* @tc.name: GetResultSet +* @tc.desc: get result set by prefix +* @tc.type: FUNC +* @tc.require: I4XVQQ +* @tc.author: Sven Wang +*/ +HWTEST_F(SingleStoreImplTest, GetResultSet_Prefix, TestSize.Level0) +{ + ASSERT_NE(kvStore_, nullptr); + std::vector input; + auto cmp = [](const Key &entry, const Key &sentry) { return entry.Data() < sentry.Data(); }; + std::map dictionary(cmp); + for (int i = 0; i < 10; ++i) { + Entry entry; + entry.key = std::to_string(i).append("_k"); + entry.value = std::to_string(i).append("_v"); + dictionary[entry.key] = entry.value; + input.push_back(entry); + } + auto status = kvStore_->PutBatch(input); + ASSERT_EQ(status, SUCCESS); + std::shared_ptr output; + status = kvStore_->GetResultSet({ "" }, output); + ASSERT_EQ(status, SUCCESS); + ASSERT_NE(output, nullptr); + ASSERT_EQ(output->GetCount(), 10); + int count = 0; + while (output->MoveToNext()) { + count++; + Entry entry; + output->GetEntry(entry); + ASSERT_EQ(entry.value.Data(), dictionary[entry.key].Data()); + } + ASSERT_EQ(count, output->GetCount()); +} + +/** +* @tc.name: GetResultSet +* @tc.desc: get result set by query +* @tc.type: FUNC +* @tc.require: I4XVQQ +* @tc.author: Sven Wang +*/ +HWTEST_F(SingleStoreImplTest, GetResultSet_Query, TestSize.Level0) +{ + ASSERT_NE(kvStore_, nullptr); + std::vector input; + auto cmp = [](const Key &entry, const Key &sentry) { return entry.Data() < sentry.Data(); }; + std::map dictionary(cmp); + for (int i = 0; i < 10; ++i) { + Entry entry; + entry.key = std::to_string(i).append("_k"); + entry.value = std::to_string(i).append("_v"); + dictionary[entry.key] = entry.value; + input.push_back(entry); + } + auto status = kvStore_->PutBatch(input); + ASSERT_EQ(status, SUCCESS); + DataQuery query; + query.InKeys({"0_k", "1_k"}); + std::shared_ptr output; + status = kvStore_->GetResultSet(query, output); + ASSERT_EQ(status, SUCCESS); + ASSERT_NE(output, nullptr); + ASSERT_LE(output->GetCount(), 2); + int count = 0; + while (output->MoveToNext()) { + count++; + Entry entry; + output->GetEntry(entry); + ASSERT_EQ(entry.value.Data(), dictionary[entry.key].Data()); + } + ASSERT_EQ(count, output->GetCount()); +} + +/** +* @tc.name: CloseResultSet +* @tc.desc: close the result set +* @tc.type: FUNC +* @tc.require: I4XVQQ +* @tc.author: Sven Wang +*/ +HWTEST_F(SingleStoreImplTest, CloseResultSet, TestSize.Level0) +{ + ASSERT_NE(kvStore_, nullptr); + std::vector input; + auto cmp = [](const Key &entry, const Key &sentry) { return entry.Data() < sentry.Data(); }; + std::map dictionary(cmp); + for (int i = 0; i < 10; ++i) { + Entry entry; + entry.key = std::to_string(i).append("_k"); + entry.value = std::to_string(i).append("_v"); + dictionary[entry.key] = entry.value; + input.push_back(entry); + } + auto status = kvStore_->PutBatch(input); + ASSERT_EQ(status, SUCCESS); + DataQuery query; + query.InKeys({"0_k", "1_k"}); + std::shared_ptr output; + status = kvStore_->GetResultSet(query, output); + ASSERT_EQ(status, SUCCESS); + ASSERT_NE(output, nullptr); + ASSERT_LE(output->GetCount(), 2); + auto outputTmp = output; + status = kvStore_->CloseResultSet(output); + ASSERT_EQ(status, SUCCESS); + ASSERT_EQ(output, nullptr); + ASSERT_EQ(outputTmp->GetCount(), KvStoreResultSet::INVALID_COUNT); + ASSERT_EQ(outputTmp->GetPosition(), KvStoreResultSet::INVALID_POSITION); + ASSERT_EQ(outputTmp->MoveToFirst(), false); + ASSERT_EQ(outputTmp->MoveToLast(), false); + ASSERT_EQ(outputTmp->MoveToNext(), false); + ASSERT_EQ(outputTmp->MoveToPrevious(), false); + ASSERT_EQ(outputTmp->Move(1), false); + ASSERT_EQ(outputTmp->MoveToPosition(1), false); + ASSERT_EQ(outputTmp->IsFirst(), false); + ASSERT_EQ(outputTmp->IsLast(), false); + ASSERT_EQ(outputTmp->IsBeforeFirst(), false); + ASSERT_EQ(outputTmp->IsAfterLast(), false); + Entry entry; + ASSERT_EQ(outputTmp->GetEntry(entry), ALREADY_CLOSED); +} + +/** +* @tc.name: GetCount +* @tc.desc: close the result set +* @tc.type: FUNC +* @tc.require: I4XVQQ +* @tc.author: Sven Wang +*/ +HWTEST_F(SingleStoreImplTest, GetCount, TestSize.Level0) +{ + ASSERT_NE(kvStore_, nullptr); + std::vector input; + auto cmp = [](const Key &entry, const Key &sentry) { return entry.Data() < sentry.Data(); }; + std::map dictionary(cmp); + for (int i = 0; i < 10; ++i) { + Entry entry; + entry.key = std::to_string(i).append("_k"); + entry.value = std::to_string(i).append("_v"); + dictionary[entry.key] = entry.value; + input.push_back(entry); + } + auto status = kvStore_->PutBatch(input); + ASSERT_EQ(status, SUCCESS); + DataQuery query; + query.InKeys({"0_k", "1_k"}); + int count = 0; + status = kvStore_->GetCount(query, count); + ASSERT_EQ(status, SUCCESS); + ASSERT_EQ(count, 2); + query.Reset(); + status = kvStore_->GetCount(query, count); + ASSERT_EQ(status, SUCCESS); + ASSERT_EQ(count, 10); +} + +/** +* @tc.name: RemoveDeviceData +* @tc.desc: remove local device data +* @tc.type: FUNC +* @tc.require: I4XVQQ +* @tc.author: Sven Wang +*/ +HWTEST_F(SingleStoreImplTest, RemoveDeviceData, TestSize.Level0) +{ + ASSERT_NE(kvStore_, nullptr); + std::vector input; + auto cmp = [](const Key &entry, const Key &sentry) { return entry.Data() < sentry.Data(); }; + std::map dictionary(cmp); + for (int i = 0; i < 10; ++i) { + Entry entry; + entry.key = std::to_string(i).append("_k"); + entry.value = std::to_string(i).append("_v"); + dictionary[entry.key] = entry.value; + input.push_back(entry); + } + auto status = kvStore_->PutBatch(input); + ASSERT_EQ(status, SUCCESS); + int count = 0; + status = kvStore_->GetCount({}, count); + ASSERT_EQ(status, SUCCESS); + ASSERT_EQ(count, 10); + status = kvStore_->RemoveDeviceData(DevManager::GetInstance().GetLocalDevice().deviceId); + ASSERT_EQ(status, SUCCESS); + status = kvStore_->GetCount({}, count); + ASSERT_EQ(status, SUCCESS); + ASSERT_EQ(count, 0); +} + +/** +* @tc.name: RemoveDeviceData +* @tc.desc: remove local device data +* @tc.type: FUNC +* @tc.require: I4XVQQ +* @tc.author: Sven Wang +*/ +HWTEST_F(SingleStoreImplTest, GetSecurityLevel, TestSize.Level0) +{ + ASSERT_NE(kvStore_, nullptr); + SecurityLevel securityLevel = NO_LABEL; + auto status = kvStore_->GetSecurityLevel(securityLevel); ASSERT_EQ(status, SUCCESS); + ASSERT_EQ(securityLevel, S1); } \ No newline at end of file diff --git a/interfaces/innerkits/distributeddata/BUILD.gn b/interfaces/innerkits/distributeddata/BUILD.gn index c915974ce..73482027d 100644 --- a/interfaces/innerkits/distributeddata/BUILD.gn +++ b/interfaces/innerkits/distributeddata/BUILD.gn @@ -96,8 +96,10 @@ ohos_shared_library("distributeddata_inner") { "../../../frameworks/innerkitsimpl/kvdb/src/security_manager.cpp", "../../../frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp", "../../../frameworks/innerkitsimpl/kvdb/src/store_factory.cpp", + "../../../frameworks/innerkitsimpl/kvdb/src/store_manager.cpp", "../../../frameworks/innerkitsimpl/kvdb/src/store_result_set.cpp", "../../../frameworks/innerkitsimpl/kvdb/src/store_util.cpp", + "../../../frameworks/innerkitsimpl/kvdb/src/system_api.cpp", ] sources = old_sources + rdb_sources + kvdb_sources + object_sources diff --git a/interfaces/innerkits/distributeddata/include/kvstore_result_set.h b/interfaces/innerkits/distributeddata/include/kvstore_result_set.h index 3ecd8fdcc..25c526b7b 100644 --- a/interfaces/innerkits/distributeddata/include/kvstore_result_set.h +++ b/interfaces/innerkits/distributeddata/include/kvstore_result_set.h @@ -22,6 +22,8 @@ namespace OHOS { namespace DistributedKv { class KvStoreResultSet { public: + inline static constexpr int INVALID_COUNT = -ALREADY_CLOSED; + inline static constexpr int INVALID_POSITION = -ALREADY_CLOSED; API_EXPORT virtual ~KvStoreResultSet() {} // Returns the count of rows in the result set. diff --git a/interfaces/innerkits/distributeddata/include/single_kvstore.h b/interfaces/innerkits/distributeddata/include/single_kvstore.h index 661873a74..6d403a4d2 100644 --- a/interfaces/innerkits/distributeddata/include/single_kvstore.h +++ b/interfaces/innerkits/distributeddata/include/single_kvstore.h @@ -96,7 +96,7 @@ public: // Status of this remove operation. virtual Status RemoveDeviceData(const std::string &device) = 0; - virtual Status GetSecurityLevel(SecurityLevel &securityLevel) const = 0; + virtual Status GetSecurityLevel(SecurityLevel &secLevel) const = 0; // Sync store with other devices. This is an asynchronous method, // sync will fail if there is a syncing operation in progress. diff --git a/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp b/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp index c5ffac9dc..d63d9eba0 100644 --- a/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp +++ b/services/distributeddataservice/service/kvdb/kvdb_service_impl.cpp @@ -44,7 +44,7 @@ Status KVDBServiceImpl::GetStoreIds(const AppId &appId, std::vector &st return SUCCESS; } -Status KVDBServiceImpl::Delete(const AppId &appId, const StoreId &storeId, const std::string &path) +Status KVDBServiceImpl::Delete(const AppId &appId, const StoreId &storeId) { return NOT_SUPPORT; } diff --git a/services/distributeddataservice/service/kvdb/kvdb_service_impl.h b/services/distributeddataservice/service/kvdb/kvdb_service_impl.h index e18b8f7a9..8c13705ce 100644 --- a/services/distributeddataservice/service/kvdb/kvdb_service_impl.h +++ b/services/distributeddataservice/service/kvdb/kvdb_service_impl.h @@ -25,7 +25,7 @@ public: Status BeforeCreate(const AppId &appId, const StoreId &storeId, const Options &options) override; Status AfterCreate(const AppId &appId, const StoreId &storeId, const Options &options, const std::vector &password) override; - Status Delete(const AppId &appId, const StoreId &storeId, const std::string &path) override; + Status Delete(const AppId &appId, const StoreId &storeId) override; Status Sync(const AppId &appId, const StoreId &storeId, const SyncInfo &syncInfo) override; Status RegisterSyncCallback( const AppId &appId, const StoreId &storeId, sptr callback) override; diff --git a/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp b/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp index 753db0b8d..7a86e8b73 100644 --- a/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp +++ b/services/distributeddataservice/service/kvdb/kvdb_service_stub.cpp @@ -114,12 +114,7 @@ int32_t KVDBServiceStub::OnAfterCreate( int32_t KVDBServiceStub::OnDelete(const AppId &appId, const StoreId &storeId, MessageParcel &data, MessageParcel &reply) { - std::string path; - if (!ITypesUtil::Unmarshal(data, path)) { - ZLOGE("Unmarshal appId:%{public}s storeId:%{public}s", appId.appId.c_str(), storeId.storeId.c_str()); - return IPC_STUB_INVALID_DATA_ERR; - } - int32_t status = Delete(appId, storeId, path); + int32_t status = Delete(appId, storeId); if (!ITypesUtil::Marshal(reply, status)) { ZLOGE("Marshal status:0x%{public}x appId:%{public}s storeId:%{public}s", status, appId.appId.c_str(), storeId.storeId.c_str()); -- Gitee From 9045efc81c2449013a514c0989d097bdf5a2dd2a Mon Sep 17 00:00:00 2001 From: Sven Wang Date: Thu, 2 Jun 2022 17:33:29 +0800 Subject: [PATCH 4/7] update security label Signed-off-by: Sven Wang --- frameworks/innerkitsimpl/kvdb/include/store_factory.h | 1 - interfaces/innerkits/distributeddata/BUILD.gn | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/frameworks/innerkitsimpl/kvdb/include/store_factory.h b/frameworks/innerkitsimpl/kvdb/include/store_factory.h index 0588fcfa1..6e544a5f3 100644 --- a/frameworks/innerkitsimpl/kvdb/include/store_factory.h +++ b/frameworks/innerkitsimpl/kvdb/include/store_factory.h @@ -37,7 +37,6 @@ private: using DBPassword = DistributedDB::CipherPassword; StoreFactory(); - std::shared_ptr GetDBManager(const std::string &path, const AppId &appId); DBOption GetDBOption(const Options &options, const DBPassword &password) const; ConcurrentMap> dbManagers_; diff --git a/interfaces/innerkits/distributeddata/BUILD.gn b/interfaces/innerkits/distributeddata/BUILD.gn index 73482027d..bf2c7c1e2 100644 --- a/interfaces/innerkits/distributeddata/BUILD.gn +++ b/interfaces/innerkits/distributeddata/BUILD.gn @@ -36,6 +36,7 @@ config("distributeddatafwk_config") { "//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/app_distributeddata/include", "//foundation/distributeddatamgr/appdatamgr/interfaces/inner_api/native/data_share/provider/include", "//foundation/distributeddatamgr/appdatamgr/interfaces/inner_api/native/data_share/common/include", + "//foundation/distributeddatamgr/distributedfile/interfaces/kits/js/src/mod_securitylabel", ] } @@ -113,6 +114,7 @@ ohos_shared_library("distributeddata_inner") { "//utils/native/base:utils", ] external_deps = [ + "dataclassification:data_transit_mgr", "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", "samgr_standard:samgr_proxy", -- Gitee From 15f008ade50fa0c3ba9934660de36758edf65c4d Mon Sep 17 00:00:00 2001 From: Sven Wang Date: Thu, 2 Jun 2022 19:13:01 +0800 Subject: [PATCH 5/7] update Signed-off-by: Sven Wang --- frameworks/innerkitsimpl/kvdb/src/store_factory.cpp | 1 + frameworks/innerkitsimpl/kvdb/src/system_api.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/frameworks/innerkitsimpl/kvdb/src/store_factory.cpp b/frameworks/innerkitsimpl/kvdb/src/store_factory.cpp index 2cd4f3d33..ab0487b5d 100644 --- a/frameworks/innerkitsimpl/kvdb/src/store_factory.cpp +++ b/frameworks/innerkitsimpl/kvdb/src/store_factory.cpp @@ -40,6 +40,7 @@ std::shared_ptr StoreFactory::Create( std::shared_ptr kvStore; stores_.Compute(appId, [&](auto &, auto &stores) { if (stores.find(storeId) != stores.end()) { + kvStore = stores[storeId]; return !stores.empty(); } auto dbManager = GetDBManager(path, appId); diff --git a/frameworks/innerkitsimpl/kvdb/src/system_api.cpp b/frameworks/innerkitsimpl/kvdb/src/system_api.cpp index e6d95db72..61d528890 100644 --- a/frameworks/innerkitsimpl/kvdb/src/system_api.cpp +++ b/frameworks/innerkitsimpl/kvdb/src/system_api.cpp @@ -45,7 +45,7 @@ bool SystemApi::IsAccessControlled() const SystemApi::DBStatus SystemApi::SetSecurityOption(const std::string &filePath, const DBOption &option) { - if (filePath.empty() || Label::NOT_SET < option.securityLabel || option.securityLabel > Label::S4) { + if (filePath.empty() || option.securityLabel < Label::NOT_SET || option.securityLabel > Label::S4) { return DBStatus::INVALID_ARGS; } -- Gitee From d81fd9dbb3b19558e6a5fc5d231d6c1ed06c2c2f Mon Sep 17 00:00:00 2001 From: Sven Wang Date: Thu, 2 Jun 2022 20:30:47 +0800 Subject: [PATCH 6/7] update Signed-off-by: Sven Wang --- .../distributeddatafwk/src/kvstore_observer_client.h | 2 +- frameworks/innerkitsimpl/kvdb/src/system_api.cpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_observer_client.h b/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_observer_client.h index a4c596100..da219a62f 100644 --- a/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_observer_client.h +++ b/frameworks/innerkitsimpl/distributeddatafwk/src/kvstore_observer_client.h @@ -26,7 +26,7 @@ namespace OHOS { namespace DistributedKv { class KvStoreObserverClient : public KvStoreObserverStub { public: - KvStoreObserverClient(std::shared_ptr kvStoreObserver); + explicit KvStoreObserverClient(std::shared_ptr kvStoreObserver); ~KvStoreObserverClient(); diff --git a/frameworks/innerkitsimpl/kvdb/src/system_api.cpp b/frameworks/innerkitsimpl/kvdb/src/system_api.cpp index 61d528890..fa2b2b5bd 100644 --- a/frameworks/innerkitsimpl/kvdb/src/system_api.cpp +++ b/frameworks/innerkitsimpl/kvdb/src/system_api.cpp @@ -72,7 +72,6 @@ SystemApi::DBStatus SystemApi::SetSecurityOption(const std::string &filePath, co } return DBStatus::OK; - } SystemApi::DBStatus SystemApi::GetSecurityOption(const std::string &filePath, DBOption &option) const -- Gitee From 87b4e3d4897d7a10eb1f012e4b8f1dc55b61f5da Mon Sep 17 00:00:00 2001 From: Sven Wang Date: Sun, 5 Jun 2022 11:59:59 +0800 Subject: [PATCH 7/7] update Signed-off-by: Sven Wang --- .../kvdb/include/single_store_impl.h | 2 +- .../innerkitsimpl/kvdb/src/single_store_impl.cpp | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h b/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h index 45fe2383c..d3cc7b3bf 100644 --- a/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h +++ b/frameworks/innerkitsimpl/kvdb/include/single_store_impl.h @@ -79,7 +79,7 @@ private: Status GetResultSet(const DistributedDB::Query &query, std::shared_ptr &resultSet) const; Status GetEntries(const DistributedDB::Query &query, std::vector &entries) const; std::vector GetPrefix(const DataQuery &query) const; - sptr GetIPCSyncClient(); + sptr GetIPCSyncClient(std::shared_ptr service); Status DoSync(const SyncInfo &syncInfo, std::shared_ptr observer); std::string appId_; diff --git a/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp b/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp index b8eedb6ce..10c5d96cb 100644 --- a/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp +++ b/frameworks/innerkitsimpl/kvdb/src/single_store_impl.cpp @@ -655,7 +655,7 @@ std::vector SingleStoreImpl::GetPrefix(const DataQuery &query) const return { prefix.begin(), prefix.end() }; } -sptr SingleStoreImpl::GetIPCSyncClient() +sptr SingleStoreImpl::GetIPCSyncClient(std::shared_ptr service) { sptr callback; { @@ -667,8 +667,8 @@ sptr SingleStoreImpl::GetIPCSyncClient() callback = syncCallback_; } - if (callback != nullptr) { - KVDBServiceClient::GetInstance()->RegisterSyncCallback({ appId_ }, { storeId_ }, callback); + if (service != nullptr) { + service->RegisterSyncCallback({ appId_ }, { storeId_ }, callback); } return callback; @@ -676,12 +676,17 @@ sptr SingleStoreImpl::GetIPCSyncClient() Status SingleStoreImpl::DoSync(const SyncInfo &syncInfo, std::shared_ptr observer) { - auto syncClient = GetIPCSyncClient(); + auto service = KVDBServiceClient::GetInstance(); + if (service == nullptr) { + return SERVER_UNAVAILABLE; + } + + auto syncClient = GetIPCSyncClient(service); if (syncClient == nullptr) { ZLOGE("db:%{public}s already closed!", storeId_.c_str()); return ILLEGAL_STATE; } syncClient->AddSyncCallback(observer, syncInfo.seqId); - return KVDBServiceClient::GetInstance()->Sync({ appId_ }, { storeId_ }, syncInfo); + return service->Sync({ appId_ }, { storeId_ }, syncInfo); } } // namespace OHOS::DistributedKv \ No newline at end of file -- Gitee