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 ¬ificationRdbConfig): 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 ¬ificationRdbConfig)
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 }