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