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 { sendBroadcast } from '@ohos/common/src/main/ets/broadcast/BroadcastHelper'; 20import { Log } from '@ohos/common/src/main/ets/utils/Log'; 21import { 22 getCurrentTimeZoneMillisecond, 23 MILLS_PER_MINUTE, 24 MILLS_PER_HOUR, 25 MILLS_PER_DAY, 26 MILLS_PER_WEEK 27} from '@ohos/common/src/main/ets/utils/TimeUtils'; 28import { getBundleNameByUri } from '@ohos/common/src/main/ets/utils/UrlUtils'; 29 30import { CalendarAccountType } from '@ohos/datastructure/src/main/ets/calendars/CalendarAccountType'; 31import { CalendarAlerts } from '@ohos/datastructure/src/main/ets/calendaralerts/CalendarAlerts'; 32import { parseCalendarAlerts } from '@ohos/datastructure/src/main/ets/calendaralerts/CalendarAlertsParser'; 33import { CalendarAlertStateType } from '@ohos/datastructure/src/main/ets/calendaralerts/CalendarAlertStateType'; 34import { CalendarAlertsColumns } from '@ohos/datastructure/src/main/ets/calendaralerts/CalendarAlertsColumns'; 35import { CalendarAlertsIndexes } from '@ohos/datastructure/src/main/ets/calendaralerts/CalendarAlertsIndexes'; 36import { CalendarsColumns } from '@ohos/datastructure/src/main/ets/calendars/CalendarsColumns'; 37import { EventColumns } from '@ohos/datastructure/src/main/ets/events/EventColumns'; 38import { parseEvents } from '@ohos/datastructure/src/main/ets/events/EventParser'; 39import { Events } from '@ohos/datastructure/src/main/ets/events/Events'; 40import { EventIndexes, parseIndexes } from '@ohos/datastructure/src/main/ets/events/EventIndexes'; 41import { InstancesColumns } from '@ohos/datastructure/src/main/ets/instances/InstancesColumns'; 42import { ReminderMethodType } from '@ohos/datastructure/src/main/ets/reminders/ReminderMethodType'; 43import { RemindersColumns } from '@ohos/datastructure/src/main/ets/reminders/RemindersColumns'; 44 45import { CommonEventConstants } from '../../commonevents/CommonEventConstants'; 46import { DefaultProcessor } from '../DefaultProcessor'; 47import { ErrorCode } from '../../constants/ErrorCode'; 48import { notifyEventReminder } from '../../commonevents/notify/ScheduleAlarmNotifier'; 49import CalendarDataHelper from '../../utils/CalendarDataHelper'; 50import { acquireExpandAll } from '../instances/InstancesProcessor'; 51import { initValueCreator, initPredicateCreator, deleteValueCreator } from '../DatabaseProcessorHelper'; 52import { ValueType, ValuesBucket } from '@ohos.data.ValuesBucket'; 53import { BusinessError } from '@ohos.base'; 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: data_rdb.RdbStore, uri: string, values: data_rdb.ValuesBucket, callback: Function) { 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: BusinessError = { 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: data_rdb.RdbStore, uri: string, values: ValuesBucket, callback: Function) { 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: BusinessError = { 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: data_rdb.RdbStore, uri: string, predicates: dataSharePredicates.DataSharePredicates, callback: Function) { 150 const callerName = getBundleNameByUri(uri); 151 initPredicateCreator(predicates, callerName); 152 this.doDelete(rdbStore, uri, predicates, callback); 153 } 154 155 async updateByHighAuthority(rdbStore: data_rdb.RdbStore, uri: string, values: data_rdb.ValuesBucket, predicates: dataSharePredicates.DataSharePredicates, callback: Function) { 156 values = deleteValueCreator(values); 157 this.doUpdate(rdbStore, uri, values, predicates, callback) 158 } 159 160 async updateByLowAuthority(rdbStore: data_rdb.RdbStore, uri: string, values: data_rdb.ValuesBucket, predicates: dataSharePredicates.DataSharePredicates, callback: Function) { 161 const callerName = getBundleNameByUri(uri); 162 values = deleteValueCreator(values); 163 initPredicateCreator(predicates, callerName); 164 this.doUpdate(rdbStore, uri, values, predicates, callback) 165 } 166 167 async queryByLowAuthority(rdbStore: data_rdb.RdbStore, uri: string, columns: Array<string>, predicates: dataSharePredicates.DataSharePredicates, callback: Function) { 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: data_rdb.RdbStore, values: ValuesBucket): 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 try { 189 const eventIndexes: EventIndexes = parseIndexes(resultSet) as EventIndexes; 190 if (resultSet.goToFirstRow()) { 191 let events: Events | undefined = parseEvents(resultSet, eventIndexes); 192 if (events === null || events === undefined) { 193 return false; 194 } 195 return events.creator === calendarAlertCreator; 196 } 197 } catch (err) { 198 Log.warn(TAG, `isEventSameWithAlertCreator err ${JSON.stringify(err)}`); 199 } finally { 200 if (resultSet) { 201 resultSet.close(); 202 } 203 } 204 return false; 205} 206 207/** 208 * 检查待插入的 alert 与 event 表中是否存在相同 event_id 的元组 209 * 210 * @param rdbStore rdb数据库 211 * @param values 插入操作的数据 212 * @return true 相同 false 不相同 213 */ 214async function isEventSameWithAlertId(rdbStore: data_rdb.RdbStore, values: data_rdb.ValuesBucket): Promise<boolean> { 215 Log.debug(TAG, 'isEventSameWithAlertId start'); 216 let resultSet = await queryEventIdAndCreatorByAlert(rdbStore, values); 217 try { 218 if (resultSet === null || resultSet === undefined) { 219 return false; 220 } 221 if (resultSet.rowCount > 0) { 222 return true; 223 } 224 } catch (err) { 225 Log.warn(TAG, `isEventSameWithAlertId err ${JSON.stringify(err)}`); 226 } finally { 227 if (resultSet) { 228 resultSet.close(); 229 } 230 } 231 return false; 232} 233 234/** 235 * 查询待插入的 alert 数据中 event_id 与 event 表相同的结果 236 * 237 * @param rdbStore rdb数据库 238 * @param values 插入操作的数据 239 * @return DataShareResultSet 240 */ 241async function queryEventIdAndCreatorByAlert(rdbStore: data_rdb.RdbStore, values: data_rdb.ValuesBucket) { 242 const eventId = values[CalendarAlertsColumns.EVENT_ID] as ValueType; 243 const columns = [EventColumns.ID, EventColumns.CREATOR]; 244 let predicates = new dataSharePredicates.DataSharePredicates(); 245 predicates.equalTo(EventColumns.ID, eventId); 246 try { 247 return await rdbStore.query(EventColumns.TABLE_NAME, predicates, columns); 248 } catch (err) { 249 Log.error(TAG, 'Event query data error'); 250 } 251 return; 252} 253 254/** 255 * 为下一个日历中的事件生成alarm 256 * 257 * @param isRemoveAlarms 是否需要移除状态为0的Alarms 258 */ 259export async function runScheduleNextAlarm(isRemoveAlarms: boolean = false) { 260 Log.info(TAG, 'runScheduleNextAlarm start.'); 261 let rdbStore = await CalendarDataHelper.getInstance().getRdbStore(); 262 if (!rdbStore) { 263 Log.warn(TAG, 'runScheduleNextAlarm: rdbStore is null.'); 264 return; 265 } 266 await deleteRepeatReminders(rdbStore); 267 try { 268 if (isRemoveAlarms) { 269 await removeScheduledAlarmsLocked(rdbStore); 270 } 271 await scheduleNextAlarmLocked(rdbStore); 272 } catch (err) { 273 Log.error(TAG, "runScheduleNextAlarm error"); 274 } 275} 276 277/** 278 * 检索数据表,生成alarm,在提醒时间发送广播 279 * 280 * @param rdbStore RdbStore 281 */ 282async function scheduleNextAlarmLocked(rdbStore: data_rdb.RdbStore) { 283 Log.info(TAG, 'scheduleNextAlarmLocked start.'); 284 let rowsDeleted: number = 0; 285 let isAlarmLessThenCurrent: boolean = false; 286 const date: Date = new Date(); 287 let currentMillis = date.getTime(); 288 const start = currentMillis - SCHEDULE_ALARM_SLACK; 289 const end = start + MILLS_PER_DAY + MILLS_PER_HOUR + SCHEDULE_ALARM_SLACK; 290 291 try { 292 rowsDeleted = await deleteInvalidAlert(rdbStore, currentMillis); 293 } catch (err) { 294 Log.error(TAG, 'TAG, Error in deleting invalidAlert'); 295 } 296 297 let nextAlarmTime = end; 298 try { 299 let tmpAlarmTime: number = await findNextAlarmTime(rdbStore, currentMillis); 300 if (tmpAlarmTime !== INVALIDATE_TIME_MILLIS && tmpAlarmTime < nextAlarmTime) { 301 nextAlarmTime = tmpAlarmTime; 302 } 303 } catch (err) { 304 Log.error(TAG, 'TAG, Error in getting nextAlarmTime'); 305 } 306 const localOffset = getCurrentTimeZoneMillisecond(date); 307 const queryParams = [localOffset.toString(), localOffset.toString(), start.toString(), nextAlarmTime.toString(), 308 currentMillis.toString(), start.toString(), nextAlarmTime.toString(), currentMillis.toString()]; 309 310 // 扩展Instances:扩展范围为一天 311 await acquireExpandAll(rdbStore, start - MILLS_PER_DAY, end + MILLS_PER_DAY); 312 let resultSet: data_rdb.ResultSet | null = null; 313 try { 314 resultSet = await rdbStore.querySql(ALERT_GENERATE_QUERY, queryParams); 315 Log.info(TAG, "scheduleNextAlarmLocked() result row count is " + resultSet.rowCount); 316 const indexes: CalendarAlertsIndexes = parseScheduleCalendarAlertsIndexes(resultSet) as CalendarAlertsIndexes; 317 while (resultSet.goToNextRow()) { 318 let calendarAlerts: CalendarAlerts | undefined = parseCalendarAlerts(resultSet, indexes); 319 if (calendarAlerts === null || calendarAlerts === undefined) { 320 Log.debug(TAG, "scheduleNextAlarmLocked() result is null or undefined"); 321 continue; 322 } 323 if (calendarAlerts.alarmTime < nextAlarmTime) { 324 nextAlarmTime = calendarAlerts.alarmTime; 325 } 326 327 const isExistAlarm = await alarmExists(rdbStore, calendarAlerts); 328 if (isExistAlarm) { 329 continue; 330 } 331 332 const rowId = await insertAlert(rdbStore, date, calendarAlerts); 333 if (rowId == -1) { 334 continue; 335 } 336 if (!await notifyEventReminder(calendarAlerts.alarmTime)) { 337 isAlarmLessThenCurrent = true; 338 } 339 } 340 if (isAlarmLessThenCurrent || rowsDeleted > 0) { 341 sendBroadcast(CommonEventConstants.EVENT_REMINDER); 342 runScheduleNextAlarm(); 343 } 344 } catch (err) { 345 Log.error(TAG, 'This is a resultSet ergodic error'); 346 } finally { 347 if (resultSet) { 348 resultSet.close(); 349 } 350 } 351} 352 353/** 354 * 查找给定时间之后的下一个alarm时间 355 * 356 * @param rdbStore RdbStore 357 * @param mills 给定的事件 358 * @return 返回下一个alarm的时间,如果不存在此类alarm,则返回-1 359 */ 360async function findNextAlarmTime(rdbStore: data_rdb.RdbStore, mills: number): Promise<number> { 361 Log.info(TAG, 'findNextAlarmTime start.'); 362 let alarmTime = INVALIDATE_TIME_MILLIS; 363 const columns = [CalendarAlertsColumns.ALARM_TIME]; 364 let predicates = new dataSharePredicates.DataSharePredicates(); 365 predicates.greaterThanOrEqualTo(CalendarAlertsColumns.ALARM_TIME, mills.toString()); 366 predicates.orderByAsc(CalendarAlertsColumns.ALARM_TIME); 367 try { 368 let resultSet = await rdbStore.query(CalendarAlertsColumns.TABLE_NAME, predicates, columns); 369 if (resultSet === null || resultSet === undefined) { 370 return alarmTime; 371 } 372 if (resultSet.goToFirstRow()) { 373 alarmTime = resultSet.getLong(resultSet.getColumnIndex(CalendarAlertsColumns.ALARM_TIME)); 374 Log.debug(TAG, 'findNextAlarmTime succeed'); 375 } 376 } catch (err) { 377 Log.error(TAG, 'findNextAlarmTime error'); 378 } 379 return alarmTime; 380} 381 382/** 383 * 查看alarm是否已经存在 384 * 385 * @param calendarAlerts 携带参数的calendarAlerts 386 * @return 存在则返回true 387 */ 388async function alarmExists(rdbStore: data_rdb.RdbStore, calendarAlerts: CalendarAlerts): Promise<boolean> { 389 let isExistAlarm = false; 390 const columns = [CalendarAlertsColumns.ALARM_TIME]; 391 let predicates = new dataSharePredicates.DataSharePredicates(); 392 predicates.equalTo(InstancesColumns.EVENT_ID, calendarAlerts.eventId.toString()); 393 predicates.equalTo(CalendarAlertsColumns.BEGIN, calendarAlerts.begin.toString()); 394 predicates.equalTo(CalendarAlertsColumns.ALARM_TIME, calendarAlerts.alarmTime.toString()); 395 try { 396 let resultSet = await rdbStore.query(CalendarAlertsColumns.TABLE_NAME, predicates, columns); 397 if (resultSet === null || resultSet === undefined) { 398 return isExistAlarm; 399 } 400 if (resultSet.rowCount > 0) { 401 isExistAlarm = true; 402 Log.debug(TAG, 'alarmExists:alarm already exist'); 403 } 404 } catch (err) { 405 Log.error(TAG, 'alarmExists query data error'); 406 } 407 return isExistAlarm; 408} 409 410/** 411 * 获取触发提醒sql语句所查询的Alert表的列 412 * 413 * @param resultSet 执行查询sql语句的结果 414 * @return CalendarAlertsIndexes 返回查询的列Index 415 */ 416function parseScheduleCalendarAlertsIndexes(resultSet: data_rdb.ResultSet) { 417 if (resultSet === null || resultSet === undefined) { 418 return; 419 } 420 let indexes: CalendarAlertsIndexes = new CalendarAlertsIndexes(); 421 indexes.alarmTimeIndex = resultSet.getColumnIndex('alertAlarmTime'); 422 indexes.eventIdIndex = resultSet.getColumnIndex('eventId'); 423 indexes.minutesIndex = resultSet.getColumnIndex(CalendarAlertsColumns.MINUTES); 424 indexes.beginIndex = resultSet.getColumnIndex(CalendarAlertsColumns.BEGIN); 425 indexes.endIndex = resultSet.getColumnIndex(CalendarAlertsColumns.END); 426 indexes.creatorIndex = resultSet.getColumnIndex(CalendarAlertsColumns.CREATOR); 427 return indexes; 428} 429 430/** 431 * Alert插入数据表中 432 * 433 * @param calendarAlerts 携带参数的calendarAlerts 434 * @return 成功则返回rowId 435 */ 436async function insertAlert(rdbStore: data_rdb.RdbStore, date: Date, calendarAlerts: CalendarAlerts): Promise<number> { 437 let currentMillis = date.getTime(); 438 let rowId: number = -1; 439 const valueBucket: ValuesBucket = {}; 440 valueBucket[CalendarAlertsColumns.EVENT_ID] = calendarAlerts.eventId; 441 valueBucket[CalendarAlertsColumns.BEGIN] = calendarAlerts.begin; 442 valueBucket[CalendarAlertsColumns.END] = calendarAlerts.end; 443 valueBucket[CalendarAlertsColumns.ALARM_TIME] = calendarAlerts.alarmTime; 444 valueBucket[CalendarAlertsColumns.CREATION_TIME] = currentMillis; 445 valueBucket[CalendarAlertsColumns.RECEIVED_TIME] = 0; 446 valueBucket[CalendarAlertsColumns.NOTIFY_TIME] = 0; 447 valueBucket[CalendarAlertsColumns.STATE] = CalendarAlertStateType.STATE_SCHEDULED; 448 valueBucket[CalendarAlertsColumns.MINUTES] = calendarAlerts.minutes; 449 valueBucket[CalendarAlertsColumns.CREATOR] = calendarAlerts.creator; 450 try { 451 rowId = await rdbStore.insert(CalendarAlertsColumns.TABLE_NAME, valueBucket); 452 Log.debug(TAG, `insertAlert succeed , rowId = ${rowId}`); 453 } catch (err) { 454 Log.error(TAG, 'insertAlert error'); 455 } 456 return rowId; 457} 458 459/** 460 * 删除无用的alarm 461 * 462 * @param rdbStore RdbStore 463 * @param currentMillis 当前时间 464 * @return 成功则返回受影响的行数 465 */ 466async function deleteInvalidAlert(rdbStore: data_rdb.RdbStore, currentMillis: number): Promise<number> { 467 Log.info(TAG, 'deleteInvalidAlert start.'); 468 let rowsDeleted: number = 0; 469 let arraysDeleteId: number[] = []; 470 let predicates = new dataSharePredicates.DataSharePredicates(); 471 const selectArg = [(currentMillis - CLEAR_OLD_ALARM_THRESHOLD).toString()]; 472 try { 473 let resultSet = await rdbStore.querySql(INVALID_CALENDARALERTS_SELECTOR, selectArg); 474 if (resultSet === null || resultSet === undefined) { 475 return 0; 476 } 477 if (!resultSet.goToFirstRow()) { 478 return 0; 479 } 480 do { 481 let deleteId = resultSet.getLong(resultSet.getColumnIndex(CalendarAlertsColumns.ID)); 482 arraysDeleteId.push(deleteId); 483 } while (resultSet.goToNextRow()); 484 predicates.in(CalendarAlertsColumns.ID, arraysDeleteId); 485 rowsDeleted = await rdbStore.delete(CalendarAlertsColumns.TABLE_NAME, predicates); 486 Log.debug(TAG, `deleteInvalidAlert succeed, rowsDeleted = ${rowsDeleted}`); 487 } catch (err) { 488 Log.error(TAG, 'deleteInvalidAlert error'); 489 } 490 return rowsDeleted; 491} 492 493/** 494 * 删除重复的Reminder 495 * 496 * @param rdbStore RdbStore 497 */ 498async function deleteRepeatReminders(rdbStore: data_rdb.RdbStore) { 499 Log.info(TAG, 'deleteRepeatReminders start.'); 500 let arraysList: number[] = []; 501 let predicates = new dataSharePredicates.DataSharePredicates(); 502 try { 503 let resultSet = await rdbStore.querySql(SINGLE_REMINDERS_SELECTOR); 504 if (resultSet === null || resultSet === undefined) { 505 return; 506 } 507 if (!resultSet.goToFirstRow()) { 508 return; 509 } 510 do { 511 let deleteId = resultSet.getLong(resultSet.getColumnIndex(RemindersColumns.ID)); 512 arraysList.push(deleteId); 513 } while (resultSet.goToNextRow()); 514 predicates.notIn(RemindersColumns.ID, arraysList); 515 await rdbStore.delete(RemindersColumns.TABLE_NAME, predicates); 516 Log.debug(TAG, `deleteRepeatReminders succeed`); 517 } catch (err) { 518 Log.error(TAG, 'deleteRepeatReminders error'); 519 } 520} 521 522/** 523 * 移除状态为0的Alarms 524 * 525 * @param rdbStore 526 */ 527async function removeScheduledAlarmsLocked(rdbStore: data_rdb.RdbStore) { 528 Log.info(TAG, 'removeScheduledAlarmsLocked start.'); 529 let predicates = new dataSharePredicates.DataSharePredicates(); 530 predicates.equalTo(CalendarAlertsColumns.STATE, CalendarAlertStateType.STATE_SCHEDULED) 531 try { 532 await rdbStore.delete(CalendarAlertsColumns.TABLE_NAME, predicates); 533 Log.debug(TAG, `removeScheduledAlarmsLocked succeed`); 534 } catch (err) { 535 Log.error(TAG, 'removeScheduledAlarmsLocked error'); 536 } 537} 538 539