• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 #include "account_data_storage.h"
16 #include <memory>
17 #include <unistd.h>
18 #include "account_log_wrapper.h"
19 #include "account_hisysevent_adapter.h"
20 
21 namespace OHOS {
22 namespace AccountSA {
23 const int32_t MAX_TIMES = 10;
24 const int32_t SLEEP_INTERVAL = 100 * 1000;
25 constexpr char KV_STORE_EL1_BASE_DIR[] = "/data/service/el1/public/database/";
26 
27 #ifndef SQLITE_DLCLOSE_ENABLE
AccountDataStorage(const std::string & appId,const std::string & storeId,const AccountDataStorageOptions & options)28 AccountDataStorage::AccountDataStorage(const std::string &appId, const std::string &storeId,
29     const AccountDataStorageOptions &options)
30 {
31     ACCOUNT_LOGI("Constructed");
32     appId_.appId = appId;
33     storeId_.storeId = storeId;
34     options_ = options;
35     if (options_.area == DistributedKv::EL1) {
36         baseDir_ = KV_STORE_EL1_BASE_DIR + appId;
37     } else {
38         baseDir_ = options.baseDir;
39     }
40 }
41 #else
AccountDataStorage(const std::string & appId,const std::string & storeId,const DbAdapterOptions & options)42 AccountDataStorage::AccountDataStorage(const std::string &appId, const std::string &storeId,
43     const DbAdapterOptions &options)
44 {
45     appId_ = appId;
46     storeId_ = storeId;
47     options_ = options;
48     dataManager_ = DatabaseAdapterLoader::GetInstance().GetDataManager();
49     if (options_.area == DbAdapterArea::EL1) {
50         baseDir_ = KV_STORE_EL1_BASE_DIR + appId;
51     } else {
52         baseDir_ = options.baseDir;
53     }
54     options_.baseDir = baseDir_;
55 }
56 #endif // SQLITE_DLCLOSE_ENABLE
57 
~AccountDataStorage()58 AccountDataStorage::~AccountDataStorage()
59 {
60     ACCOUNT_LOGI("Destroyed");
61     if (kvStorePtr_ != nullptr) {
62     #ifndef SQLITE_DLCLOSE_ENABLE
63         dataManager_.CloseKvStore(appId_, kvStorePtr_);
64     #else
65         dataManager_->CloseKvStore(appId_, kvStorePtr_);
66     #endif // SQLITE_DLCLOSE_ENABLE
67     }
68 }
69 
70 #ifndef SQLITE_DLCLOSE_ENABLE
TryTwice(const std::function<DistributedKv::Status ()> & func) const71 void AccountDataStorage::TryTwice(const std::function<DistributedKv::Status()> &func) const
72 {
73     OHOS::DistributedKv::Status status = func();
74     if (status == OHOS::DistributedKv::Status::IPC_ERROR) {
75         status = func();
76         ACCOUNT_LOGE("distribute database ipc error and try again, status = %{public}d", status);
77     }
78 }
79 #else
TryTwice(const std::function<DbAdapterStatus ()> & func) const80 void AccountDataStorage::TryTwice(const std::function<DbAdapterStatus()> &func) const
81 {
82     DbAdapterStatus status = func();
83     if (status == DbAdapterStatus::IPC_ERROR) {
84         status = func();
85         ACCOUNT_LOGE("distribute database ipc error and try again, status = %{public}d", status);
86     }
87 }
88 #endif // SQLITE_DLCLOSE_ENABLE
89 
90 #ifndef SQLITE_DLCLOSE_ENABLE
GetKvStore()91 OHOS::DistributedKv::Status AccountDataStorage::GetKvStore()
92 {
93     OHOS::DistributedKv::Options options = {
94         .createIfMissing = true,
95         .encrypt = options_.encrypt,
96         .autoSync = options_.autoSync,
97         .syncable = options_.autoSync,
98         .securityLevel = options_.securityLevel,
99         .area = options_.area,
100         .kvStoreType = OHOS::DistributedKv::KvStoreType::SINGLE_VERSION,
101         .baseDir = baseDir_,
102     };
103 
104     OHOS::DistributedKv::Status status = dataManager_.GetSingleKvStore(options, appId_, storeId_, kvStorePtr_);
105     if (status != OHOS::DistributedKv::Status::SUCCESS || kvStorePtr_ == nullptr) {
106 #else
107 DbAdapterStatus AccountDataStorage::GetKvStore()
108 {
109     DbAdapterStatus status = dataManager_->GetSingleKvStore(options_, appId_, storeId_, kvStorePtr_);
110     if (status != DbAdapterStatus::SUCCESS || kvStorePtr_ == nullptr) {
111 #endif // SQLITE_DLCLOSE_ENABLE
112         ACCOUNT_LOGE("GetSingleKvStore failed! status %{public}d, kvStorePtr_ is nullptr", status);
113         return status;
114     }
115     return status;
116 }
117 
118 bool AccountDataStorage::CheckKvStore()
119 {
120     std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
121 
122     if (kvStorePtr_ != nullptr) {
123         return true;
124     }
125     int32_t tryTimes = MAX_TIMES;
126 #ifndef SQLITE_DLCLOSE_ENABLE
127     OHOS::DistributedKv::Status status = OHOS::DistributedKv::Status::SUCCESS;
128 #else
129     DbAdapterStatus status = DbAdapterStatus::SUCCESS;
130 #endif // SQLITE_DLCLOSE_ENABLE
131     while (tryTimes > 0) {
132         status = GetKvStore();
133     #ifndef SQLITE_DLCLOSE_ENABLE
134         if (status == OHOS::DistributedKv::Status::SUCCESS && kvStorePtr_ != nullptr) {
135             break;
136         }
137     #else
138         if (status == DbAdapterStatus::SUCCESS && kvStorePtr_ != nullptr) {
139             break;
140         }
141     #endif // SQLITE_DLCLOSE_ENABLE
142 
143         usleep(SLEEP_INTERVAL);
144         tryTimes--;
145     }
146 
147     if (kvStorePtr_ == nullptr) {
148         return false;
149     }
150 
151     return true;
152 }
153 
154 ErrCode AccountDataStorage::LoadAllData(std::map<std::string, std::shared_ptr<IAccountInfo>> &infos)
155 {
156     if (!CheckKvStore()) {
157         ACCOUNT_LOGE("kvStore is nullptr");
158         return OHOS::ERR_OSACCOUNT_SERVICE_MANAGER_QUERY_DISTRIBUTE_DATA_ERROR;
159     }
160 #ifndef SQLITE_DLCLOSE_ENABLE
161     OHOS::DistributedKv::Status status = DistributedKv::Status::SUCCESS;
162     std::vector<OHOS::DistributedKv::Entry> allEntries;
163     TryTwice([this, &status, &allEntries] {
164         status = GetEntries("", allEntries);
165         return status;
166     });
167 
168     if (status != OHOS::DistributedKv::Status::SUCCESS) {
169 #else
170     DbAdapterStatus status = DbAdapterStatus::SUCCESS;
171     std::vector<DbAdapterEntry> allEntries;
172     TryTwice([this, &status, &allEntries] {
173         status = GetEntries("", allEntries);
174         return status;
175     });
176 
177     if (status != DbAdapterStatus::SUCCESS) {
178 #endif // SQLITE_DLCLOSE_ENABLE
179         ACCOUNT_LOGE("get entries error: %{public}d", status);
180         return OHOS::ERR_OSACCOUNT_SERVICE_MANAGER_QUERY_DISTRIBUTE_DATA_ERROR;
181     }
182     infos.clear();
183     SaveEntries(allEntries, infos);
184     return ERR_OK;
185 }
186 
187 ErrCode AccountDataStorage::AddAccountInfo(const IAccountInfo &iAccountInfo)
188 {
189     if (IsKeyExists(iAccountInfo.GetPrimeKey())) {
190         ACCOUNT_LOGE("the key already exists.");
191         return ERR_OSACCOUNT_SERVICE_DATA_STORAGE_KEY_EXISTED_ERROR;
192     }
193 
194     std::string accountInfoStr = iAccountInfo.ToString();
195     if (accountInfoStr.empty()) {
196         ACCOUNT_LOGE("account info str is empty!");
197         return ERR_OSACCOUNT_SERVICE_ACCOUNT_INFO_EMPTY_ERROR;
198     }
199     return PutValueToKvStore(iAccountInfo.GetPrimeKey(), accountInfoStr);
200 }
201 
202 ErrCode AccountDataStorage::SaveAccountInfo(const IAccountInfo &iAccountInfo)
203 {
204     if (!IsKeyExists(iAccountInfo.GetPrimeKey())) {
205         ACCOUNT_LOGE("the key does not exist");
206         return ERR_OSACCOUNT_SERVICE_DATA_STORAGE_KEY_NOT_EXISTS_ERROR;
207     }
208 
209     std::string accountInfoStr = iAccountInfo.ToString();
210     if (accountInfoStr.empty()) {
211         ACCOUNT_LOGE("account info str is empty!");
212         return ERR_OSACCOUNT_SERVICE_ACCOUNT_INFO_EMPTY_ERROR;
213     }
214     return PutValueToKvStore(iAccountInfo.GetPrimeKey(), accountInfoStr);
215 }
216 
217 #ifndef SQLITE_DLCLOSE_ENABLE
218 ErrCode AccountDataStorage::RemoveValueFromKvStore(const std::string &keyStr)
219 {
220     if (!CheckKvStore()) {
221         ACCOUNT_LOGE("kvStore is nullptr");
222         return ERR_ACCOUNT_COMMON_CHECK_KVSTORE_ERROR;
223     }
224 
225     OHOS::DistributedKv::Key key(keyStr);
226     OHOS::DistributedKv::Status status;
227     OHOS::DistributedKv::Value value;
228     {
229         std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
230         // check exist
231         status = kvStorePtr_->Get(key, value);
232         if (status == OHOS::DistributedKv::Status::IPC_ERROR) {
233             ACCOUNT_LOGE("kvstore ipc error and try again, status = %{public}d", status);
234             status = kvStorePtr_->Get(key, value);
235         }
236         if (status != OHOS::DistributedKv::Status::SUCCESS) {
237             ACCOUNT_LOGI("key does not exist in kvStore.");
238             return ERR_OK;
239         }
240 
241         // delete
242         status = kvStorePtr_->Delete(key);
243         if (status == OHOS::DistributedKv::Status::IPC_ERROR) {
244             status = kvStorePtr_->Delete(key);
245             ACCOUNT_LOGE("kvstore ipc error and try to call again, status = %{public}d", status);
246         }
247     }
248 
249     if (status != OHOS::DistributedKv::Status::SUCCESS) {
250         ACCOUNT_LOGE("delete key from kvstore failed, status %{public}d.", status);
251         return ERR_ACCOUNT_COMMON_DELETE_KEY_FROM_KVSTORE_ERROR;
252     }
253 
254     ACCOUNT_LOGD("delete key from kvStore succeed!");
255     return ERR_OK;
256 }
257 #else
258 ErrCode AccountDataStorage::RemoveValueFromKvStore(const std::string &keyStr)
259 {
260     if (!CheckKvStore()) {
261         ACCOUNT_LOGE("kvStore is nullptr");
262         return ERR_ACCOUNT_COMMON_CHECK_KVSTORE_ERROR;
263     }
264 
265     DbAdapterStatus status;
266     std::string value;
267     {
268         std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
269         // check exist
270         status = kvStorePtr_->Get(keyStr, value);
271         if (status == DbAdapterStatus::IPC_ERROR) {
272             ACCOUNT_LOGE("kvstore ipc error and try again, status = %{public}d", status);
273             status = kvStorePtr_->Get(keyStr, value);
274         }
275         if (status != DbAdapterStatus::SUCCESS) {
276             ACCOUNT_LOGI("key does not exist in kvStore.");
277             return ERR_OK;
278         }
279 
280         // delete
281         status = kvStorePtr_->Delete(keyStr);
282         if (status == DbAdapterStatus::IPC_ERROR) {
283             status = kvStorePtr_->Delete(keyStr);
284             ACCOUNT_LOGE("kvstore ipc error and try to call again, status = %{public}d", status);
285         }
286     }
287 
288     if (status != DbAdapterStatus::SUCCESS) {
289         ACCOUNT_LOGE("delete key from kvstore failed, status %{public}d.", status);
290         return ERR_ACCOUNT_COMMON_DELETE_KEY_FROM_KVSTORE_ERROR;
291     }
292 
293     ACCOUNT_LOGD("delete key from kvStore succeed!");
294     return ERR_OK;
295 }
296 #endif // SQLITE_DLCLOSE_ENABLE
297 
298 #ifndef SQLITE_DLCLOSE_ENABLE
299 OHOS::DistributedKv::Status AccountDataStorage::GetEntries(
300     std::string subId, std::vector<OHOS::DistributedKv::Entry> &allEntries) const
301 {
302     OHOS::DistributedKv::Key allEntryKeyPrefix(subId);
303     std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
304     OHOS::DistributedKv::Status status = kvStorePtr_->GetEntries(allEntryKeyPrefix, allEntries);
305 
306     return status;
307 }
308 #else
309 DbAdapterStatus AccountDataStorage::GetEntries(
310     std::string subId, std::vector<DbAdapterEntry> &allEntries) const
311 {
312     std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
313     DbAdapterStatus status = kvStorePtr_->GetEntries(subId, allEntries);
314 
315     return status;
316 }
317 #endif // SQLITE_DLCLOSE_ENABLE
318 
319 ErrCode AccountDataStorage::Close()
320 {
321     std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
322 #ifndef SQLITE_DLCLOSE_ENABLE
323     ErrCode errCode = dataManager_.CloseKvStore(appId_, kvStorePtr_);
324 #else
325     ErrCode errCode = dataManager_->CloseKvStore(appId_, kvStorePtr_);
326 #endif // SQLITE_DLCLOSE_ENABLE
327     kvStorePtr_ = nullptr;
328     return errCode;
329 }
330 
331 ErrCode AccountDataStorage::DeleteKvStore()
332 {
333 #ifndef SQLITE_DLCLOSE_ENABLE
334     if (!CheckKvStore()) {
335         ACCOUNT_LOGE("kvStore is nullptr");
336         return OHOS::ERR_OSACCOUNT_SERVICE_MANAGER_QUERY_DISTRIBUTE_DATA_ERROR;
337     }
338 
339     OHOS::DistributedKv::Status status;
340     {
341         std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
342         dataManager_.CloseKvStore(this->appId_, this->storeId_);
343         status = dataManager_.DeleteKvStore(this->appId_, this->storeId_, baseDir_);
344     }
345     if (status != OHOS::DistributedKv::Status::SUCCESS) {
346         ACCOUNT_LOGE("error, status = %{public}d", status);
347         return OHOS::ERR_OSACCOUNT_SERVICE_MANAGER_QUERY_DISTRIBUTE_DATA_ERROR;
348     }
349 #else
350     ACCOUNT_LOGI("DeleteKvStore not enabled.");
351 #endif // SQLITE_DLCLOSE_ENABLE
352     return ERR_OK;
353 }
354 
355 ErrCode AccountDataStorage::GetAccountInfoById(const std::string id, IAccountInfo &iAccountInfo)
356 {
357     std::string valueStr;
358     ErrCode ret = GetValueFromKvStore(id, valueStr);
359     if (ret != ERR_OK) {
360         ACCOUNT_LOGE("get value from kvstore failed! id %{public}s.", id.c_str());
361         return ret;
362     }
363 
364     nlohmann::json jsonObject = nlohmann::json::parse(valueStr, nullptr, false);
365     if (jsonObject.is_discarded() || !jsonObject.is_structured()) {  // check format
366         ACCOUNT_LOGE("bad format of value from kvstore! id %{public}s.", id.c_str());
367         return ERR_ACCOUNT_COMMON_BAD_JSON_FORMAT_ERROR;
368     }
369     iAccountInfo.FromJson(jsonObject);
370     return ERR_OK;
371 }
372 
373 ErrCode AccountDataStorage::LoadDataByLocalFuzzyQuery(
374     std::string subId, std::map<std::string, std::shared_ptr<IAccountInfo>> &infos)
375 {
376     if (!CheckKvStore()) {
377         ACCOUNT_LOGE("kvStore is nullptr");
378         return OHOS::ERR_OSACCOUNT_SERVICE_MANAGER_QUERY_DISTRIBUTE_DATA_ERROR;
379     }
380 #ifndef SQLITE_DLCLOSE_ENABLE
381     OHOS::DistributedKv::Status status = OHOS::DistributedKv::Status::SUCCESS;
382     std::vector<OHOS::DistributedKv::Entry> allEntries;
383 #else
384     DbAdapterStatus status = DbAdapterStatus::SUCCESS;
385     std::vector<DbAdapterEntry> allEntries;
386 #endif // SQLITE_DLCLOSE_ENABLE
387     TryTwice([this, &status, &allEntries, subId] {
388         status = GetEntries(subId, allEntries);
389         return status;
390     });
391 #ifndef SQLITE_DLCLOSE_ENABLE
392     if (status != OHOS::DistributedKv::Status::SUCCESS) {
393 #else
394     if (status != DbAdapterStatus::SUCCESS) {
395 #endif // SQLITE_DLCLOSE_ENABLE
396         ACCOUNT_LOGE("get entries error: %{public}d", status);
397         return OHOS::ERR_OSACCOUNT_SERVICE_MANAGER_QUERY_DISTRIBUTE_DATA_ERROR;
398     }
399     infos.clear();
400     SaveEntries(allEntries, infos);
401     return ERR_OK;
402 }
403 
404 ErrCode AccountDataStorage::PutValueToKvStore(const std::string &keyStr, const std::string &valueStr)
405 {
406     if (!CheckKvStore()) {
407         ACCOUNT_LOGE("kvStore is nullptr");
408         return ERR_ACCOUNT_COMMON_CHECK_KVSTORE_ERROR;
409     }
410 #ifndef SQLITE_DLCLOSE_ENABLE
411     OHOS::DistributedKv::Key key(keyStr);
412     OHOS::DistributedKv::Value value(valueStr);
413     OHOS::DistributedKv::Status status;
414 
415     {
416         std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
417         status = kvStorePtr_->Put(key, value);
418         if (status == OHOS::DistributedKv::Status::IPC_ERROR) {
419             status = kvStorePtr_->Put(key, value);
420         }
421     }
422 
423     if (status != OHOS::DistributedKv::Status::SUCCESS) {
424 #else
425     DbAdapterStatus status = DbAdapterStatus::SUCCESS;
426     {
427         std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
428         status = kvStorePtr_->Put(keyStr, valueStr);
429         if (status == DbAdapterStatus::IPC_ERROR) {
430             status = kvStorePtr_->Put(keyStr, valueStr);
431         }
432     }
433 
434     if (status != DbAdapterStatus::SUCCESS) {
435 #endif // SQLITE_DLCLOSE_ENABLE
436         ACCOUNT_LOGE("put value to kvStore error, status = %{public}d", status);
437         return OHOS::ERR_OSACCOUNT_SERVICE_MANAGER_QUERY_DISTRIBUTE_DATA_ERROR;
438     }
439 
440     return ERR_OK;
441 }
442 
443 ErrCode AccountDataStorage::GetValueFromKvStore(const std::string &keyStr, std::string &valueStr)
444 {
445     if (!CheckKvStore()) {
446         ACCOUNT_LOGE("kvStore is nullptr");
447         return ERR_ACCOUNT_COMMON_CHECK_KVSTORE_ERROR;
448     }
449 #ifndef SQLITE_DLCLOSE_ENABLE
450     OHOS::DistributedKv::Key key(keyStr);
451     OHOS::DistributedKv::Value value;
452     OHOS::DistributedKv::Status status;
453 
454     {
455         std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
456         status = kvStorePtr_->Get(key, value);
457         if (status == OHOS::DistributedKv::Status::IPC_ERROR) {
458             ACCOUNT_LOGE("kvstore ipc error and try again, status = %{public}d", status);
459             status = kvStorePtr_->Get(key, value);
460         }
461     }
462 
463     if (status != OHOS::DistributedKv::Status::SUCCESS) {
464 #else
465     DbAdapterStatus status;
466 
467     {
468         std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
469         status = kvStorePtr_->Get(keyStr, valueStr);
470         if (status == DbAdapterStatus::IPC_ERROR) {
471             ACCOUNT_LOGE("kvstore ipc error and try again, status = %{public}d", status);
472             status = kvStorePtr_->Get(keyStr, valueStr);
473         }
474     }
475 
476     if (status != DbAdapterStatus::SUCCESS) {
477 #endif // SQLITE_DLCLOSE_ENABLE
478         ACCOUNT_LOGE("get value from kvstore error, status %{public}d.", status);
479         return ERR_OSACCOUNT_SERVICE_MANAGER_QUERY_DISTRIBUTE_DATA_ERROR;
480     }
481 #ifndef SQLITE_DLCLOSE_ENABLE
482     valueStr = value.ToString();
483 #endif
484     return ERR_OK;
485 }
486 
487 bool AccountDataStorage::IsKeyExists(const std::string keyStr)
488 {
489     std::string valueStr;
490     if (GetValueFromKvStore(keyStr, valueStr) != ERR_OK) {
491         return false;
492     }
493     return true;
494 }
495 
496 ErrCode AccountDataStorage::MoveData(const std::shared_ptr<AccountDataStorage> &ptr)
497 {
498 #ifndef SQLITE_DLCLOSE_ENABLE
499     if (ptr == nullptr || !ptr->CheckKvStore() || !CheckKvStore()) {
500         ACCOUNT_LOGE("AccountDataStorage is nullptr");
501         return ERR_ACCOUNT_COMMON_CHECK_KVSTORE_ERROR;
502     }
503     std::vector<OHOS::DistributedKv::Entry> entries;
504     OHOS::DistributedKv::Status status = ptr->GetEntries("", entries);
505     if (status != OHOS::DistributedKv::Status::SUCCESS) {
506         ACCOUNT_LOGE("GetEntries failed, result=%{public}u", status);
507         return ERR_OSACCOUNT_SERVICE_MANAGER_QUERY_DISTRIBUTE_DATA_ERROR;
508     }
509     std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
510     status = kvStorePtr_->PutBatch(entries);
511     if (status != OHOS::DistributedKv::Status::SUCCESS) {
512         ACCOUNT_LOGE("PutBatch failed, result=%{public}u", status);
513         return ERR_OSACCOUNT_SERVICE_MANAGER_QUERY_DISTRIBUTE_DATA_ERROR;
514     }
515 #else
516     ACCOUNT_LOGI("MoveData not enabled.");
517 #endif
518     return ERR_OK;
519 }
520 }  // namespace AccountSA
521 }  // namespace OHOS
522