1/** 2 * @file Describe the file 3 * Copyright (c) 2023 Huawei Device Co., Ltd. 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17import data_rdb from '@ohos.data.relationalStore'; 18import dataSharePredicates from '@ohos.data.dataSharePredicates'; 19import DataShareResultSet from '@ohos.data.DataShareResultSet'; 20 21import { sendBroadcast } from '@ohos/common/src/main/ets/broadcast/BroadcastHelper'; 22import { Log } from '@ohos/common/src/main/ets/utils/Log'; 23import { 24 getCurrentTimeZoneMillisecond, 25 MILLS_PER_MINUTE, 26 MILLS_PER_HOUR, 27 MILLS_PER_DAY, 28 MILLS_PER_WEEK 29} from '@ohos/common/src/main/ets/utils/TimeUtils'; 30import { getBundleNameByUri } from '@ohos/common/src/main/ets/utils/UrlUtils'; 31 32import { CalendarAccountType } from '@ohos/datastructure/src/main/ets/calendars/CalendarAccountType'; 33import { CalendarAlerts } from '@ohos/datastructure/src/main/ets/calendaralerts/CalendarAlerts'; 34import { parseCalendarAlerts } from '@ohos/datastructure/src/main/ets/calendaralerts/CalendarAlertsParser'; 35import { CalendarAlertStateType } from '@ohos/datastructure/src/main/ets/calendaralerts/CalendarAlertStateType'; 36import { CalendarAlertsColumns } from '@ohos/datastructure/src/main/ets/calendaralerts/CalendarAlertsColumns'; 37import { CalendarAlertsIndexes } from '@ohos/datastructure/src/main/ets/calendaralerts/CalendarAlertsIndexes'; 38import { CalendarsColumns } from '@ohos/datastructure/src/main/ets/calendars/CalendarsColumns'; 39import { EventColumns } from '@ohos/datastructure/src/main/ets/events/EventColumns'; 40import { parseEvents } from '@ohos/datastructure/src/main/ets/events/EventParser'; 41import { Events } from '@ohos/datastructure/src/main/ets/events/Events'; 42import { EventIndexes, parseIndexes } from '@ohos/datastructure/src/main/ets/events/EventIndexes'; 43import { InstancesColumns } from '@ohos/datastructure/src/main/ets/instances/InstancesColumns'; 44import { ReminderMethodType } from '@ohos/datastructure/src/main/ets/reminders/ReminderMethodType'; 45import { RemindersColumns } from '@ohos/datastructure/src/main/ets/reminders/RemindersColumns'; 46 47import { CommonEventConstants } from '../../commonevents/CommonEventConstants'; 48import { DefaultProcessor } from '../DefaultProcessor'; 49import { ErrorCode } from '../../constants/ErrorCode'; 50import { notifyEventReminder } from '../../commonevents/notify/ScheduleAlarmNotifier'; 51import CalendarDataHelper from '../../utils/CalendarDataHelper'; 52import { acquireExpandAll } from '../instances/InstancesProcessor'; 53import { initValueCreator, initPredicateCreator, deleteValueCreator } from '../DatabaseProcessorHelper'; 54 55const TAG = 'AlertsProcessor'; 56 57const SCHEDULE_ALARM_SLACK = 2 * MILLS_PER_HOUR; 58 59const CLEAR_OLD_ALARM_THRESHOLD = MILLS_PER_WEEK + SCHEDULE_ALARM_SLACK; 60 61const ALLDAY_EVENT_ALARM_TIME = 9 * MILLS_PER_HOUR; 62 63const INVALIDATE_TIME_MILLIS = -1; 64 65const INVALID_CALENDARALERTS_SELECTOR = `SELECT ca.${CalendarAlertsColumns.ID} FROM ` 66+ `${CalendarAlertsColumns.TABLE_NAME} AS ca LEFT OUTER JOIN ${InstancesColumns.TABLE_NAME} USING ` 67+ `(${InstancesColumns.EVENT_ID},${InstancesColumns.BEGIN},${InstancesColumns.END}) LEFT OUTER JOIN ` 68+ `${RemindersColumns.TABLE_NAME} AS r ON (ca.${CalendarAlertsColumns.EVENT_ID}=r.${RemindersColumns.EVENT_ID} AND ` 69+ `ca.${CalendarAlertsColumns.MINUTES}=r.${RemindersColumns.MINUTES}) LEFT OUTER JOIN ` 70+ `(${EventColumns.TABLE_NAME} AS e JOIN ${CalendarsColumns.TABLE_NAME} AS c ON (e.${EventColumns.CALENDAR_ID}=` 71+ `c.${CalendarsColumns.ID})) ON (ca.${CalendarAlertsColumns.EVENT_ID}=e.${EventColumns.ID}) WHERE ` 72+ `${InstancesColumns.TABLE_NAME}.${InstancesColumns.BEGIN} ISNULL OR ca.${CalendarAlertsColumns.ALARM_TIME}<? OR ` 73+ `(r.${RemindersColumns.MINUTES} ISNULL AND ca.${CalendarAlertsColumns.MINUTES}<>0) OR ` 74+ `c.${CalendarsColumns.CAN_REMINDER}=0 OR c.${CalendarsColumns.VISIBLE}=0`; 75 76const SINGLE_REMINDERS_SELECTOR = `select min ( ${RemindersColumns.ID} ) as _id FROM ${RemindersColumns.TABLE_NAME} ` 77+ `group by ${RemindersColumns.EVENT_ID},${RemindersColumns.MINUTES},${RemindersColumns.METHOD}`; 78 79const ALL_DAY_SUB_QUERY_PREFIX = `SELECT (CASE WHEN ` 80+ `${CalendarsColumns.ACCOUNT_TYPE}='${CalendarAccountType.BIRTHDAY_ACCOUNT_TYPE}' THEN ` 81+ `${InstancesColumns.BEGIN} -? -(${RemindersColumns.MINUTES}*${MILLS_PER_MINUTE}) ELSE ` 82+ `${InstancesColumns.BEGIN} -? + (${ALLDAY_EVENT_ALARM_TIME}) -` 83+ `(${RemindersColumns.MINUTES}*${MILLS_PER_MINUTE}) END)`; 84 85const SUB_QUERY_PREFIX = `SELECT ${InstancesColumns.BEGIN} -(${RemindersColumns.MINUTES}*${MILLS_PER_MINUTE})`; 86 87const SUB_QUERY_SUFFIX = ` AS alertAlarmTime,${InstancesColumns.TABLE_NAME}.${InstancesColumns.EVENT_ID} AS eventId, ` 88+ `${EventColumns.TABLE_NAME}.${EventColumns.CREATOR} AS ${EventColumns.CREATOR}, ` 89+ `${InstancesColumns.BEGIN},${InstancesColumns.END},${CalendarsColumns.TABLE_NAME}.account_type AS account_type,` 90+ `${EventColumns.TITLE},${EventColumns.ALLDAY},${RemindersColumns.METHOD},${RemindersColumns.MINUTES} FROM ` 91+ `${InstancesColumns.TABLE_NAME} INNER JOIN (${EventColumns.TABLE_NAME} JOIN ${CalendarsColumns.TABLE_NAME} ON ` 92+ `(${EventColumns.TABLE_NAME}.${EventColumns.CALENDAR_ID}=${CalendarsColumns.TABLE_NAME}.${CalendarsColumns.ID})) ON ` 93+ `(${EventColumns.TABLE_NAME}.${EventColumns.ID}=${InstancesColumns.TABLE_NAME}.${InstancesColumns.EVENT_ID}) ` 94+ `INNER JOIN ${RemindersColumns.TABLE_NAME} ON (${InstancesColumns.TABLE_NAME}.${InstancesColumns.EVENT_ID}=` 95+ `${RemindersColumns.TABLE_NAME}.${RemindersColumns.EVENT_ID}) WHERE ${CalendarsColumns.VISIBLE}=1 AND ` 96+ `${CalendarsColumns.CAN_REMINDER}=1 AND alertAlarmTime>=CAST(? AS INT) AND alertAlarmTime<=CAST(? AS INT) AND ` 97+ `${InstancesColumns.END}>=? AND ${RemindersColumns.METHOD}=${ReminderMethodType.METHOD_ALERT}`; 98 99const ALL_DAY_QUERY = `${ALL_DAY_SUB_QUERY_PREFIX} ${SUB_QUERY_SUFFIX} AND ${EventColumns.ALLDAY}=1`; 100 101const NO_ALL_DAY_QUERY = `${SUB_QUERY_PREFIX} ${SUB_QUERY_SUFFIX} AND ${EventColumns.ALLDAY}=0`; 102 103const ALERT_GENERATE_QUERY = `SELECT * FROM (${ALL_DAY_QUERY} UNION ALL ${NO_ALL_DAY_QUERY}) WHERE 0=(SELECT count(*) FROM ` 104+ `${CalendarAlertsColumns.TABLE_NAME} CA WHERE CA.${CalendarAlertsColumns.EVENT_ID}=eventId AND ` 105+ `CA.${CalendarAlertsColumns.BEGIN}=${InstancesColumns.BEGIN} AND ` 106+ `CA.${CalendarAlertsColumns.ALARM_TIME}=alertAlarmTime) ` 107+ `ORDER BY alertAlarmTime,${InstancesColumns.BEGIN},${EventColumns.TITLE}`; 108 109/** 110 * the AlertsProcessor table processor 111 * 112 * @since 2022-10-25 113 */ 114export class AlertsProcessor extends DefaultProcessor { 115 async insertByHighAuthority(rdbStore, uri: string, values, callback) { 116 const callerName = getBundleNameByUri(uri); 117 initValueCreator(values, callerName); 118 const isEventExist = await isEventSameWithAlertId(rdbStore, values); 119 if (isEventExist) { 120 this.doInsert(rdbStore, uri, values, callback); 121 } else { 122 Log.warn(TAG, 'not support insert operation'); 123 const err = { 124 code: ErrorCode.UN_SUPPORT_OPERATION, 125 name: 'UnSupportedOperationException', 126 message: 'The calling application cannot insert an reminder without its own event' 127 }; 128 callback(err, -1); 129 } 130 } 131 132 async insertByLowAuthority(rdbStore, uri: string, values, callback) { 133 const callerName = getBundleNameByUri(uri); 134 initValueCreator(values, callerName); 135 const isEventCreatorExist = await isEventSameWithAlertCreator(rdbStore, values); 136 if (isEventCreatorExist) { 137 this.doInsert(rdbStore, uri, values, callback); 138 } else { 139 Log.warn(TAG, 'not support insert operation'); 140 const err = { 141 code: ErrorCode.UN_SUPPORT_OPERATION, 142 name: 'UnSupportedOperationException', 143 message: 'The calling application cannot insert an reminder with different creator from event' 144 }; 145 callback(err, -1); 146 } 147 } 148 149 async deleteByLowAuthority(rdbStore, uri: string, predicates, callback) { 150 const callerName = getBundleNameByUri(uri); 151 initPredicateCreator(predicates, callerName); 152 this.doDelete(rdbStore, uri, predicates, callback); 153 } 154 155 async updateByHighAuthority(rdbStore, uri: string, values, predicates, callback) { 156 deleteValueCreator(values); 157 this.doUpdate(rdbStore, uri, values, predicates, callback) 158 } 159 160 async updateByLowAuthority(rdbStore, uri: string, values, predicates, callback) { 161 const callerName = getBundleNameByUri(uri); 162 deleteValueCreator(values); 163 initPredicateCreator(predicates, callerName); 164 this.doUpdate(rdbStore, uri, values, predicates, callback) 165 } 166 167 async queryByLowAuthority(rdbStore, uri: string, columns: Array<string>, predicates, callback) { 168 const callerName = getBundleNameByUri(uri); 169 initPredicateCreator(predicates, callerName); 170 this.doQuery(rdbStore, uri, columns, predicates, callback); 171 } 172} 173 174/** 175 * 检查待插入的 alert 与 event 表中相同 event_id 的元组是否拥有相同的 creator 176 * 177 * @param rdbStore rdb数据库 178 * @param values 插入操作的数据 179 * @return true 相同 false 不相同 180 */ 181async function isEventSameWithAlertCreator(rdbStore, values): Promise<boolean> { 182 Log.debug(TAG, 'isEventSameWithAlertCreator start'); 183 const calendarAlertCreator = values[CalendarsColumns.CREATOR]; 184 let resultSet = await queryEventIdAndCreatorByAlert(rdbStore, values); 185 if (resultSet === null || resultSet === undefined) { 186 return false; 187 } 188 const eventIndexes: EventIndexes = parseIndexes(resultSet); 189 if (resultSet.goToFirstRow()) { 190 let events: Events = parseEvents(resultSet, eventIndexes); 191 if (events === null || events === undefined) { 192 return false; 193 } 194 if (events.creator === calendarAlertCreator) { 195 return true; 196 } 197 } 198 return false; 199} 200 201/** 202 * 检查待插入的 alert 与 event 表中是否存在相同 event_id 的元组 203 * 204 * @param rdbStore rdb数据库 205 * @param values 插入操作的数据 206 * @return true 相同 false 不相同 207 */ 208async function isEventSameWithAlertId(rdbStore, values): Promise<boolean> { 209 Log.debug(TAG, 'isEventSameWithAlertId start'); 210 let resultSet = await queryEventIdAndCreatorByAlert(rdbStore, values); 211 if (resultSet === null || resultSet === undefined) { 212 return false; 213 } 214 if (resultSet.rowCount > 0) { 215 return true; 216 } 217 return false; 218} 219 220/** 221 * 查询待插入的 alert 数据中 event_id 与 event 表相同的结果 222 * 223 * @param rdbStore rdb数据库 224 * @param values 插入操作的数据 225 * @return DataShareResultSet 226 */ 227async function queryEventIdAndCreatorByAlert(rdbStore, values): Promise<DataShareResultSet> { 228 const eventId = values[CalendarAlertsColumns.EVENT_ID]; 229 const columns = [EventColumns.ID, EventColumns.CREATOR]; 230 let predicates = new dataSharePredicates.DataSharePredicates(); 231 predicates.equalTo(EventColumns.ID, eventId); 232 let resultSet: DataShareResultSet; 233 try { 234 resultSet = await rdbStore.query(EventColumns.TABLE_NAME, predicates, columns); 235 } catch (err) { 236 Log.error(TAG, 'Event query data error'); 237 } 238 return resultSet; 239} 240 241/** 242 * 为下一个日历中的事件生成alarm 243 * 244 * @param isRemoveAlarms 是否需要移除状态为0的Alarms 245 */ 246export async function runScheduleNextAlarm(isRemoveAlarms: boolean = false) { 247 Log.info(TAG, 'runScheduleNextAlarm start.'); 248 let rdbStore = await CalendarDataHelper.getInstance().getRdbStore(); 249 await deleteRepeatReminders(rdbStore); 250 try { 251 if (isRemoveAlarms) { 252 await removeScheduledAlarmsLocked(rdbStore); 253 } 254 await scheduleNextAlarmLocked(rdbStore); 255 } catch (err) { 256 Log.error(TAG, "runScheduleNextAlarm error"); 257 } 258} 259 260/** 261 * 检索数据表,生成alarm,在提醒时间发送广播 262 * 263 * @param rdbStore RdbStore 264 */ 265async function scheduleNextAlarmLocked(rdbStore: data_rdb.RdbStore) { 266 Log.info(TAG, 'scheduleNextAlarmLocked start.'); 267 let rowsDeleted: number; 268 let isAlarmLessThenCurrent: boolean = false; 269 const date: Date = new Date(); 270 let currentMillis = date.getTime(); 271 const start = currentMillis - SCHEDULE_ALARM_SLACK; 272 const end = start + MILLS_PER_DAY + MILLS_PER_HOUR + SCHEDULE_ALARM_SLACK; 273 274 try { 275 rowsDeleted = await deleteInvalidAlert(rdbStore, currentMillis); 276 } catch (err) { 277 Log.error(TAG, 'TAG, Error in deleting invalidAlert'); 278 } 279 280 let nextAlarmTime = end; 281 let tmpAlarmTime: number; 282 try { 283 tmpAlarmTime = await findNextAlarmTime(rdbStore, currentMillis); 284 } catch (err) { 285 Log.error(TAG, 'TAG, Error in getting nextAlarmTime'); 286 } 287 if (tmpAlarmTime !== INVALIDATE_TIME_MILLIS && tmpAlarmTime < nextAlarmTime) { 288 nextAlarmTime = tmpAlarmTime; 289 } 290 291 const localOffset = getCurrentTimeZoneMillisecond(date); 292 const queryParams = [localOffset.toString(), localOffset.toString(), start.toString(), nextAlarmTime.toString(), 293 currentMillis.toString(), start.toString(), nextAlarmTime.toString(), currentMillis.toString()]; 294 295 // 扩展Instances:扩展范围为一天 296 await acquireExpandAll(rdbStore, start - MILLS_PER_DAY, end + MILLS_PER_DAY); 297 try { 298 let resultSet = await rdbStore.querySql(ALERT_GENERATE_QUERY, queryParams); 299 Log.info(TAG, "scheduleNextAlarmLocked() result row count is " + resultSet.rowCount); 300 const indexes: CalendarAlertsIndexes = parseScheduleCalendarAlertsIndexes(resultSet); 301 while (resultSet.goToNextRow()) { 302 let calendarAlerts: CalendarAlerts; 303 calendarAlerts = parseCalendarAlerts(resultSet, indexes); 304 if (calendarAlerts === null || calendarAlerts === undefined) { 305 Log.debug(TAG, "scheduleNextAlarmLocked() result is null or undefined"); 306 continue; 307 } 308 if (calendarAlerts.alarmTime < nextAlarmTime) { 309 nextAlarmTime = calendarAlerts.alarmTime; 310 } 311 312 const isExistAlarm = await alarmExists(rdbStore, calendarAlerts); 313 if (isExistAlarm) { 314 continue; 315 } 316 317 const rowId = await insertAlert(rdbStore, date, calendarAlerts); 318 if (rowId == -1) { 319 continue; 320 } 321 if (!await notifyEventReminder(calendarAlerts.alarmTime)) { 322 isAlarmLessThenCurrent = true; 323 } 324 } 325 if (isAlarmLessThenCurrent === true || rowsDeleted > 0) { 326 sendBroadcast(CommonEventConstants.EVENT_REMINDER); 327 runScheduleNextAlarm(); 328 } 329 } catch (err) { 330 Log.error(TAG, 'This is a resultSet ergodic error'); 331 } 332} 333 334/** 335 * 查找给定时间之后的下一个alarm时间 336 * 337 * @param rdbStore RdbStore 338 * @param mills 给定的事件 339 * @return 返回下一个alarm的时间,如果不存在此类alarm,则返回-1 340 */ 341async function findNextAlarmTime(rdbStore: data_rdb.RdbStore, mills: number): Promise<number> { 342 Log.info(TAG, 'findNextAlarmTime start.'); 343 let alarmTime = INVALIDATE_TIME_MILLIS; 344 const columns = [CalendarAlertsColumns.ALARM_TIME]; 345 let predicates = new dataSharePredicates.DataSharePredicates(); 346 predicates.greaterThanOrEqualTo(CalendarAlertsColumns.ALARM_TIME, mills.toString()); 347 predicates.orderByAsc(CalendarAlertsColumns.ALARM_TIME); 348 try { 349 let resultSet = await rdbStore.query(CalendarAlertsColumns.TABLE_NAME, predicates, columns); 350 if (resultSet === null || resultSet === undefined) { 351 return alarmTime; 352 } 353 if (resultSet.goToFirstRow()) { 354 alarmTime = resultSet.getLong(resultSet.getColumnIndex(CalendarAlertsColumns.ALARM_TIME)); 355 Log.debug(TAG, 'findNextAlarmTime succeed'); 356 } 357 } catch (err) { 358 Log.error(TAG, 'findNextAlarmTime error'); 359 } 360 return alarmTime; 361} 362 363/** 364 * 查看alarm是否已经存在 365 * 366 * @param calendarAlerts 携带参数的calendarAlerts 367 * @return 存在则返回true 368 */ 369async function alarmExists(rdbStore: data_rdb.RdbStore, calendarAlerts: CalendarAlerts): Promise<boolean> { 370 let isExistAlarm = false; 371 const columns = [CalendarAlertsColumns.ALARM_TIME]; 372 let predicates = new dataSharePredicates.DataSharePredicates(); 373 predicates.equalTo(InstancesColumns.EVENT_ID, calendarAlerts.eventId.toString()); 374 predicates.equalTo(CalendarAlertsColumns.BEGIN, calendarAlerts.begin.toString()); 375 predicates.equalTo(CalendarAlertsColumns.ALARM_TIME, calendarAlerts.alarmTime.toString()); 376 try { 377 let resultSet = await rdbStore.query(CalendarAlertsColumns.TABLE_NAME, predicates, columns); 378 if (resultSet === null || resultSet === undefined) { 379 return isExistAlarm; 380 } 381 if (resultSet.rowCount > 0) { 382 isExistAlarm = true; 383 Log.debug(TAG, 'alarmExists:alarm already exist'); 384 } 385 } catch (err) { 386 Log.error(TAG, 'alarmExists query data error'); 387 } 388 return isExistAlarm; 389} 390 391/** 392 * 获取触发提醒sql语句所查询的Alert表的列 393 * 394 * @param resultSet 执行查询sql语句的结果 395 * @return CalendarAlertsIndexes 返回查询的列Index 396 */ 397function parseScheduleCalendarAlertsIndexes(resultSet): CalendarAlertsIndexes { 398 if (resultSet === null || resultSet === undefined) { 399 return undefined; 400 } 401 let indexes: CalendarAlertsIndexes = new CalendarAlertsIndexes(); 402 indexes.alarmTimeIndex = resultSet.getColumnIndex('alertAlarmTime'); 403 indexes.eventIdIndex = resultSet.getColumnIndex('eventId'); 404 indexes.minutesIndex = resultSet.getColumnIndex(CalendarAlertsColumns.MINUTES); 405 indexes.beginIndex = resultSet.getColumnIndex(CalendarAlertsColumns.BEGIN); 406 indexes.endIndex = resultSet.getColumnIndex(CalendarAlertsColumns.END); 407 indexes.creatorIndex = resultSet.getColumnIndex(CalendarAlertsColumns.CREATOR); 408 return indexes; 409} 410 411/** 412 * Alert插入数据表中 413 * 414 * @param calendarAlerts 携带参数的calendarAlerts 415 * @return 成功则返回rowId 416 */ 417async function insertAlert(rdbStore, date, calendarAlerts: CalendarAlerts): Promise<number> { 418 let currentMillis = date.getTime(); 419 let rowId: number; 420 const valueBucket = { 421 [CalendarAlertsColumns.EVENT_ID]: calendarAlerts.eventId, 422 [CalendarAlertsColumns.BEGIN]: calendarAlerts.begin, 423 [CalendarAlertsColumns.END]: calendarAlerts.end, 424 [CalendarAlertsColumns.ALARM_TIME]: calendarAlerts.alarmTime, 425 [CalendarAlertsColumns.CREATION_TIME]: currentMillis, 426 [CalendarAlertsColumns.RECEIVED_TIME]: 0, 427 [CalendarAlertsColumns.NOTIFY_TIME]: 0, 428 [CalendarAlertsColumns.STATE]: CalendarAlertStateType.STATE_SCHEDULED, 429 [CalendarAlertsColumns.MINUTES]: calendarAlerts.minutes, 430 [CalendarAlertsColumns.CREATOR]: calendarAlerts.creator, 431 } 432 try { 433 rowId = await rdbStore.insert(CalendarAlertsColumns.TABLE_NAME, valueBucket); 434 Log.debug(TAG, `insertAlert succeed , rowId = ${rowId}`); 435 } catch (err) { 436 Log.error(TAG, 'insertAlert error'); 437 } 438 return rowId; 439} 440 441/** 442 * 删除无用的alarm 443 * 444 * @param rdbStore RdbStore 445 * @param currentMillis 当前时间 446 * @return 成功则返回受影响的行数 447 */ 448async function deleteInvalidAlert(rdbStore: data_rdb.RdbStore, currentMillis): Promise<number> { 449 Log.info(TAG, 'deleteInvalidAlert start.'); 450 let rowsDeleted: number = 0; 451 let arraysDeleteId: number[] = []; 452 let predicates = new dataSharePredicates.DataSharePredicates(); 453 const selectArg = [(currentMillis - CLEAR_OLD_ALARM_THRESHOLD).toString()]; 454 try { 455 let resultSet = await rdbStore.querySql(INVALID_CALENDARALERTS_SELECTOR, selectArg); 456 if (resultSet === null || resultSet === undefined) { 457 return 0; 458 } 459 if (!resultSet.goToFirstRow()) { 460 return 0; 461 } 462 do { 463 let deleteId = resultSet.getLong(resultSet.getColumnIndex(CalendarAlertsColumns.ID)); 464 arraysDeleteId.push(deleteId); 465 } while (resultSet.goToNextRow()); 466 predicates.in(CalendarAlertsColumns.ID, arraysDeleteId); 467 rowsDeleted = await rdbStore.delete(CalendarAlertsColumns.TABLE_NAME, predicates); 468 Log.debug(TAG, `deleteInvalidAlert succeed, rowsDeleted = ${rowsDeleted}`); 469 } catch (err) { 470 Log.error(TAG, 'deleteInvalidAlert error'); 471 } 472 return rowsDeleted; 473} 474 475/** 476 * 删除重复的Reminder 477 * 478 * @param rdbStore RdbStore 479 */ 480async function deleteRepeatReminders(rdbStore: data_rdb.RdbStore) { 481 Log.info(TAG, 'deleteRepeatReminders start.'); 482 let arraysList: number[] = []; 483 let predicates = new dataSharePredicates.DataSharePredicates(); 484 try { 485 let resultSet = await rdbStore.querySql(SINGLE_REMINDERS_SELECTOR); 486 if (resultSet === null || resultSet === undefined) { 487 return; 488 } 489 if (!resultSet.goToFirstRow()) { 490 return; 491 } 492 do { 493 let deleteId = resultSet.getLong(resultSet.getColumnIndex(RemindersColumns.ID)); 494 arraysList.push(deleteId); 495 } while (resultSet.goToNextRow()); 496 predicates.notIn(RemindersColumns.ID, arraysList); 497 await rdbStore.delete(RemindersColumns.TABLE_NAME, predicates); 498 Log.debug(TAG, `deleteRepeatReminders succeed`); 499 } catch (err) { 500 Log.error(TAG, 'deleteRepeatReminders error'); 501 } 502} 503 504/** 505 * 移除状态为0的Alarms 506 * 507 * @param rdbStore 508 */ 509async function removeScheduledAlarmsLocked(rdbStore: data_rdb.RdbStore) { 510 Log.info(TAG, 'removeScheduledAlarmsLocked start.'); 511 let predicates = new dataSharePredicates.DataSharePredicates(); 512 predicates.equalTo(CalendarAlertsColumns.STATE, CalendarAlertStateType.STATE_SCHEDULED) 513 try { 514 await rdbStore.delete(CalendarAlertsColumns.TABLE_NAME, predicates); 515 Log.debug(TAG, `removeScheduledAlarmsLocked succeed`); 516 } catch (err) { 517 Log.error(TAG, 'removeScheduledAlarmsLocked error'); 518 } 519} 520 521