• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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 "notification_rdb_data_mgr.h"
16 
17 #include "ans_log_wrapper.h"
18 #include "os_account_manager_helper.h"
19 #include "rdb_errno.h"
20 #include <algorithm>
21 #include <cstddef>
22 #include <sstream>
23 #include <string>
24 #include <vector>
25 #include "notification_analytics_util.h"
26 
27 namespace OHOS {
28 namespace Notification {
29 namespace {
30 const std::string NOTIFICATION_KEY = "KEY";
31 const std::string NOTIFICATION_VALUE = "VALUE";
32 const int32_t NOTIFICATION_KEY_INDEX = 0;
33 const int32_t NOTIFICATION_VALUE_INDEX = 1;
34 const std::ptrdiff_t MAX_SIZE_PER_BATCH = 100;
35 } // namespace
RdbStoreDataCallBackNotificationStorage(const NotificationRdbConfig & notificationRdbConfig)36 RdbStoreDataCallBackNotificationStorage::RdbStoreDataCallBackNotificationStorage(
37     const NotificationRdbConfig &notificationRdbConfig): notificationRdbConfig_(notificationRdbConfig)
38 {
39     ANS_LOGD("create rdb store callback instance");
40 }
41 
~RdbStoreDataCallBackNotificationStorage()42 RdbStoreDataCallBackNotificationStorage::~RdbStoreDataCallBackNotificationStorage()
43 {
44     ANS_LOGD("destroy rdb store callback instance");
45 }
46 
OnCreate(NativeRdb::RdbStore & rdbStore)47 int32_t RdbStoreDataCallBackNotificationStorage::OnCreate(NativeRdb::RdbStore &rdbStore)
48 {
49     ANS_LOGD("OnCreate");
50     int ret = NativeRdb::E_OK;
51     if (hasTableInit_) {
52         return ret;
53     }
54     std::string createTableSql = "CREATE TABLE IF NOT EXISTS " + notificationRdbConfig_.tableName
55         + " (KEY TEXT NOT NULL PRIMARY KEY, VALUE TEXT NOT NULL);";
56     ret = rdbStore.ExecuteSql(createTableSql);
57     if (ret == NativeRdb::E_OK) {
58         hasTableInit_ = true;
59         ANS_LOGD("createTable succeed");
60     }
61     return ret;
62 }
63 
OnUpgrade(NativeRdb::RdbStore & rdbStore,int32_t oldVersion,int32_t newVersion)64 int32_t RdbStoreDataCallBackNotificationStorage::OnUpgrade(
65     NativeRdb::RdbStore &rdbStore, int32_t oldVersion, int32_t newVersion)
66 {
67     ANS_LOGD("OnUpgrade currentVersion: %{public}d, targetVersion: %{public}d",
68         oldVersion, newVersion);
69     return NativeRdb::E_OK;
70 }
71 
OnDowngrade(NativeRdb::RdbStore & rdbStore,int currentVersion,int targetVersion)72 int32_t RdbStoreDataCallBackNotificationStorage::OnDowngrade(
73     NativeRdb::RdbStore &rdbStore, int currentVersion, int targetVersion)
74 {
75     ANS_LOGD("OnDowngrade  currentVersion: %{public}d, targetVersion: %{public}d",
76         currentVersion, targetVersion);
77     return NativeRdb::E_OK;
78 }
79 
OnOpen(NativeRdb::RdbStore & rdbStore)80 int32_t RdbStoreDataCallBackNotificationStorage::OnOpen(NativeRdb::RdbStore &rdbStore)
81 {
82     ANS_LOGD("OnOpen");
83     return NativeRdb::E_OK;
84 }
85 
onCorruption(std::string databaseFile)86 int32_t RdbStoreDataCallBackNotificationStorage::onCorruption(std::string databaseFile)
87 {
88     return NativeRdb::E_OK;
89 }
90 
NotificationDataMgr(const NotificationRdbConfig & notificationRdbConfig)91 NotificationDataMgr::NotificationDataMgr(const NotificationRdbConfig &notificationRdbConfig)
92     : notificationRdbConfig_(notificationRdbConfig)
93 {
94     ANS_LOGD("create notification rdb data manager");
95 }
96 
Init()97 int32_t NotificationDataMgr::Init()
98 {
99     ANS_LOGD("Create rdbStore");
100     {
101         std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
102         if (rdbStore_ != nullptr) {
103             ANS_LOGD("notification rdb has existed");
104             return NativeRdb::E_OK;
105         }
106     }
107     NativeRdb::RdbStoreConfig rdbStoreConfig(
108             notificationRdbConfig_.dbPath + notificationRdbConfig_.dbName,
109             NativeRdb::StorageMode::MODE_DISK,
110             false,
111             std::vector<uint8_t>(),
112             notificationRdbConfig_.journalMode,
113             notificationRdbConfig_.syncMode);
114     rdbStoreConfig.SetSecurityLevel(NativeRdb::SecurityLevel::S1);
115     rdbStoreConfig.SetHaMode(NativeRdb::HAMode::MAIN_REPLICA);
116     RdbStoreDataCallBackNotificationStorage rdbDataCallBack_(notificationRdbConfig_);
117     std::lock_guard<std::mutex> lock(createdTableMutex_);
118     {
119         std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
120         int32_t ret = NativeRdb::E_OK;
121         rdbStore_ = NativeRdb::RdbHelper::GetRdbStore(rdbStoreConfig, notificationRdbConfig_.version,
122             rdbDataCallBack_, ret);
123         if (rdbStore_ == nullptr) {
124             ANS_LOGE("notification rdb init fail");
125             return NativeRdb::E_ERROR;
126         }
127         return InitCreatedTables();
128     }
129 }
130 
InitCreatedTables()131 int32_t NotificationDataMgr::InitCreatedTables()
132 {
133     std::string queryTableSql = "SELECT name FROM sqlite_master WHERE type='table'";
134     auto absSharedResultSet = rdbStore_->QuerySql(queryTableSql);
135     int32_t ret = absSharedResultSet->GoToFirstRow();
136     if (ret != NativeRdb::E_OK) {
137         ANS_LOGE("Query tableName failed. It's empty!");
138         return NativeRdb::E_EMPTY_VALUES_BUCKET;
139     }
140 
141     do {
142         std::string tableName;
143         ret = absSharedResultSet->GetString(0, tableName);
144         if (ret != NativeRdb::E_OK) {
145             ANS_LOGE("GetString string failed from sqlite_master table.");
146             return NativeRdb::E_ERROR;
147         }
148         createdTables_.insert(tableName);
149     } while (absSharedResultSet->GoToNextRow() == NativeRdb::E_OK);
150     absSharedResultSet->Close();
151     return NativeRdb::E_OK;
152 }
153 
Destroy()154 int32_t NotificationDataMgr::Destroy()
155 {
156     ANS_LOGD("Destory rdbStore");
157     std::lock_guard<std::mutex> lock(createdTableMutex_);
158     createdTables_.clear();
159     {
160         std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
161         if (rdbStore_ == nullptr) {
162             ANS_LOGE("notification rdb is null");
163             return NativeRdb::E_ERROR;
164         }
165 
166         rdbStore_ = nullptr;
167     }
168     int32_t ret = NativeRdb::RdbHelper::DeleteRdbStore(notificationRdbConfig_.dbPath + notificationRdbConfig_.dbName);
169     if (ret != NativeRdb::E_OK) {
170         ANS_LOGE("failed to destroy db store");
171         return NativeRdb::E_ERROR;
172     }
173     ANS_LOGD("destroy db store successfully");
174     return NativeRdb::E_OK;
175 }
176 
InsertData(const std::string & key,const std::string & value,const int32_t & userId)177 int32_t NotificationDataMgr::InsertData(const std::string &key, const std::string &value, const int32_t &userId)
178 {
179     ANS_LOGD("InsertData start");
180     {
181         std::string tableName;
182         int32_t ret = GetUserTableName(userId, tableName);
183         if (ret != NativeRdb::E_OK) {
184             ANS_LOGE("Get user table name failed.");
185             return NativeRdb::E_ERROR;
186         }
187         std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
188         if (rdbStore_ == nullptr) {
189             ANS_LOGE("notification rdb is null");
190             return NativeRdb::E_ERROR;
191         }
192         int64_t rowId = -1;
193         NativeRdb::ValuesBucket valuesBucket;
194         valuesBucket.PutString(NOTIFICATION_KEY, key);
195         valuesBucket.PutString(NOTIFICATION_VALUE, value);
196         ret = rdbStore_->InsertWithConflictResolution(rowId, tableName, valuesBucket,
197             NativeRdb::ConflictResolution::ON_CONFLICT_REPLACE);
198         if (ret == NativeRdb::E_SQLITE_CORRUPT) {
199             RestoreForMasterSlaver();
200         }
201         if (ret != NativeRdb::E_OK) {
202             ANS_LOGE("Insert operation failed, result: %{public}d, key=%{public}s.", ret, key.c_str());
203             return NativeRdb::E_ERROR;
204         }
205     }
206     return NativeRdb::E_OK;
207 }
208 
InsertData(const std::string & key,const std::vector<uint8_t> & value,const int32_t & userId)209 int32_t NotificationDataMgr::InsertData(const std::string &key, const std::vector<uint8_t> &value,
210     const int32_t &userId)
211 {
212     std::string tableName;
213     int32_t ret = GetUserTableName(userId, tableName);
214     if (ret != NativeRdb::E_OK) {
215         ANS_LOGE("Get user table name failed.");
216         return NativeRdb::E_ERROR;
217     }
218     std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
219     if (rdbStore_ == nullptr) {
220         ANS_LOGE("notification rdb is null");
221         return NativeRdb::E_ERROR;
222     }
223     int64_t rowId = -1;
224     NativeRdb::ValuesBucket valuesBucket;
225     valuesBucket.PutString(NOTIFICATION_KEY, key);
226     valuesBucket.PutBlob(NOTIFICATION_VALUE, value);
227     ret = rdbStore_->InsertWithConflictResolution(rowId, tableName, valuesBucket,
228         NativeRdb::ConflictResolution::ON_CONFLICT_REPLACE);
229     if (ret == NativeRdb::E_SQLITE_CORRUPT) {
230             RestoreForMasterSlaver();
231         }
232     if (ret != NativeRdb::E_OK) {
233         ANS_LOGE("Insert operation failed, result: %{public}d, key=%{public}s.", ret, key.c_str());
234         return NativeRdb::E_ERROR;
235     }
236     return NativeRdb::E_OK;
237 }
238 
InsertBatchData(const std::unordered_map<std::string,std::string> & values,const int32_t & userId)239 int32_t NotificationDataMgr::InsertBatchData(const std::unordered_map<std::string, std::string> &values,
240     const int32_t &userId)
241 {
242     ANS_LOGD("InsertBatchData start");
243     {
244         std::string tableName;
245         int32_t ret = GetUserTableName(userId, tableName);
246         if (ret != NativeRdb::E_OK) {
247             ANS_LOGE("Get user table name failed.");
248             return NativeRdb::E_ERROR;
249         }
250         std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
251         if (rdbStore_ == nullptr) {
252             ANS_LOGE("notification rdb is null");
253             return NativeRdb::E_ERROR;
254         }
255         int64_t rowId = -1;
256         std::vector<NativeRdb::ValuesBucket> buckets;
257         for (auto &value : values) {
258             NativeRdb::ValuesBucket valuesBucket;
259             valuesBucket.PutString(NOTIFICATION_KEY, value.first);
260             valuesBucket.PutString(NOTIFICATION_VALUE, value.second);
261             buckets.emplace_back(valuesBucket);
262         }
263         ret = rdbStore_->BatchInsert(rowId, tableName, buckets);
264         if (ret == NativeRdb::E_SQLITE_CORRUPT) {
265             RestoreForMasterSlaver();
266         }
267         if (ret != NativeRdb::E_OK) {
268             ANS_LOGE("Insert batch operation failed, result: %{public}d.", ret);
269             return NativeRdb::E_ERROR;
270         }
271     }
272     return NativeRdb::E_OK;
273 }
274 
DeleteData(const std::string & key,const int32_t & userId)275 int32_t NotificationDataMgr::DeleteData(const std::string &key, const int32_t &userId)
276 {
277     ANS_LOGD("DeleteData start");
278     std::vector<std::string> operatedTables = GenerateOperatedTables(userId);
279     std::reverse(operatedTables.begin(), operatedTables.end());
280     std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
281     if (rdbStore_ == nullptr) {
282         ANS_LOGE("notification rdb is null");
283         return NativeRdb::E_ERROR;
284     }
285     int32_t ret = NativeRdb::E_OK;
286     int32_t rowId = -1;
287     for (auto tableName : operatedTables) {
288         ret = DeleteData(tableName, key, rowId);
289         if (ret != NativeRdb::E_OK) {
290             return ret;
291         }
292     }
293     return ret;
294 }
295 
DeleteData(const std::string tableName,const std::string key,int32_t & rowId)296 int32_t NotificationDataMgr::DeleteData(const std::string tableName, const std::string key, int32_t &rowId)
297 {
298     NativeRdb::AbsRdbPredicates absRdbPredicates(tableName);
299     absRdbPredicates.EqualTo(NOTIFICATION_KEY, key);
300     int32_t ret = rdbStore_->Delete(rowId, absRdbPredicates);
301     if (ret == NativeRdb::E_SQLITE_CORRUPT) {
302         RestoreForMasterSlaver();
303     }
304     if (ret != NativeRdb::E_OK) {
305         ANS_LOGW("Delete operation failed from %{public}s, result: %{public}d, key=%{public}s.",
306             tableName.c_str(), ret, key.c_str());
307         return NativeRdb::E_ERROR;
308     }
309     return NativeRdb::E_OK;
310 }
311 
DeleteBatchData(const std::vector<std::string> & keys,const int32_t & userId)312 int32_t NotificationDataMgr::DeleteBatchData(const std::vector<std::string> &keys, const int32_t &userId)
313 {
314     ANS_LOGD("Delete Bathch Data start");
315     {
316         std::vector<std::string> operatedTables = GenerateOperatedTables(userId);
317         std::reverse(operatedTables.begin(), operatedTables.end());
318         std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
319         if (rdbStore_ == nullptr) {
320             ANS_LOGE("notification rdb is null");
321             return NativeRdb::E_ERROR;
322         }
323         std::vector<std::vector<std::string>> batchKeys;
324         auto start = keys.cbegin(), next = keys.cbegin(), end = keys.cend();
325         while (next != end) {
326             next = end - next < MAX_SIZE_PER_BATCH ? end : next + MAX_SIZE_PER_BATCH;
327             batchKeys.push_back(std::vector<std::string>(start, next));
328             start = next;
329         }
330 
331         int32_t rowId = -1;
332         for (auto tableName : operatedTables) {
333             NativeRdb::AbsRdbPredicates absRdbPredicates(tableName);
334             for (const auto &batchKey : batchKeys) {
335                 absRdbPredicates.In(NOTIFICATION_KEY, batchKey);
336                 int32_t ret = rdbStore_->Delete(rowId, absRdbPredicates);
337                 if (ret == NativeRdb::E_SQLITE_CORRUPT) {
338                     RestoreForMasterSlaver();
339                 }
340                 if (ret != NativeRdb::E_OK) {
341                     ANS_LOGW("Delete operation failed from %{public}s, result: %{public}d.",
342                         tableName.c_str(), ret);
343                     return NativeRdb::E_ERROR;
344                 }
345             }
346         }
347     }
348     return NativeRdb::E_OK;
349 }
350 
QueryData(const std::string & key,std::string & value,const int32_t & userId)351 int32_t NotificationDataMgr::QueryData(const std::string &key, std::string &value, const int32_t &userId)
352 {
353     ANS_LOGD("QueryData start");
354     std::vector<std::string> operatedTables = GenerateOperatedTables(userId);
355     std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
356     if (rdbStore_ == nullptr) {
357         ANS_LOGE("notification rdb is null");
358         return NativeRdb::E_ERROR;
359     }
360     int32_t ret = NativeRdb::E_OK;
361     for (auto tableName : operatedTables) {
362         ret = QueryData(tableName, key, value);
363         if (ret != NativeRdb::E_EMPTY_VALUES_BUCKET) {
364             return ret;
365         }
366     }
367     return ret;
368 }
369 
QueryData(const std::string tableName,const std::string key,std::string & value)370 int32_t NotificationDataMgr::QueryData(const std::string tableName, const std::string key, std::string &value)
371 {
372     NativeRdb::AbsRdbPredicates absRdbPredicates(tableName);
373     absRdbPredicates.EqualTo(NOTIFICATION_KEY, key);
374     auto absSharedResultSet = rdbStore_->Query(absRdbPredicates, std::vector<std::string>());
375     if (absSharedResultSet == nullptr) {
376         ANS_LOGE("absSharedResultSet failed from %{public}s table.", tableName.c_str());
377         return NativeRdb::E_ERROR;
378     }
379 
380     int32_t ret = absSharedResultSet->GoToFirstRow();
381     if (ret == NativeRdb::E_SQLITE_CORRUPT) {
382         RestoreForMasterSlaver();
383     }
384     if (ret != NativeRdb::E_OK) {
385         ANS_LOGW("GoToFirstRow failed from %{public}s table. It is empty!, key=%{public}s",
386             tableName.c_str(), key.c_str());
387         return NativeRdb::E_EMPTY_VALUES_BUCKET;
388     }
389     ret = absSharedResultSet->GetString(NOTIFICATION_VALUE_INDEX, value);
390     if (ret == NativeRdb::E_SQLITE_CORRUPT) {
391         RestoreForMasterSlaver();
392     }
393     if (ret != NativeRdb::E_OK) {
394         ANS_LOGE("GetString value failed from %{public}s table.", tableName.c_str());
395         return NativeRdb::E_ERROR;
396     }
397     absSharedResultSet->Close();
398     return NativeRdb::E_OK;
399 }
400 
QueryData(const std::string & key,std::vector<uint8_t> & values,const int32_t & userId)401 int32_t NotificationDataMgr::QueryData(const std::string &key, std::vector<uint8_t> &values, const int32_t &userId)
402 {
403     std::vector<std::string> operatedTables = GenerateOperatedTables(userId);
404     std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
405     if (rdbStore_ == nullptr) {
406         ANS_LOGE("notification rdb is null");
407         return NativeRdb::E_ERROR;
408     }
409     int32_t ret = NativeRdb::E_OK;
410     for (auto tableName : operatedTables) {
411         ret = QueryData(tableName, key, values);
412         if (ret != NativeRdb::E_EMPTY_VALUES_BUCKET) {
413             return ret;
414         }
415     }
416     return ret;
417 }
418 
QueryData(const std::string tableName,const std::string key,std::vector<uint8_t> & value)419 int32_t NotificationDataMgr::QueryData(const std::string tableName, const std::string key, std::vector<uint8_t> &value)
420 {
421     NativeRdb::AbsRdbPredicates absRdbPredicates(tableName);
422     absRdbPredicates.EqualTo(NOTIFICATION_KEY, key);
423     auto absSharedResultSet = rdbStore_->Query(absRdbPredicates, std::vector<std::string>());
424     if (absSharedResultSet == nullptr) {
425         ANS_LOGE("absSharedResultSet failed from %{public}s table.", tableName.c_str());
426         return NativeRdb::E_ERROR;
427     }
428 
429     int32_t ret = absSharedResultSet->GoToFirstRow();
430     if (ret == NativeRdb::E_SQLITE_CORRUPT) {
431         RestoreForMasterSlaver();
432     }
433     if (ret != NativeRdb::E_OK) {
434         ANS_LOGW("GoToFirstRow failed from %{public}s table. It is empty!, key=%{public}s",
435             tableName.c_str(), key.c_str());
436         return NativeRdb::E_EMPTY_VALUES_BUCKET;
437     }
438     ret = absSharedResultSet->GetBlob(NOTIFICATION_VALUE_INDEX, value);
439     if (ret != NativeRdb::E_OK) {
440         ANS_LOGE("GetString value failed from %{public}s table.", tableName.c_str());
441         return NativeRdb::E_ERROR;
442     }
443     absSharedResultSet->Close();
444 
445     return NativeRdb::E_OK;
446 }
447 
QueryDataBeginWithKey(const std::string & key,std::unordered_map<std::string,std::string> & values,const int32_t & userId)448 int32_t NotificationDataMgr::QueryDataBeginWithKey(
449     const std::string &key, std::unordered_map<std::string, std::string> &values, const int32_t &userId)
450 {
451     ANS_LOGD("QueryData BeginWithKey start");
452     std::vector<std::string> operatedTables = GenerateOperatedTables(userId);
453     std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
454     if (rdbStore_ == nullptr) {
455         ANS_LOGE("notification rdb is null");
456         return NativeRdb::E_ERROR;
457     }
458     int32_t ret = NativeRdb::E_OK;
459     for (auto tableName : operatedTables) {
460         ret = QueryDataBeginWithKey(tableName, key, values);
461         if (ret == NativeRdb::E_ERROR) {
462             return ret;
463         }
464     }
465     if (ret == NativeRdb::E_EMPTY_VALUES_BUCKET && values.empty()) {
466         return NativeRdb::E_EMPTY_VALUES_BUCKET;
467     }
468     return NativeRdb::E_OK;
469 }
470 
QueryDataBeginWithKey(const std::string tableName,const std::string key,std::unordered_map<std::string,std::string> & values)471 int32_t NotificationDataMgr::QueryDataBeginWithKey(
472     const std::string tableName, const std::string key, std::unordered_map<std::string, std::string> &values)
473 {
474     NativeRdb::AbsRdbPredicates absRdbPredicates(tableName);
475     absRdbPredicates.BeginsWith(NOTIFICATION_KEY, key);
476     auto absSharedResultSet = rdbStore_->Query(absRdbPredicates, std::vector<std::string>());
477     if (absSharedResultSet == nullptr) {
478         ANS_LOGE("absSharedResultSet failed from %{public}s table.", tableName.c_str());
479         return NativeRdb::E_ERROR;
480     }
481 
482     int32_t ret = absSharedResultSet->GoToFirstRow();
483     if (ret == NativeRdb::E_SQLITE_CORRUPT) {
484         RestoreForMasterSlaver();
485     }
486     if (ret != NativeRdb::E_OK) {
487         ANS_LOGD("GoToFirstRow failed from %{public}s table.It is empty!, key=%{public}s",
488             tableName.c_str(), key.c_str());
489         return NativeRdb::E_EMPTY_VALUES_BUCKET;
490     }
491 
492     do {
493         std::string resultKey;
494         ret = absSharedResultSet->GetString(NOTIFICATION_KEY_INDEX, resultKey);
495         if (ret != NativeRdb::E_OK) {
496             ANS_LOGE("Failed to GetString key from %{public}s table.", tableName.c_str());
497             return NativeRdb::E_ERROR;
498         }
499 
500         std::string resultValue;
501         ret = absSharedResultSet->GetString(NOTIFICATION_VALUE_INDEX, resultValue);
502         if (ret != NativeRdb::E_OK) {
503             ANS_LOGE("GetString value failed from %{public}s table", tableName.c_str());
504             return NativeRdb::E_ERROR;
505         }
506 
507         values.emplace(resultKey, resultValue);
508     } while (absSharedResultSet->GoToNextRow() == NativeRdb::E_OK);
509     absSharedResultSet->Close();
510 
511     return NativeRdb::E_OK;
512 }
513 
QueryAllData(std::unordered_map<std::string,std::string> & datas,const int32_t & userId)514 int32_t NotificationDataMgr::QueryAllData(std::unordered_map<std::string, std::string> &datas, const int32_t &userId)
515 {
516     ANS_LOGD("QueryAllData start");
517     std::vector<std::string> operatedTables = GenerateOperatedTables(userId);
518     std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
519     if (rdbStore_ == nullptr) {
520         ANS_LOGE("notification rdb is null");
521         return NativeRdb::E_ERROR;
522     }
523     int32_t ret = NativeRdb::E_OK;
524     for (auto tableName : operatedTables) {
525         ret = QueryAllData(tableName,  datas);
526         if (ret == NativeRdb::E_ERROR) {
527             return ret;
528         }
529     }
530     if (ret == NativeRdb::E_EMPTY_VALUES_BUCKET && datas.empty()) {
531         return NativeRdb::E_EMPTY_VALUES_BUCKET;
532     }
533     return NativeRdb::E_OK;
534 }
535 
QueryAllData(const std::string tableName,std::unordered_map<std::string,std::string> & datas)536 int32_t NotificationDataMgr::QueryAllData(
537     const std::string tableName, std::unordered_map<std::string, std::string> &datas)
538 {
539     NativeRdb::AbsRdbPredicates absRdbPredicates(tableName);
540     auto absSharedResultSet = rdbStore_->Query(absRdbPredicates, std::vector<std::string>());
541     if (absSharedResultSet == nullptr) {
542         ANS_LOGE("absSharedResultSet failed from %{public}s table.", tableName.c_str());
543         return NativeRdb::E_ERROR;
544     }
545 
546     int32_t ret = absSharedResultSet->GoToFirstRow();
547     if (ret == NativeRdb::E_SQLITE_CORRUPT) {
548         RestoreForMasterSlaver();
549     }
550     if (ret != NativeRdb::E_OK) {
551         ANS_LOGD("GoToFirstRow failed from %{public}s table. It is empty!", tableName.c_str());
552         return NativeRdb::E_EMPTY_VALUES_BUCKET;
553     }
554 
555     do {
556         std::string resultKey;
557         ret = absSharedResultSet->GetString(NOTIFICATION_KEY_INDEX, resultKey);
558         if (ret != NativeRdb::E_OK) {
559             ANS_LOGE("GetString key failed from %{public}s table.", tableName.c_str());
560             return NativeRdb::E_ERROR;
561         }
562 
563         std::string resultValue;
564         ret = absSharedResultSet->GetString(NOTIFICATION_VALUE_INDEX, resultValue);
565         if (ret != NativeRdb::E_OK) {
566             ANS_LOGE("GetString value failed from %{public}s table.", tableName.c_str());
567             return NativeRdb::E_ERROR;
568         }
569 
570         datas.emplace(resultKey, resultValue);
571     } while (absSharedResultSet->GoToNextRow() == NativeRdb::E_OK);
572     absSharedResultSet->Close();
573 
574     return NativeRdb::E_OK;
575 }
576 
DropUserTable(const int32_t userId)577 int32_t NotificationDataMgr::DropUserTable(const int32_t userId)
578 {
579     const char *keySpliter = "_";
580     std::stringstream stream;
581     stream << notificationRdbConfig_.tableName << keySpliter << userId;
582     std::string tableName = stream.str();
583     std::lock_guard<std::mutex> lock(createdTableMutex_);
584     int32_t ret = NativeRdb::E_OK;
585     {
586         std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
587         if (rdbStore_ == nullptr) {
588             return NativeRdb::E_ERROR;
589         }
590         std::string dropTableSql = "DROP TABLE IF EXISTS " + tableName;
591         ret = rdbStore_->ExecuteSql(dropTableSql);
592     }
593     if (ret == NativeRdb::E_OK) {
594         createdTables_.erase(tableName);
595         ANS_LOGD("drop Table %{public}s succeed", tableName.c_str());
596         return ret;
597     }
598     return ret;
599 }
600 
GetUserTableName(const int32_t & userId,std::string & tableName)601 int32_t NotificationDataMgr::GetUserTableName(const int32_t &userId, std::string &tableName)
602 {
603     if (!OsAccountManagerHelper::IsSystemAccount(userId)) {
604         tableName = notificationRdbConfig_.tableName;
605         return NativeRdb::E_OK;
606     }
607 
608     const char *keySpliter = "_";
609     std::stringstream stream;
610     stream << notificationRdbConfig_.tableName << keySpliter << userId;
611     tableName = stream.str();
612     if (createdTables_.find(tableName) == createdTables_.end()) {
613         std::lock_guard<std::mutex> lock(createdTableMutex_);
614         if (createdTables_.find(tableName) == createdTables_.end()) {
615             std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
616             if (rdbStore_ == nullptr) {
617                 return NativeRdb::E_ERROR;
618             }
619             std::string createTableSql = "CREATE TABLE IF NOT EXISTS " + tableName
620                 + " (KEY TEXT NOT NULL PRIMARY KEY, VALUE TEXT NOT NULL);";
621             int32_t ret = rdbStore_->ExecuteSql(createTableSql);
622             if (ret != NativeRdb::E_OK) {
623                 ANS_LOGW("createTable %{public}s failed, code: %{public}d", tableName.c_str(), ret);
624                 return ret;
625             }
626             createdTables_.insert(tableName);
627             ANS_LOGD("createTable %{public}s succeed", tableName.c_str());
628             return NativeRdb::E_OK;
629         }
630     }
631     return NativeRdb::E_OK;
632 }
633 
GenerateOperatedTables(const int32_t & userId)634 std::vector<std::string> NotificationDataMgr::GenerateOperatedTables(const int32_t &userId)
635 {
636     std::vector<std::string> operatedTables;
637     if (OsAccountManagerHelper::IsSystemAccount(userId)) {
638         const char *keySpliter = "_";
639         std::stringstream stream;
640         stream << notificationRdbConfig_.tableName << keySpliter << userId;
641         std::string tableName = stream.str();
642         std::lock_guard<std::mutex> lock(createdTableMutex_);
643         if (createdTables_.find(tableName) != createdTables_.end()) {
644             operatedTables.emplace_back(tableName);
645         }
646     }
647     operatedTables.emplace_back(notificationRdbConfig_.tableName);
648     return operatedTables;
649 }
650 
RestoreForMasterSlaver()651 int32_t NotificationDataMgr::RestoreForMasterSlaver()
652 {
653     HaMetaMessage message = HaMetaMessage(EventSceneId::SCENE_10, EventBranchId::BRANCH_1)
654         .ErrorCode(NativeRdb::E_SQLITE_CORRUPT).Message("Rdb is corruped.");
655     NotificationAnalyticsUtil::ReportModifyEvent(message);
656     ANS_LOGI("RestoreForMasterSlaver start");
657     int32_t result =  rdbStore_->Restore("");
658     ANS_LOGI("RestoreForMasterSlaver result = %{public}d", result);
659     return result;
660 }
661 }
662 }