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