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