1 /*
2 * Copyright (c) 2022 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
16 #include "reminder_store.h"
17
18 #include <filesystem>
19 #include <sstream>
20 #include <sys/stat.h>
21 #include <unistd.h>
22
23 #include "ability_context.h"
24 #include "ans_log_wrapper.h"
25 #include "reminder_table.h"
26 #include "reminder_table_old.h"
27 #include "reminder_request_alarm.h"
28 #include "reminder_request_timer.h"
29 #include "reminder_request_calendar.h"
30 #include "reminder_store_strategy.h"
31
32 namespace OHOS {
33 namespace Notification {
34 namespace {
35 const int32_t REMINDER_RDB_VERSION_V1 = 1;
36 const int32_t REMINDER_RDB_VERSION_V2 = 2;
37 const int32_t REMINDER_RDB_VERSION_V3 = 3;
38 const int32_t REMINDER_RDB_VERSION_V4 = 4;
39 const int32_t REMINDER_RDB_VERSION_V5 = 5;
40 const int32_t REMINDER_RDB_VERSION_V6 = 6;
41 const int32_t REMINDER_RDB_VERSION = 7;
42 }
43
44 const int32_t ReminderStore::STATE_OK = 0;
45 const int32_t ReminderStore::STATE_FAIL = -1;
46 const std::string ReminderStore::REMINDER_DB_DIR = "/data/service/el1/public/notification/";
47 const std::string ReminderStore::REMINDER_DB_NAME = "notification.db";
48
OnCreate(NativeRdb::RdbStore & store)49 int32_t ReminderStore::ReminderStoreDataCallBack::OnCreate(NativeRdb::RdbStore& store)
50 {
51 ANSR_LOGI("Create table");
52 return CreateTable(store);
53 }
54
OnUpgrade(NativeRdb::RdbStore & store,int32_t oldVersion,int32_t newVersion)55 int32_t ReminderStore::ReminderStoreDataCallBack::OnUpgrade(
56 NativeRdb::RdbStore& store, int32_t oldVersion, int32_t newVersion)
57 {
58 ANSR_LOGI("OnUpgrade oldVersion is %{public}d, newVersion is %{public}d", oldVersion, newVersion);
59 if (oldVersion < newVersion && newVersion == REMINDER_RDB_VERSION) {
60 switch (oldVersion) {
61 case REMINDER_RDB_VERSION_V1:
62 AddRdbColum(store, ReminderTable::TABLE_NAME, "groupId", "TEXT", "''");
63 [[fallthrough]];
64 case REMINDER_RDB_VERSION_V2:
65 AddRdbColum(store, ReminderTable::TABLE_NAME, "custom_ring_uri", "TEXT", "''");
66 AddRdbColum(store, ReminderTable::TABLE_NAME, "snooze_slot_id", "INT", "3");
67 [[fallthrough]];
68 case REMINDER_RDB_VERSION_V3:
69 AddRdbColum(store, ReminderTable::TABLE_NAME, "creator_bundle_name", "TEXT", "''");
70 [[fallthrough]];
71 case REMINDER_RDB_VERSION_V4:
72 CreateTable(store);
73 CopyData(store);
74 [[fallthrough]];
75 case REMINDER_RDB_VERSION_V5:
76 AddRdbColum(store, ReminderBaseTable::TABLE_NAME, ReminderBaseTable::CREATOR_UID, "INT", "-1");
77 [[fallthrough]];
78 case REMINDER_RDB_VERSION_V6:
79 AddRdbColum(store, ReminderCalendarTable::TABLE_NAME,
80 ReminderCalendarTable::CALENDAR_LAST_DATE_TIME, "BIGINT", "0");
81 [[fallthrough]];
82 default:
83 break;
84 }
85 }
86 store.SetVersion(newVersion);
87 return NativeRdb::E_OK;
88 }
89
OnDowngrade(NativeRdb::RdbStore & store,int32_t currentVersion,int32_t targetVersion)90 int32_t ReminderStore::ReminderStoreDataCallBack::OnDowngrade(
91 NativeRdb::RdbStore& store, int32_t currentVersion, int32_t targetVersion)
92 {
93 ANSR_LOGI("OnDowngrade currentVersion is %{public}d, targetVersion is %{public}d", currentVersion, targetVersion);
94 if (currentVersion > targetVersion && targetVersion <= REMINDER_RDB_VERSION_V4) {
95 std::string createSql = "CREATE TABLE IF NOT EXISTS " + ReminderTable::TABLE_NAME + " ("
96 + ReminderTable::ADD_COLUMNS + ")";
97 int32_t ret = store.ExecuteSql(createSql);
98 if (ret != NativeRdb::E_OK) {
99 ANSR_LOGE("Create reminder table failed:%{public}d", ret);
100 }
101 return ret;
102 }
103 store.SetVersion(targetVersion);
104 return NativeRdb::E_OK;
105 }
106
CreateTable(NativeRdb::RdbStore & store)107 int32_t ReminderStore::ReminderStoreDataCallBack::CreateTable(NativeRdb::RdbStore& store)
108 {
109 std::string createSql = "CREATE TABLE IF NOT EXISTS " + ReminderBaseTable::TABLE_NAME + " ("
110 + ReminderBaseTable::ADD_COLUMNS + ")";
111 int32_t ret = store.ExecuteSql(createSql);
112 if (ret != NativeRdb::E_OK) {
113 ANSR_LOGE("Create reminder_base table failed:%{public}d", ret);
114 return ret;
115 }
116
117 createSql = "CREATE TABLE IF NOT EXISTS " + ReminderAlarmTable::TABLE_NAME + " ("
118 + ReminderAlarmTable::ADD_COLUMNS + ")";
119 ret = store.ExecuteSql(createSql);
120 if (ret != NativeRdb::E_OK) {
121 ANSR_LOGE("Create reminder_alarm table failed:%{public}d", ret);
122 return ret;
123 }
124
125 createSql = "CREATE TABLE IF NOT EXISTS " + ReminderCalendarTable::TABLE_NAME + " ("
126 + ReminderCalendarTable::ADD_COLUMNS + ")";
127 ret = store.ExecuteSql(createSql);
128 if (ret != NativeRdb::E_OK) {
129 ANSR_LOGE("Create reminder_calendar table failed:%{public}d", ret);
130 return ret;
131 }
132
133 createSql = "CREATE TABLE IF NOT EXISTS " + ReminderTimerTable::TABLE_NAME + " ("
134 + ReminderTimerTable::ADD_COLUMNS + ")";
135 ret = store.ExecuteSql(createSql);
136 if (ret != NativeRdb::E_OK) {
137 ANSR_LOGE("Create reminder_timer table failed:%{public}d", ret);
138 return ret;
139 }
140 return ret;
141 }
142
CopyData(NativeRdb::RdbStore & store)143 int32_t ReminderStore::ReminderStoreDataCallBack::CopyData(NativeRdb::RdbStore& store)
144 {
145 // select old data
146 auto reminders = GetOldReminders(store);
147 // insert new data
148 if (!reminders.empty()) {
149 InsertNewReminders(store, reminders);
150 }
151 // delete old table
152 std::string sql = "DELETE FROM " + ReminderTable::TABLE_NAME;
153 store.ExecuteSql(sql);
154 return NativeRdb::E_OK;
155 }
156
GetOldReminders(NativeRdb::RdbStore & store)157 std::vector<sptr<ReminderRequest>> ReminderStore::ReminderStoreDataCallBack::GetOldReminders(NativeRdb::RdbStore& store)
158 {
159 std::string sql = "SELECT " + ReminderTable::SELECT_COLUMNS + " FROM "
160 + ReminderTable::TABLE_NAME;
161 std::vector<sptr<ReminderRequest>> reminders;
162 std::vector<std::string> whereArgs;
163 auto queryResult = store.QuerySql(sql, whereArgs);
164 if (queryResult == nullptr) {
165 return reminders;
166 }
167
168 bool isLastRow = false;
169 queryResult->IsAtLastRow(isLastRow);
170 while (!isLastRow) {
171 queryResult->GoToNextRow();
172 int32_t reminderId;
173 int32_t reminderType;
174 GetInt32Val(queryResult, ReminderTable::REMINDER_ID, reminderId);
175 GetInt32Val(queryResult, ReminderTable::REMINDER_TYPE, reminderType);
176
177 sptr<ReminderRequest> reminderReq = nullptr;
178 switch (reminderType) {
179 case (static_cast<int32_t>(ReminderRequest::ReminderType::TIMER)): {
180 reminderReq = new (std::nothrow) ReminderRequestTimer(reminderId);
181 ReminderTimerStrategy::RecoverFromOldVersion(reminderReq, queryResult);
182 break;
183 }
184 case (static_cast<int32_t>(ReminderRequest::ReminderType::CALENDAR)): {
185 reminderReq = new (std::nothrow) ReminderRequestCalendar(reminderId);
186 ReminderCalendarStrategy::RecoverFromOldVersion(reminderReq, queryResult);
187 break;
188 }
189 case (static_cast<int32_t>(ReminderRequest::ReminderType::ALARM)): {
190 reminderReq = new (std::nothrow) ReminderRequestAlarm(reminderId);
191 ReminderAlarmStrategy::RecoverFromOldVersion(reminderReq, queryResult);
192 break;
193 }
194 default: {
195 break;
196 }
197 }
198 if (reminderReq != nullptr) {
199 reminders.push_back(reminderReq);
200 }
201 queryResult->IsAtLastRow(isLastRow);
202 }
203 return reminders;
204 }
205
InsertNewReminders(NativeRdb::RdbStore & store,const std::vector<sptr<ReminderRequest>> & reminders)206 void ReminderStore::ReminderStoreDataCallBack::InsertNewReminders(NativeRdb::RdbStore& store,
207 const std::vector<sptr<ReminderRequest>>& reminders)
208 {
209 for (auto reminder : reminders) {
210 int64_t rowId = STATE_FAIL;
211 sptr<NotificationBundleOption> bundleOption = new (std::nothrow) NotificationBundleOption();
212 if (bundleOption == nullptr) {
213 continue;
214 }
215 bundleOption->SetBundleName(reminder->GetBundleName());
216 NativeRdb::ValuesBucket baseValues;
217 ReminderStrategy::AppendValuesBucket(reminder, baseValues, true);
218
219 store.BeginTransaction();
220 // insert reminder_base
221 int32_t ret = store.Insert(rowId, ReminderBaseTable::TABLE_NAME, baseValues);
222 if (ret != NativeRdb::E_OK) {
223 ANSR_LOGE("Insert reminder_base operation failed, result: %{public}d, reminderId=%{public}d.",
224 ret, reminder->GetReminderId());
225 store.RollBack();
226 continue;
227 }
228
229 // insert reminder_alarm or reminder_calendar
230 NativeRdb::ValuesBucket values;
231 rowId = STATE_FAIL;
232 switch (reminder->GetReminderType()) {
233 case ReminderRequest::ReminderType::CALENDAR:
234 ReminderCalendarStrategy::AppendValuesBucket(reminder, values);
235 ret = store.Insert(rowId, ReminderCalendarTable::TABLE_NAME, values);
236 break;
237 case ReminderRequest::ReminderType::ALARM:
238 ReminderAlarmStrategy::AppendValuesBucket(reminder, values);
239 ret = store.Insert(rowId, ReminderAlarmTable::TABLE_NAME, values);
240 break;
241 case ReminderRequest::ReminderType::TIMER:
242 ReminderTimerStrategy::AppendValuesBucket(reminder, values);
243 ret = store.Insert(rowId, ReminderTimerTable::TABLE_NAME, values);
244 break;
245 default:
246 ANSR_LOGE("Insert reminder_base operation failed, unkown type.");
247 ret = STATE_FAIL;
248 break;
249 }
250 if (ret != NativeRdb::E_OK) {
251 ANSR_LOGE("Insert operation failed, result: %{public}d, reminderId=%{public}d.",
252 ret, reminder->GetReminderId());
253 store.RollBack();
254 continue;
255 }
256 store.Commit();
257 ANSR_LOGD("Insert successfully, reminderId=%{public}d.", reminder->GetReminderId());
258 }
259 }
260
AddRdbColum(NativeRdb::RdbStore & store,const std::string & tableName,const std::string & columnName,const std::string & columnType,const std::string & defValue)261 void ReminderStore::ReminderStoreDataCallBack::AddRdbColum(NativeRdb::RdbStore& store, const std::string& tableName,
262 const std::string& columnName, const std::string& columnType, const std::string& defValue)
263 {
264 std::string sqlStr = "";
265 sqlStr = "ALTER TABLE " + tableName + " ADD " + columnName + " " + columnType + " DEFAULT " + defValue + ";";
266 ANSR_LOGD("AddRdbColum sqlStr = %{public}s", sqlStr.c_str());
267 int errorCode = store.ExecuteSql(sqlStr);
268 if (errorCode != NativeRdb::E_OK) {
269 ANSR_LOGE("AddRdbColum error,errorCode is = %{public}d", errorCode);
270 }
271 }
272
Init()273 __attribute__((no_sanitize("cfi"))) int32_t ReminderStore::Init()
274 {
275 ANSR_LOGD("Reminder store init.");
276 if (access(REMINDER_DB_DIR.c_str(), F_OK) != 0) {
277 int createDir = mkdir(REMINDER_DB_DIR.c_str(), S_IRWXU);
278 if (createDir != 0) {
279 ANSR_LOGE("Failed to create directory %{private}s", REMINDER_DB_DIR.c_str());
280 return STATE_FAIL;
281 }
282 }
283
284 ReminderTable::InitDbColumns();
285 ReminderBaseTable::InitDbColumns();
286 ReminderTimerTable::InitDbColumns();
287 ReminderAlarmTable::InitDbColumns();
288 ReminderCalendarTable::InitDbColumns();
289
290 std::string dbConfig = REMINDER_DB_DIR + REMINDER_DB_NAME;
291 NativeRdb::RdbStoreConfig config(dbConfig);
292 config.SetSecurityLevel(NativeRdb::SecurityLevel::S1);
293
294 ReminderStoreDataCallBack rdbDataCallBack;
295 int32_t errCode = STATE_FAIL;
296 rdbStore_ = NativeRdb::RdbHelper::GetRdbStore(config, REMINDER_RDB_VERSION, rdbDataCallBack, errCode);
297 if (rdbStore_ == nullptr) {
298 ANSR_LOGE("ReminderStore init fail, errCode %{public}d.", errCode);
299 return STATE_FAIL;
300 }
301 return InitData();
302 }
303
Delete(const int32_t reminderId)304 __attribute__((no_sanitize("cfi"))) int32_t ReminderStore::Delete(const int32_t reminderId)
305 {
306 if (rdbStore_ == nullptr) {
307 ANSR_LOGE("Rdb store is not initialized.");
308 return STATE_FAIL;
309 }
310 std::string condition = ReminderBaseTable::REMINDER_ID + " = " + std::to_string(reminderId);
311 rdbStore_->BeginTransaction();
312 int32_t delRows = STATE_FAIL;
313 std::vector<std::string> whereArgs;
314 int32_t ret = rdbStore_->Delete(delRows, ReminderBaseTable::TABLE_NAME, condition, whereArgs);
315 if (ret != NativeRdb::E_OK) {
316 ANSR_LOGE("Delete from %{public}s failed, reminderId = %{public}d",
317 ReminderBaseTable::TABLE_NAME.c_str(), reminderId);
318 rdbStore_->RollBack();
319 return STATE_FAIL;
320 }
321 delRows = STATE_FAIL;
322 ret = rdbStore_->Delete(delRows, ReminderAlarmTable::TABLE_NAME, condition, whereArgs);
323 if (ret != NativeRdb::E_OK) {
324 ANSR_LOGE("Delete from %{public}s failed, reminderId = %{public}d",
325 ReminderAlarmTable::TABLE_NAME.c_str(), reminderId);
326 rdbStore_->RollBack();
327 return STATE_FAIL;
328 }
329 delRows = STATE_FAIL;
330 ret = rdbStore_->Delete(delRows, ReminderCalendarTable::TABLE_NAME, condition, whereArgs);
331 if (ret != NativeRdb::E_OK) {
332 ANSR_LOGE("Delete from %{public}s failed, reminderId = %{public}d",
333 ReminderCalendarTable::TABLE_NAME.c_str(), reminderId);
334 rdbStore_->RollBack();
335 return STATE_FAIL;
336 }
337 delRows = STATE_FAIL;
338 ret = rdbStore_->Delete(delRows, ReminderTimerTable::TABLE_NAME, condition, whereArgs);
339 if (ret != NativeRdb::E_OK) {
340 ANSR_LOGE("Delete from %{public}s failed, reminderId = %{public}d",
341 ReminderTimerTable::TABLE_NAME.c_str(), reminderId);
342 rdbStore_->RollBack();
343 return STATE_FAIL;
344 }
345 rdbStore_->Commit();
346 return STATE_OK;
347 }
348
Delete(const std::string & pkg,const int32_t userId,const int32_t uid)349 __attribute__((no_sanitize("cfi"))) int32_t ReminderStore::Delete(const std::string& pkg, const int32_t userId,
350 const int32_t uid)
351 {
352 std::string assoConditon = "(SELECT " + ReminderBaseTable::REMINDER_ID + " FROM " + ReminderBaseTable::TABLE_NAME
353 + " WHERE " + ReminderBaseTable::TABLE_NAME + "." + ReminderBaseTable::PACKAGE_NAME + " = '" + pkg
354 + "' AND " + ReminderBaseTable::TABLE_NAME + "." + ReminderBaseTable::USER_ID + " = " + std::to_string(userId);
355
356 std::string baseCondtion = ReminderBaseTable::PACKAGE_NAME + " = '" + pkg + "' AND "
357 + ReminderBaseTable::USER_ID + " = " + std::to_string(userId);
358
359 if (uid != -1) {
360 assoConditon += " AND " + ReminderBaseTable::TABLE_NAME + "." + ReminderBaseTable::UID
361 + " = " + std::to_string(uid);
362 baseCondtion += " AND " + ReminderBaseTable::UID + " = " + std::to_string(uid);
363 }
364 assoConditon += ")";
365 return Delete(baseCondtion, assoConditon);
366 }
367
DeleteUser(const int32_t userId)368 __attribute__((no_sanitize("cfi"))) int32_t ReminderStore::DeleteUser(const int32_t userId)
369 {
370 std::string assoConditon = "(SELECT " + ReminderBaseTable::REMINDER_ID + " FROM " + ReminderBaseTable::TABLE_NAME
371 + " WHERE " + ReminderBaseTable::TABLE_NAME + "." + ReminderBaseTable::USER_ID + " = "
372 + std::to_string(userId) + ")";
373
374 std::string baseCondtion = ReminderBaseTable::USER_ID + " = " + std::to_string(userId);
375 return Delete(baseCondtion, assoConditon);
376 }
377
UpdateOrInsert(const sptr<ReminderRequest> & reminder,const sptr<NotificationBundleOption> & bundleOption)378 int32_t ReminderStore::UpdateOrInsert(
379 const sptr<ReminderRequest>& reminder, const sptr<NotificationBundleOption>& bundleOption)
380 {
381 if (rdbStore_ == nullptr) {
382 ANSR_LOGE("Rdb store is not initialized.");
383 return STATE_FAIL;
384 }
385 if (bundleOption == nullptr) {
386 ANSR_LOGE("BundleOption is null.");
387 return STATE_FAIL;
388 }
389 if (IsReminderExist(reminder)) {
390 return Update(reminder, bundleOption);
391 } else {
392 return Insert(reminder, bundleOption);
393 }
394 }
395
GetMaxId()396 int32_t ReminderStore::GetMaxId()
397 {
398 if (rdbStore_ == nullptr) {
399 ANSR_LOGE("Rdb store is not initialized.");
400 return STATE_FAIL;
401 }
402 std::string queryCondition = "SELECT " + ReminderBaseTable::REMINDER_ID
403 + " FROM " + ReminderBaseTable::TABLE_NAME + " ORDER BY "
404 + ReminderBaseTable::REMINDER_ID + " DESC";
405 auto queryResultSet = Query(queryCondition);
406 if (queryResultSet == nullptr) {
407 ANSR_LOGE("QueryResultSet is null.");
408 return STATE_FAIL;
409 }
410 int32_t resultNum = 0;
411 queryResultSet->GetRowCount(resultNum);
412 if (resultNum == 0) {
413 ANSR_LOGI("QueryResultSet is zero.");
414 return STATE_FAIL;
415 }
416 queryResultSet->GoToNextRow();
417 int32_t maxId = STATE_FAIL;
418 int32_t result = queryResultSet->GetInt(0, maxId);
419 if (result != NativeRdb::E_OK) {
420 ANSR_LOGE("Query operation failed, result %{public}d.", result);
421 }
422 ANSR_LOGD("MaxId: %{public}d.", maxId);
423 return maxId;
424 }
425
GetAllValidReminders()426 __attribute__((no_sanitize("cfi"))) std::vector<sptr<ReminderRequest>> ReminderStore::GetAllValidReminders()
427 {
428 std::string sql = "SELECT " + ReminderBaseTable::SELECT_COLUMNS + " FROM "
429 + ReminderBaseTable::TABLE_NAME + " WHERE "
430 + ReminderBaseTable::IS_EXPIRED + " = 'false' ORDER BY "
431 + ReminderBaseTable::TRIGGER_TIME + " ASC";
432 ANSR_LOGD("GetAllValidReminders sql =%{public}s", sql.c_str());
433 return GetReminders(sql);
434 }
435
GetUInt8Val(const std::shared_ptr<NativeRdb::ResultSet> & resultSet,const std::string & name,uint8_t & value)436 void ReminderStore::GetUInt8Val(const std::shared_ptr<NativeRdb::ResultSet>& resultSet,
437 const std::string& name, uint8_t& value)
438 {
439 int32_t val;
440 GetInt32Val(resultSet, name, val);
441 value = static_cast<uint8_t>(val);
442 }
443
GetUInt16Val(const std::shared_ptr<NativeRdb::ResultSet> & resultSet,const std::string & name,uint16_t & value)444 void ReminderStore::GetUInt16Val(const std::shared_ptr<NativeRdb::ResultSet>& resultSet,
445 const std::string& name, uint16_t& value)
446 {
447 int32_t val;
448 GetInt32Val(resultSet, name, val);
449 value = static_cast<uint16_t>(val);
450 }
451
GetInt32Val(const std::shared_ptr<NativeRdb::ResultSet> & resultSet,const std::string & name,int32_t & value)452 void ReminderStore::GetInt32Val(const std::shared_ptr<NativeRdb::ResultSet>& resultSet,
453 const std::string& name, int32_t& value)
454 {
455 value = 0;
456 int32_t columnIndex = -1;
457 resultSet->GetColumnIndex(name, columnIndex);
458 if (columnIndex == -1) {
459 ANSR_LOGE("the column %{public}s does not exsit.", name.c_str());
460 return;
461 }
462 resultSet->GetInt(columnIndex, value);
463 }
464
GetInt64Val(const std::shared_ptr<NativeRdb::ResultSet> & resultSet,const std::string & name,int64_t & value)465 void ReminderStore::GetInt64Val(const std::shared_ptr<NativeRdb::ResultSet>& resultSet,
466 const std::string& name, int64_t& value)
467 {
468 value = 0;
469 int32_t columnIndex = -1;
470 resultSet->GetColumnIndex(name, columnIndex);
471 if (columnIndex == -1) {
472 ANSR_LOGE("the column %{public}s does not exsit.", name.c_str());
473 return;
474 }
475 resultSet->GetLong(columnIndex, value);
476 }
477
GetUInt64Val(const std::shared_ptr<NativeRdb::ResultSet> & resultSet,const std::string & name,uint64_t & value)478 void ReminderStore::GetUInt64Val(const std::shared_ptr<NativeRdb::ResultSet>& resultSet,
479 const std::string& name, uint64_t& value)
480 {
481 int64_t val;
482 GetInt64Val(resultSet, name, val);
483 value = static_cast<uint64_t>(val);
484 }
485
GetStringVal(const std::shared_ptr<NativeRdb::ResultSet> & resultSet,const std::string & name,std::string & value)486 void ReminderStore::GetStringVal(const std::shared_ptr<NativeRdb::ResultSet>& resultSet,
487 const std::string& name, std::string& value)
488 {
489 int32_t columnIndex = -1;
490 resultSet->GetColumnIndex(name, columnIndex);
491 if (columnIndex == -1) {
492 ANSR_LOGE("the column %{public}s does not exsit.", name.c_str());
493 return;
494 }
495 resultSet->GetString(columnIndex, value);
496 }
497
InitData()498 __attribute__((no_sanitize("cfi"))) int32_t ReminderStore::InitData()
499 {
500 ANSR_LOGD("Reminder data init.");
501 if (rdbStore_ == nullptr) {
502 ANSR_LOGE("Rdb store is not initialized.");
503 return STATE_FAIL;
504 }
505 // delete all the reminders which IS_EXPIRED is true.
506 std::string deleteCondition = ReminderBaseTable::IS_EXPIRED + " is true";
507 DeleteBase(deleteCondition);
508
509 // set all the value of STATE to ReminderRequest::REMINDER_STATUS_INACTIVE
510 NativeRdb::ValuesBucket statusValues;
511 statusValues.PutInt(ReminderBaseTable::STATE, ReminderRequest::REMINDER_STATUS_INACTIVE);
512 int32_t statusChangedRows = STATE_FAIL;
513 int32_t ret = rdbStore_->Update(statusChangedRows, ReminderBaseTable::TABLE_NAME, statusValues);
514 ANSR_LOGD("Change status to inactive, changed rows: %{public}d.", statusChangedRows);
515 if (ret != NativeRdb::E_OK) {
516 ANSR_LOGE("Init data failed.");
517 return STATE_FAIL;
518 }
519 return STATE_OK;
520 }
521
DeleteBase(const std::string & deleteCondition)522 __attribute__((no_sanitize("cfi"))) int32_t ReminderStore::DeleteBase(const std::string& deleteCondition)
523 {
524 if (rdbStore_ == nullptr) {
525 ANSR_LOGE("Rdb store is not initialized.");
526 return STATE_FAIL;
527 }
528 int32_t deletedRows = STATE_FAIL;
529 std::vector<std::string> whereArgs;
530 int32_t ret = rdbStore_->Delete(deletedRows, ReminderBaseTable::TABLE_NAME, deleteCondition, whereArgs);
531 if (ret != NativeRdb::E_OK) {
532 ANSR_LOGE("Delete operation failed, deleteConditon: %{public}s," \
533 "result: %{public}d.", deleteCondition.c_str(), ret);
534 }
535 ANSR_LOGD("Delete operation done, deleteConditon: %{public}s," \
536 "deleted rows: %{public}d.", deleteCondition.c_str(), deletedRows);
537 return deletedRows;
538 }
539
Delete(const std::string & baseCondition,const std::string & assoConditon)540 __attribute__((no_sanitize("cfi"))) int32_t ReminderStore::Delete(const std::string& baseCondition,
541 const std::string& assoConditon)
542 {
543 if (rdbStore_ == nullptr) {
544 ANSR_LOGE("Rdb store is not initialized.");
545 return STATE_FAIL;
546 }
547 rdbStore_->BeginTransaction();
548 // delete reminder_calendar
549 std::string sql = "DELETE FROM " + ReminderCalendarTable::TABLE_NAME + " WHERE "
550 + ReminderCalendarTable::TABLE_NAME + "." + ReminderCalendarTable::REMINDER_ID
551 + " IN " + assoConditon;
552 int32_t ret = rdbStore_->ExecuteSql(sql);
553 if (ret != NativeRdb::E_OK) {
554 ANSR_LOGE("Delete from %{public}s failed", ReminderCalendarTable::TABLE_NAME.c_str());
555 rdbStore_->RollBack();
556 return STATE_FAIL;
557 }
558
559 // delete reminder_alarm
560 sql = "DELETE FROM " + ReminderAlarmTable::TABLE_NAME + " WHERE "
561 + ReminderAlarmTable::TABLE_NAME + "." + ReminderAlarmTable::REMINDER_ID
562 + " IN " + assoConditon;
563 ret = rdbStore_->ExecuteSql(sql);
564 if (ret != NativeRdb::E_OK) {
565 ANSR_LOGE("Delete from %{public}s failed", ReminderCalendarTable::TABLE_NAME.c_str());
566 rdbStore_->RollBack();
567 return STATE_FAIL;
568 }
569
570 // delete reminder_timer
571 sql = "DELETE FROM " + ReminderTimerTable::TABLE_NAME + " WHERE "
572 + ReminderTimerTable::TABLE_NAME + "." + ReminderTimerTable::REMINDER_ID
573 + " IN " + assoConditon;
574 ret = rdbStore_->ExecuteSql(sql);
575 if (ret != NativeRdb::E_OK) {
576 ANSR_LOGE("Delete from %{public}s failed", ReminderTimerTable::TABLE_NAME.c_str());
577 rdbStore_->RollBack();
578 return STATE_FAIL;
579 }
580
581 // delete reminder_base
582 sql = "DELETE FROM " + ReminderBaseTable::TABLE_NAME + " WHERE " + baseCondition;
583 ret = rdbStore_->ExecuteSql(sql);
584 if (ret != NativeRdb::E_OK) {
585 ANSR_LOGE("Delete from %{public}s failed", ReminderCalendarTable::TABLE_NAME.c_str());
586 rdbStore_->RollBack();
587 return STATE_FAIL;
588 }
589 rdbStore_->Commit();
590 return STATE_OK;
591 }
592
Insert(const sptr<ReminderRequest> & reminder,const sptr<NotificationBundleOption> & bundleOption)593 int32_t ReminderStore::Insert(
594 const sptr<ReminderRequest>& reminder, const sptr<NotificationBundleOption>& bundleOption)
595 {
596 if (rdbStore_ == nullptr) {
597 ANSR_LOGE("Rdb store is not initialized.");
598 return STATE_FAIL;
599 }
600 int64_t rowId = STATE_FAIL;
601 NativeRdb::ValuesBucket baseValues;
602 ReminderStrategy::AppendValuesBucket(reminder, baseValues);
603
604 rdbStore_->BeginTransaction();
605 // insert reminder_base
606 int32_t ret = rdbStore_->Insert(rowId, ReminderBaseTable::TABLE_NAME, baseValues);
607 if (ret != NativeRdb::E_OK) {
608 ANSR_LOGE("Insert reminder_base operation failed, result: %{public}d, reminderId=%{public}d.",
609 ret, reminder->GetReminderId());
610 rdbStore_->RollBack();
611 return STATE_FAIL;
612 }
613
614 // insert reminder_alarm or reminder_calendar
615 NativeRdb::ValuesBucket values;
616 rowId = STATE_FAIL;
617 switch (reminder->GetReminderType()) {
618 case ReminderRequest::ReminderType::CALENDAR: {
619 ReminderCalendarStrategy::AppendValuesBucket(reminder, values);
620 ret = rdbStore_->Insert(rowId, ReminderCalendarTable::TABLE_NAME, values);
621 break;
622 }
623 case ReminderRequest::ReminderType::ALARM: {
624 ReminderAlarmStrategy::AppendValuesBucket(reminder, values);
625 ret = rdbStore_->Insert(rowId, ReminderAlarmTable::TABLE_NAME, values);
626 break;
627 }
628 case ReminderRequest::ReminderType::TIMER: {
629 ReminderTimerStrategy::AppendValuesBucket(reminder, values);
630 ret = rdbStore_->Insert(rowId, ReminderTimerTable::TABLE_NAME, values);
631 break;
632 }
633 default: {
634 ANSR_LOGE("Insert reminder_base operation failed, unkown type.");
635 ret = STATE_FAIL;
636 break;
637 }
638 }
639 if (ret != NativeRdb::E_OK) {
640 ANSR_LOGE("Insert operation failed, result: %{public}d, reminderId=%{public}d.",
641 ret, reminder->GetReminderId());
642 rdbStore_->RollBack();
643 return STATE_FAIL;
644 }
645 rdbStore_->Commit();
646 ANSR_LOGD("Insert successfully, reminderId=%{public}d.", reminder->GetReminderId());
647 return STATE_OK;
648 }
649
Update(const sptr<ReminderRequest> & reminder,const sptr<NotificationBundleOption> & bundleOption)650 int32_t ReminderStore::Update(
651 const sptr<ReminderRequest>& reminder, const sptr<NotificationBundleOption>& bundleOption)
652 {
653 if (rdbStore_ == nullptr) {
654 ANSR_LOGE("Rdb store is not initialized.");
655 return STATE_FAIL;
656 }
657 int32_t rowId = STATE_FAIL;
658 NativeRdb::ValuesBucket baseValues;
659 ReminderStrategy::AppendValuesBucket(reminder, baseValues);
660
661 std::string updateCondition = ReminderBaseTable::REMINDER_ID
662 + " = " + std::to_string(reminder->GetReminderId());
663
664 rdbStore_->BeginTransaction();
665 // update reminder_base
666 std::vector<std::string> whereArgs;
667 int32_t ret = rdbStore_->Update(rowId, ReminderBaseTable::TABLE_NAME, baseValues, updateCondition, whereArgs);
668 if (ret != NativeRdb::E_OK) {
669 ANSR_LOGE("Update reminder_base operation failed, result: %{public}d, reminderId=%{public}d.",
670 ret, reminder->GetReminderId());
671 rdbStore_->RollBack();
672 return STATE_FAIL;
673 }
674
675 // update reminder_alarm or reminder_calendar
676 NativeRdb::ValuesBucket values;
677 rowId = STATE_FAIL;
678 switch (reminder->GetReminderType()) {
679 case ReminderRequest::ReminderType::CALENDAR:
680 ReminderCalendarStrategy::AppendValuesBucket(reminder, values);
681 ret = rdbStore_->Update(rowId, ReminderCalendarTable::TABLE_NAME, values, updateCondition, whereArgs);
682 break;
683 case ReminderRequest::ReminderType::ALARM:
684 ReminderAlarmStrategy::AppendValuesBucket(reminder, values);
685 ret = rdbStore_->Update(rowId, ReminderAlarmTable::TABLE_NAME, values, updateCondition, whereArgs);
686 break;
687 case ReminderRequest::ReminderType::TIMER:
688 ReminderTimerStrategy::AppendValuesBucket(reminder, values);
689 ret = rdbStore_->Update(rowId, ReminderTimerTable::TABLE_NAME, values, updateCondition, whereArgs);
690 break;
691 default:
692 ANSR_LOGE("Insert reminder_base operation failed, unkown type.");
693 ret = STATE_FAIL;
694 break;
695 }
696 if (ret != NativeRdb::E_OK) {
697 ANSR_LOGE("Update operation failed, result: %{public}d, reminderId=%{public}d.",
698 ret, reminder->GetReminderId());
699 rdbStore_->RollBack();
700 return STATE_FAIL;
701 }
702 rdbStore_->Commit();
703 ANSR_LOGD("Update successfully, reminderId=%{public}d.", reminder->GetReminderId());
704 return STATE_OK;
705 }
706
IsReminderExist(const sptr<ReminderRequest> & reminder)707 bool ReminderStore::IsReminderExist(const sptr<ReminderRequest>& reminder)
708 {
709 NativeRdb::AbsRdbPredicates absRdbPredicates(ReminderBaseTable::TABLE_NAME);
710 absRdbPredicates.EqualTo(ReminderBaseTable::REMINDER_ID, std::to_string(reminder->GetReminderId()));
711 auto queryResultSet = rdbStore_->Query(absRdbPredicates, std::vector<std::string>());
712 if (queryResultSet == nullptr) {
713 ANSR_LOGE("QueryResultSet is null.");
714 return false;
715 }
716 int32_t resultNum;
717 queryResultSet->GetRowCount(resultNum);
718 return resultNum != 0;
719 }
720
GetReminders(const std::string & queryCondition)721 std::vector<sptr<ReminderRequest>> ReminderStore::GetReminders(const std::string& queryCondition)
722 {
723 std::vector<sptr<ReminderRequest>> reminders;
724 if (rdbStore_ == nullptr) {
725 ANSR_LOGE("Rdb store is not initialized.");
726 return reminders;
727 }
728 auto queryResultSet = Query(queryCondition);
729 if (queryResultSet == nullptr) {
730 return reminders;
731 }
732 bool isAtLastRow = false;
733 int32_t ret = queryResultSet->IsAtLastRow(isAtLastRow);
734 while (ret == NativeRdb::E_OK && !isAtLastRow) {
735 queryResultSet->GoToNextRow();
736 sptr<ReminderRequest> reminder = BuildReminder(queryResultSet);
737 if (reminder != nullptr) {
738 reminders.push_back(reminder);
739 }
740 ret = queryResultSet->IsAtLastRow(isAtLastRow);
741 }
742 ANSR_LOGD("Size=%{public}zu", reminders.size());
743 return reminders;
744 }
745
BuildReminder(const std::shared_ptr<NativeRdb::ResultSet> & resultBase)746 sptr<ReminderRequest> ReminderStore::BuildReminder(const std::shared_ptr<NativeRdb::ResultSet>& resultBase)
747 {
748 int32_t reminderId;
749 int32_t reminderType;
750 GetInt32Val(resultBase, ReminderBaseTable::REMINDER_ID, reminderId);
751 GetInt32Val(resultBase, ReminderBaseTable::REMINDER_TYPE, reminderType);
752
753 sptr<ReminderRequest> reminder = nullptr;
754 std::shared_ptr<NativeRdb::ResultSet> resultSet;
755 switch (reminderType) {
756 case (static_cast<int32_t>(ReminderRequest::ReminderType::TIMER)): {
757 reminder = new (std::nothrow) ReminderRequestTimer(reminderId);
758 resultSet = Query(ReminderTimerTable::TABLE_NAME, ReminderTimerTable::SELECT_COLUMNS, reminderId);
759 ReminderTimerStrategy::RecoverFromDb(reminder, resultBase, resultSet);
760 break;
761 }
762 case (static_cast<int32_t>(ReminderRequest::ReminderType::CALENDAR)): {
763 reminder = new (std::nothrow) ReminderRequestCalendar(reminderId);
764 resultSet = Query(ReminderCalendarTable::TABLE_NAME, ReminderCalendarTable::SELECT_COLUMNS, reminderId);
765 ReminderCalendarStrategy::RecoverFromDb(reminder, resultBase, resultSet);
766 break;
767 }
768 case (static_cast<int32_t>(ReminderRequest::ReminderType::ALARM)): {
769 reminder = new (std::nothrow) ReminderRequestAlarm(reminderId);
770 resultSet = Query(ReminderAlarmTable::TABLE_NAME, ReminderAlarmTable::SELECT_COLUMNS, reminderId);
771 ReminderAlarmStrategy::RecoverFromDb(reminder, resultBase, resultSet);
772 break;
773 }
774 default: {
775 ANSR_LOGE("ReminderType from database is error, reminderType %{public}d.", reminderType);
776 break;
777 }
778 }
779 if (reminder != nullptr) {
780 ANSR_LOGI("BuildReminder success.");
781 } else {
782 ANSR_LOGW("BuildReminder fail.");
783 }
784 return reminder;
785 }
786
Query(const std::string & tableName,const std::string & colums,const int32_t reminderId)787 std::shared_ptr<NativeRdb::ResultSet> ReminderStore::Query(const std::string& tableName, const std::string& colums,
788 const int32_t reminderId)
789 {
790 if (rdbStore_ == nullptr) {
791 ANSR_LOGE("Rdb store is not initialized.");
792 return nullptr;
793 }
794 std::string queryCondition = "SELECT " + colums + " FROM " + tableName
795 + " WHERE " + ReminderBaseTable::REMINDER_ID + " = " + std::to_string(reminderId);
796 auto queryResultSet = Query(queryCondition);
797 if (queryResultSet == nullptr) {
798 return nullptr;
799 }
800 int32_t resultNum = 0;
801 queryResultSet->GetRowCount(resultNum);
802 if (resultNum == 0) {
803 return nullptr;
804 }
805 queryResultSet->GoToNextRow();
806 return queryResultSet;
807 }
808
Query(const std::string & queryCondition) const809 std::shared_ptr<NativeRdb::ResultSet> ReminderStore::Query(const std::string& queryCondition) const
810 {
811 if (rdbStore_ == nullptr) {
812 ANSR_LOGE("Rdb store is not initialized.");
813 return nullptr;
814 }
815 std::vector<std::string> whereArgs;
816 return rdbStore_->QuerySql(queryCondition, whereArgs);
817 }
818 } // namespace Notification
819 } // namespace OHOS
820