• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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