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