• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #define LOG_TAG "DeviceKvStoreImpl"
17 
18 #include "device_kvstore_impl.h"
19 
20 #include <regex>
21 
22 #include "constant.h"
23 #include "device_kvstore_observer_impl.h"
24 #include "device_kvstore_resultset_impl.h"
25 #include "kvstore_utils.h"
26 #include "log_print.h"
27 
28 namespace OHOS::DistributedKv {
29 using namespace AppDistributedKv;
DeviceKvStoreImpl(const Options & options,const std::string & userId,const std::string & bundleName,const std::string & storeId,const std::string & appId,const std::string & directory,DistributedDB::KvStoreNbDelegate * delegate)30 DeviceKvStoreImpl::DeviceKvStoreImpl(const Options &options, const std::string &userId, const std::string &bundleName,
31     const std::string &storeId, const std::string &appId, const std::string &directory,
32     DistributedDB::KvStoreNbDelegate *delegate)
33     : SingleKvStoreImpl(options, userId, bundleName, storeId, appId, directory, delegate)
34 {
35 }
36 
~DeviceKvStoreImpl()37 DeviceKvStoreImpl::~DeviceKvStoreImpl()
38 {}
39 
Get(const Key & key,Value & value)40 Status DeviceKvStoreImpl::Get(const Key &key, Value &value)
41 {
42     std::vector<uint8_t> tmpkey;
43     Status status = DeleteKeyPrefix(key, tmpkey);
44     if (status != Status::SUCCESS) {
45         ZLOGE("get deviceid failed.");
46         return status;
47     }
48     KeyEncap ke {static_cast<int>(localDeviceId_.length())};
49     tmpkey.insert(tmpkey.end(), std::begin(ke.byteLen), std::end(ke.byteLen));
50     Key decorateKey(tmpkey);
51     return SingleKvStoreImpl::Get(decorateKey, value);
52 }
53 
Put(const Key & key,const Value & value)54 Status DeviceKvStoreImpl::Put(const Key &key, const Value &value)
55 {
56     std::vector<uint8_t> tmpkey;
57     AddKeyPrefixAndSuffix(key, tmpkey);
58     Key decorateKey(tmpkey);
59     return SingleKvStoreImpl::Put(decorateKey, value);
60 }
61 
Delete(const Key & key)62 Status DeviceKvStoreImpl::Delete(const Key &key)
63 {
64     std::vector<uint8_t> tmpkey;
65     AddKeyPrefixAndSuffix(key, tmpkey);
66     Key decorateKey(tmpkey);
67     return SingleKvStoreImpl::Delete(decorateKey);
68 }
69 
GetEntries(const Key & prefixKey,std::vector<Entry> & entries)70 Status DeviceKvStoreImpl::GetEntries(const Key &prefixKey, std::vector<Entry> &entries)
71 {
72     std::vector<uint8_t> tmpkey;
73     Status status = DeleteKeyPrefix(prefixKey, tmpkey);
74     if (status == Status::KEY_NOT_FOUND) {
75         ZLOGE("DeleteKeyPrefix deviceId is invalid.");
76         return Status::SUCCESS;
77     }
78 
79     if (status != Status::SUCCESS) {
80         ZLOGE("DeleteKeyPrefix failed.");
81         return Status::ERROR;
82     }
83     Key decorateKey(tmpkey);
84     std::vector<Entry> tmpEntries;
85     Status ret = SingleKvStoreImpl::GetEntries(decorateKey, tmpEntries);
86     if (ret != Status::SUCCESS) {
87         ZLOGE("GetEntries status=%d", static_cast<int>(ret));
88         return ret;
89     }
90 
91     for (const auto &entry : tmpEntries) {
92         std::vector<uint8_t> tmpkey;
93         DeletePrefixAndSuffix(entry.key, tmpkey);
94         Key retKey(tmpkey);
95         Entry en;
96         en.key = retKey;
97         en.value = entry.value;
98         entries.push_back(en);
99     }
100     return ret;
101 }
102 
GetResultSet(const Key & prefixKey,std::function<void (Status,sptr<IKvStoreResultSet>)> callback)103 void DeviceKvStoreImpl::GetResultSet(const Key &prefixKey,
104                                      std::function<void(Status, sptr<IKvStoreResultSet>)> callback)
105 {
106     std::vector<uint8_t> tmpkey;
107     Status status = DeleteKeyPrefix(prefixKey, tmpkey);
108     if (status != Status::SUCCESS) {
109         ZLOGE("DeleteKeyPrefix failed.");
110         callback(status, nullptr);
111         return;
112     }
113     Key decorateKey(tmpkey);
114     SingleKvStoreImpl::GetResultSet(decorateKey, callback);
115 }
116 
PutBatch(const std::vector<Entry> & entries)117 Status DeviceKvStoreImpl::PutBatch(const std::vector<Entry> &entries)
118 {
119     std::vector<Entry> tmpEntries = entries;
120     for (auto &entry : tmpEntries) {
121         std::vector<uint8_t> tmpkey;
122         AddKeyPrefixAndSuffix(entry.key, tmpkey);
123         Key decorateKey(tmpkey);
124         entry.key = decorateKey;
125     }
126 
127     return SingleKvStoreImpl::PutBatch(tmpEntries);
128 }
129 
DeleteBatch(const std::vector<Key> & keys)130 Status DeviceKvStoreImpl::DeleteBatch(const std::vector<Key> &keys)
131 {
132     std::vector<Key> tmpKeys = keys;
133     for (auto &key : tmpKeys) {
134         std::vector<uint8_t> tmpkey;
135         AddKeyPrefixAndSuffix(key, tmpkey);
136         Key decorateKey(tmpkey);
137         key = decorateKey;
138     }
139     return SingleKvStoreImpl::DeleteBatch(tmpKeys);
140 }
141 
GetEntriesWithQuery(const std::string & query,std::vector<Entry> & entries)142 Status DeviceKvStoreImpl::GetEntriesWithQuery(const std::string &query, std::vector<Entry> &entries)
143 {
144     Status ret = SingleKvStoreImpl::GetEntriesWithQuery(query, entries);
145     if (ret != Status::SUCCESS) {
146         return ret;
147     }
148 
149     for (auto &entry : entries) {
150         std::vector<uint8_t> tmpkey;
151         DeletePrefixAndSuffix(entry.key, tmpkey);
152         Key retKey(tmpkey);
153         entry.key = retKey;
154     }
155     return ret;
156 }
157 
158 std::string DeviceKvStoreImpl::localDeviceId_;
GetLocalDeviceId()159 std::string DeviceKvStoreImpl::GetLocalDeviceId()
160 {
161     if (!localDeviceId_.empty()) {
162         return localDeviceId_;
163     }
164 
165     localDeviceId_ = KvStoreUtils::GetProviderInstance().GetLocalDevice().deviceId;
166     return localDeviceId_;
167 }
168 
DeleteKeyPrefix(const Key & in,std::vector<uint8_t> & out)169 Status DeviceKvStoreImpl::DeleteKeyPrefix(const Key &in, std::vector<uint8_t> &out)
170 {
171     GetLocalDeviceId();
172     // |head length|nodeid ID| original ID|
173     // |----4------|---------|------------|
174     // indicate head len is 4; this key is from java;
175     size_t deviceIdPrefixLen = 4;
176     auto inData = in.Data();
177     if (inData.size() < deviceIdPrefixLen) {
178         ZLOGE("inData length is error.");
179         return Status::ERROR;
180     }
181     std::string deviceIdLenStr(inData.begin(), inData.begin() + deviceIdPrefixLen);
182     std::regex pattern("^[0-9]*$");
183     if (!std::regex_match(deviceIdLenStr, pattern)) {
184         ZLOGE("device id length is error.");
185         return Status::ERROR;
186     }
187     std::string nodeid(inData.begin() + deviceIdPrefixLen, inData.begin() + deviceIdPrefixLen + localDeviceId_.size());
188     std::string deviceUuID = KvStoreUtils::GetProviderInstance().GetUuidByNodeId(nodeid);
189     if (deviceUuID.empty()) {
190         ZLOGE("device uuid is empty.");
191         return Status::KEY_NOT_FOUND;
192     }
193     out.insert(out.end(), deviceUuID.begin(), deviceUuID.end());
194 
195     std::string original (inData.begin() + deviceIdPrefixLen + localDeviceId_.size(), inData.end());
196     out.insert(out.end(), original.begin(), original.end());
197     return Status::SUCCESS;
198 }
199 
200 // need to delete prefix UDID and suffix UDID length;
DeletePrefixAndSuffix(const Key & in,std::vector<uint8_t> & out)201 void DeviceKvStoreImpl::DeletePrefixAndSuffix(const Key &in, std::vector<uint8_t> &out)
202 {
203     GetLocalDeviceId();
204     if (localDeviceId_.empty()) {
205         ZLOGE("Get deviceid failed.");
206         return;
207     }
208     out.insert(out.end(), in.Data().begin() + localDeviceId_.size(), in.Data().end() - sizeof(int));
209 }
210 
211 // need to add UDID to key prefix, add UDID length to key suffix to adapter 1.0;
212 // | UDID | KEY | UDID len |
AddKeyPrefixAndSuffix(const Key & in,std::vector<uint8_t> & out)213 bool DeviceKvStoreImpl::AddKeyPrefixAndSuffix(const Key &in, std::vector<uint8_t> &out)
214 {
215     GetLocalDeviceId();
216     if (localDeviceId_.empty()) {
217         ZLOGE("Get deviceid failed.");
218         return false;
219     }
220     // device ID
221     out.insert(out.end(), localDeviceId_.begin(), localDeviceId_.end());
222     // the original key
223     out.insert(out.end(), in.Data().begin(), in.Data().end());
224     // add device ID length to the tail, which include 4 uint8_t;
225     KeyEncap ke {static_cast<int>(localDeviceId_.length())};
226     out.insert(out.end(), std::begin(ke.byteLen), std::end(ke.byteLen));
227     return true;
228 }
229 
CreateObserver(const SubscribeType subscribeType,sptr<IKvStoreObserver> observer)230 KvStoreObserverImpl *DeviceKvStoreImpl::CreateObserver(
231     const SubscribeType subscribeType, sptr<IKvStoreObserver> observer)
232 {
233     return new (std::nothrow) DeviceKvStoreObserverImpl(subscribeType, observer);
234 }
235 
CreateResultSet(DistributedDB::KvStoreResultSet * resultSet,const DistributedDB::Key & prix)236 KvStoreResultSetImpl *DeviceKvStoreImpl::CreateResultSet(
237     DistributedDB::KvStoreResultSet *resultSet, const DistributedDB::Key &prix)
238 {
239     return new (std::nothrow) DeviceKvStoreResultSetImpl(resultSet, prix);
240 }
241 }
242