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