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