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         for (auto &value : values) {
254             NativeRdb::ValuesBucket valuesBucket;
255             valuesBucket.PutString(NOTIFICATION_KEY, value.first);
256             valuesBucket.PutString(NOTIFICATION_VALUE, value.second);
257             ret = rdbStore_->InsertWithConflictResolution(rowId, tableName, valuesBucket,
258                 NativeRdb::ConflictResolution::ON_CONFLICT_REPLACE);
259             if (ret == NativeRdb::E_SQLITE_CORRUPT) {
260                 RestoreForMasterSlaver();
261             }
262             if (ret != NativeRdb::E_OK) {
263                 ANS_LOGE("Insert batch operation failed, result: %{public}d.", ret);
264                 return NativeRdb::E_ERROR;
265             }
266         }
267     }
268     return NativeRdb::E_OK;
269 }
270 
DeleteData(const std::string &key, const int32_t &userId)271 int32_t NotificationDataMgr::DeleteData(const std::string &key, const int32_t &userId)
272 {
273     ANS_LOGD("DeleteData start");
274     std::vector<std::string> operatedTables = GenerateOperatedTables(userId);
275     std::reverse(operatedTables.begin(), operatedTables.end());
276     std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
277     if (rdbStore_ == nullptr) {
278         ANS_LOGE("notification rdb is null");
279         return NativeRdb::E_ERROR;
280     }
281     int32_t ret = NativeRdb::E_OK;
282     int32_t rowId = -1;
283     for (auto tableName : operatedTables) {
284         ret = DeleteData(tableName, key, rowId);
285         if (ret != NativeRdb::E_OK) {
286             return ret;
287         }
288     }
289     return ret;
290 }
291 
DeleteData(const std::string tableName, const std::string key, int32_t &rowId)292 int32_t NotificationDataMgr::DeleteData(const std::string tableName, const std::string key, int32_t &rowId)
293 {
294     NativeRdb::AbsRdbPredicates absRdbPredicates(tableName);
295     absRdbPredicates.EqualTo(NOTIFICATION_KEY, key);
296     int32_t ret = rdbStore_->Delete(rowId, absRdbPredicates);
297     if (ret == NativeRdb::E_SQLITE_CORRUPT) {
298         RestoreForMasterSlaver();
299     }
300     if (ret != NativeRdb::E_OK) {
301         ANS_LOGW("Delete operation failed from %{public}s, result: %{public}d, key=%{public}s.",
302             tableName.c_str(), ret, key.c_str());
303         return NativeRdb::E_ERROR;
304     }
305     return NativeRdb::E_OK;
306 }
307 
DeleteBathchData(const std::vector<std::string> &keys, const int32_t &userId)308 int32_t NotificationDataMgr::DeleteBathchData(const std::vector<std::string> &keys, const int32_t &userId)
309 {
310     ANS_LOGD("Delete Bathch Data start");
311     {
312         std::vector<std::string> operatedTables = GenerateOperatedTables(userId);
313         std::reverse(operatedTables.begin(), operatedTables.end());
314         std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
315         if (rdbStore_ == nullptr) {
316             ANS_LOGE("notification rdb is null");
317             return NativeRdb::E_ERROR;
318         }
319         int32_t rowId = -1;
320         for (auto key : keys) {
321             for (auto tableName : operatedTables) {
322                 int32_t ret = DeleteData(tableName, key, rowId);
323                 if (ret != NativeRdb::E_OK) {
324                     return ret;
325                 }
326             }
327         }
328     }
329     return NativeRdb::E_OK;
330 }
331 
QueryData(const std::string &key, std::string &value, const int32_t &userId)332 int32_t NotificationDataMgr::QueryData(const std::string &key, std::string &value, const int32_t &userId)
333 {
334     ANS_LOGD("QueryData start");
335     std::vector<std::string> operatedTables = GenerateOperatedTables(userId);
336     std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
337     if (rdbStore_ == nullptr) {
338         ANS_LOGE("notification rdb is null");
339         return NativeRdb::E_ERROR;
340     }
341     int32_t ret = NativeRdb::E_OK;
342     for (auto tableName : operatedTables) {
343         ret = QueryData(tableName, key, value);
344         if (ret != NativeRdb::E_EMPTY_VALUES_BUCKET) {
345             return ret;
346         }
347     }
348     return ret;
349 }
350 
QueryData(const std::string tableName, const std::string key, std::string &value)351 int32_t NotificationDataMgr::QueryData(const std::string tableName, const std::string key, std::string &value)
352 {
353     NativeRdb::AbsRdbPredicates absRdbPredicates(tableName);
354     absRdbPredicates.EqualTo(NOTIFICATION_KEY, key);
355     auto absSharedResultSet = rdbStore_->Query(absRdbPredicates, std::vector<std::string>());
356     if (absSharedResultSet == nullptr) {
357         ANS_LOGE("absSharedResultSet failed from %{public}s table.", tableName.c_str());
358         return NativeRdb::E_ERROR;
359     }
360 
361     int32_t ret = absSharedResultSet->GoToFirstRow();
362     if (ret == NativeRdb::E_SQLITE_CORRUPT) {
363         RestoreForMasterSlaver();
364     }
365     if (ret != NativeRdb::E_OK) {
366         ANS_LOGW("GoToFirstRow failed from %{public}s table. It is empty!, key=%{public}s",
367             tableName.c_str(), key.c_str());
368         return NativeRdb::E_EMPTY_VALUES_BUCKET;
369     }
370     ret = absSharedResultSet->GetString(NOTIFICATION_VALUE_INDEX, value);
371     if (ret == NativeRdb::E_SQLITE_CORRUPT) {
372         RestoreForMasterSlaver();
373     }
374     if (ret != NativeRdb::E_OK) {
375         ANS_LOGE("GetString value failed from %{public}s table.", tableName.c_str());
376         return NativeRdb::E_ERROR;
377     }
378     absSharedResultSet->Close();
379     return NativeRdb::E_OK;
380 }
381 
QueryData(const std::string &key, std::vector<uint8_t> &values, const int32_t &userId)382 int32_t NotificationDataMgr::QueryData(const std::string &key, std::vector<uint8_t> &values, const int32_t &userId)
383 {
384     std::vector<std::string> operatedTables = GenerateOperatedTables(userId);
385     std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
386     if (rdbStore_ == nullptr) {
387         ANS_LOGE("notification rdb is null");
388         return NativeRdb::E_ERROR;
389     }
390     int32_t ret = NativeRdb::E_OK;
391     for (auto tableName : operatedTables) {
392         ret = QueryData(tableName, key, values);
393         if (ret != NativeRdb::E_EMPTY_VALUES_BUCKET) {
394             return ret;
395         }
396     }
397     return ret;
398 }
399 
QueryData(const std::string tableName, const std::string key, std::vector<uint8_t> &value)400 int32_t NotificationDataMgr::QueryData(const std::string tableName, const std::string key, std::vector<uint8_t> &value)
401 {
402     NativeRdb::AbsRdbPredicates absRdbPredicates(tableName);
403     absRdbPredicates.EqualTo(NOTIFICATION_KEY, key);
404     auto absSharedResultSet = rdbStore_->Query(absRdbPredicates, std::vector<std::string>());
405     if (absSharedResultSet == nullptr) {
406         ANS_LOGE("absSharedResultSet failed from %{public}s table.", tableName.c_str());
407         return NativeRdb::E_ERROR;
408     }
409 
410     int32_t ret = absSharedResultSet->GoToFirstRow();
411     if (ret == NativeRdb::E_SQLITE_CORRUPT) {
412         RestoreForMasterSlaver();
413     }
414     if (ret != NativeRdb::E_OK) {
415         ANS_LOGW("GoToFirstRow failed from %{public}s table. It is empty!, key=%{public}s",
416             tableName.c_str(), key.c_str());
417         return NativeRdb::E_EMPTY_VALUES_BUCKET;
418     }
419     ret = absSharedResultSet->GetBlob(NOTIFICATION_VALUE_INDEX, value);
420     if (ret != NativeRdb::E_OK) {
421         ANS_LOGE("GetString value failed from %{public}s table.", tableName.c_str());
422         return NativeRdb::E_ERROR;
423     }
424     absSharedResultSet->Close();
425 
426     return NativeRdb::E_OK;
427 }
428 
QueryDataBeginWithKey( const std::string &key, std::unordered_map<std::string, std::string> &values, const int32_t &userId)429 int32_t NotificationDataMgr::QueryDataBeginWithKey(
430     const std::string &key, std::unordered_map<std::string, std::string> &values, const int32_t &userId)
431 {
432     ANS_LOGD("QueryData BeginWithKey start");
433     std::vector<std::string> operatedTables = GenerateOperatedTables(userId);
434     std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
435     if (rdbStore_ == nullptr) {
436         ANS_LOGE("notification rdb is null");
437         return NativeRdb::E_ERROR;
438     }
439     int32_t ret = NativeRdb::E_OK;
440     for (auto tableName : operatedTables) {
441         ret = QueryDataBeginWithKey(tableName, key, values);
442         if (ret == NativeRdb::E_ERROR) {
443             return ret;
444         }
445     }
446     if (ret == NativeRdb::E_EMPTY_VALUES_BUCKET && values.empty()) {
447         return NativeRdb::E_EMPTY_VALUES_BUCKET;
448     }
449     return NativeRdb::E_OK;
450 }
451 
QueryDataBeginWithKey( const std::string tableName, const std::string key, std::unordered_map<std::string, std::string> &values)452 int32_t NotificationDataMgr::QueryDataBeginWithKey(
453     const std::string tableName, const std::string key, std::unordered_map<std::string, std::string> &values)
454 {
455     NativeRdb::AbsRdbPredicates absRdbPredicates(tableName);
456     absRdbPredicates.BeginsWith(NOTIFICATION_KEY, key);
457     auto absSharedResultSet = rdbStore_->Query(absRdbPredicates, std::vector<std::string>());
458     if (absSharedResultSet == nullptr) {
459         ANS_LOGE("absSharedResultSet failed from %{public}s table.", tableName.c_str());
460         return NativeRdb::E_ERROR;
461     }
462 
463     int32_t ret = absSharedResultSet->GoToFirstRow();
464     if (ret == NativeRdb::E_SQLITE_CORRUPT) {
465         RestoreForMasterSlaver();
466     }
467     if (ret != NativeRdb::E_OK) {
468         ANS_LOGD("GoToFirstRow failed from %{public}s table.It is empty!, key=%{public}s",
469             tableName.c_str(), key.c_str());
470         return NativeRdb::E_EMPTY_VALUES_BUCKET;
471     }
472 
473     do {
474         std::string resultKey;
475         ret = absSharedResultSet->GetString(NOTIFICATION_KEY_INDEX, resultKey);
476         if (ret != NativeRdb::E_OK) {
477             ANS_LOGE("Failed to GetString key from %{public}s table.", tableName.c_str());
478             return NativeRdb::E_ERROR;
479         }
480 
481         std::string resultValue;
482         ret = absSharedResultSet->GetString(NOTIFICATION_VALUE_INDEX, resultValue);
483         if (ret != NativeRdb::E_OK) {
484             ANS_LOGE("GetString value failed from %{public}s table", tableName.c_str());
485             return NativeRdb::E_ERROR;
486         }
487 
488         values.emplace(resultKey, resultValue);
489     } while (absSharedResultSet->GoToNextRow() == NativeRdb::E_OK);
490     absSharedResultSet->Close();
491 
492     return NativeRdb::E_OK;
493 }
494 
QueryAllData(std::unordered_map<std::string, std::string> &datas, const int32_t &userId)495 int32_t NotificationDataMgr::QueryAllData(std::unordered_map<std::string, std::string> &datas, const int32_t &userId)
496 {
497     ANS_LOGD("QueryAllData start");
498     std::vector<std::string> operatedTables = GenerateOperatedTables(userId);
499     std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
500     if (rdbStore_ == nullptr) {
501         ANS_LOGE("notification rdb is null");
502         return NativeRdb::E_ERROR;
503     }
504     int32_t ret = NativeRdb::E_OK;
505     for (auto tableName : operatedTables) {
506         ret = QueryAllData(tableName,  datas);
507         if (ret == NativeRdb::E_ERROR) {
508             return ret;
509         }
510     }
511     if (ret == NativeRdb::E_EMPTY_VALUES_BUCKET && datas.empty()) {
512         return NativeRdb::E_EMPTY_VALUES_BUCKET;
513     }
514     return NativeRdb::E_OK;
515 }
516 
QueryAllData( const std::string tableName, std::unordered_map<std::string, std::string> &datas)517 int32_t NotificationDataMgr::QueryAllData(
518     const std::string tableName, std::unordered_map<std::string, std::string> &datas)
519 {
520     NativeRdb::AbsRdbPredicates absRdbPredicates(tableName);
521     auto absSharedResultSet = rdbStore_->Query(absRdbPredicates, std::vector<std::string>());
522     if (absSharedResultSet == nullptr) {
523         ANS_LOGE("absSharedResultSet failed from %{public}s table.", tableName.c_str());
524         return NativeRdb::E_ERROR;
525     }
526 
527     int32_t ret = absSharedResultSet->GoToFirstRow();
528     if (ret == NativeRdb::E_SQLITE_CORRUPT) {
529         RestoreForMasterSlaver();
530     }
531     if (ret != NativeRdb::E_OK) {
532         ANS_LOGD("GoToFirstRow failed from %{public}s table. It is empty!", tableName.c_str());
533         return NativeRdb::E_EMPTY_VALUES_BUCKET;
534     }
535 
536     do {
537         std::string resultKey;
538         ret = absSharedResultSet->GetString(NOTIFICATION_KEY_INDEX, resultKey);
539         if (ret != NativeRdb::E_OK) {
540             ANS_LOGE("GetString key failed from %{public}s table.", tableName.c_str());
541             return NativeRdb::E_ERROR;
542         }
543 
544         std::string resultValue;
545         ret = absSharedResultSet->GetString(NOTIFICATION_VALUE_INDEX, resultValue);
546         if (ret != NativeRdb::E_OK) {
547             ANS_LOGE("GetString value failed from %{public}s table.", tableName.c_str());
548             return NativeRdb::E_ERROR;
549         }
550 
551         datas.emplace(resultKey, resultValue);
552     } while (absSharedResultSet->GoToNextRow() == NativeRdb::E_OK);
553     absSharedResultSet->Close();
554 
555     return NativeRdb::E_OK;
556 }
557 
DropUserTable(const int32_t userId)558 int32_t NotificationDataMgr::DropUserTable(const int32_t userId)
559 {
560     const char *keySpliter = "_";
561     std::stringstream stream;
562     stream << notificationRdbConfig_.tableName << keySpliter << userId;
563     std::string tableName = stream.str();
564     std::lock_guard<std::mutex> lock(createdTableMutex_);
565     int32_t ret = NativeRdb::E_OK;
566     {
567         std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
568         if (rdbStore_ == nullptr) {
569             return NativeRdb::E_ERROR;
570         }
571         std::string dropTableSql = "DROP TABLE IF EXISTS " + tableName;
572         ret = rdbStore_->ExecuteSql(dropTableSql);
573     }
574     if (ret == NativeRdb::E_OK) {
575         createdTables_.erase(tableName);
576         ANS_LOGD("drop Table %{public}s succeed", tableName.c_str());
577         return ret;
578     }
579     return ret;
580 }
581 
GetUserTableName(const int32_t &userId, std::string &tableName)582 int32_t NotificationDataMgr::GetUserTableName(const int32_t &userId, std::string &tableName)
583 {
584     if (!OsAccountManagerHelper::IsSystemAccount(userId)) {
585         tableName = notificationRdbConfig_.tableName;
586         return NativeRdb::E_OK;
587     }
588 
589     const char *keySpliter = "_";
590     std::stringstream stream;
591     stream << notificationRdbConfig_.tableName << keySpliter << userId;
592     tableName = stream.str();
593     if (createdTables_.find(tableName) == createdTables_.end()) {
594         std::lock_guard<std::mutex> lock(createdTableMutex_);
595         if (createdTables_.find(tableName) == createdTables_.end()) {
596             std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
597             if (rdbStore_ == nullptr) {
598                 return NativeRdb::E_ERROR;
599             }
600             std::string createTableSql = "CREATE TABLE IF NOT EXISTS " + tableName
601                 + " (KEY TEXT NOT NULL PRIMARY KEY, VALUE TEXT NOT NULL);";
602             int32_t ret = rdbStore_->ExecuteSql(createTableSql);
603             if (ret != NativeRdb::E_OK) {
604                 ANS_LOGW("createTable %{public}s failed, code: %{code}d", tableName.c_str(), ret);
605                 return ret;
606             }
607             createdTables_.insert(tableName);
608             ANS_LOGD("createTable %{public}s succeed", tableName.c_str());
609             return NativeRdb::E_OK;
610         }
611     }
612     return NativeRdb::E_OK;
613 }
614 
GenerateOperatedTables(const int32_t &userId)615 std::vector<std::string> NotificationDataMgr::GenerateOperatedTables(const int32_t &userId)
616 {
617     std::vector<std::string> operatedTables;
618     if (OsAccountManagerHelper::IsSystemAccount(userId)) {
619         const char *keySpliter = "_";
620         std::stringstream stream;
621         stream << notificationRdbConfig_.tableName << keySpliter << userId;
622         std::string tableName = stream.str();
623         std::lock_guard<std::mutex> lock(createdTableMutex_);
624         if (createdTables_.find(tableName) != createdTables_.end()) {
625             operatedTables.emplace_back(tableName);
626         }
627     }
628     operatedTables.emplace_back(notificationRdbConfig_.tableName);
629     return operatedTables;
630 }
631 
RestoreForMasterSlaver()632 int32_t NotificationDataMgr::RestoreForMasterSlaver()
633 {
634     ANS_LOGI("RestoreForMasterSlaver start");
635     int32_t result =  rdbStore_->Restore("");
636     ANS_LOGI("RestoreForMasterSlaver result = %{public}d", result);
637     return result;
638 }
639 }
640 }