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 { Log } from '@ohos/common/src/main/ets/utils/Log'; 20import { getBundleNameByUri } from '@ohos/common/src/main/ets/utils/UrlUtils'; 21import { EventColumns } from '@ohos/datastructure/src/main/ets/events/EventColumns'; 22import { Events } from '@ohos/datastructure/src/main/ets/events/Events'; 23import { RemindersColumns } from '@ohos/datastructure/src/main/ets/reminders/RemindersColumns'; 24import { parseIndexes, EventIndexes } from '@ohos/datastructure/src/main/ets/events/EventIndexes'; 25import { parseEvents } from '@ohos/datastructure/src/main/ets/events/EventParser'; 26import { initValueCreator, initPredicateCreator, deleteValueCreator } from '../DatabaseProcessorHelper'; 27import { DefaultProcessor } from '../DefaultProcessor'; 28import { ErrorCode } from '../../constants/ErrorCode'; 29import { BusinessError } from '@ohos.base'; 30import { ValueType } from '@ohos.data.ValuesBucket'; 31 32const TAG = "RemindersProcessor"; 33 34/** 35 * the RemindersProcessor table processor 36 * 37 * @since 2022-10-17 38 */ 39export class RemindersProcessor extends DefaultProcessor { 40 public constructor(isFromMigrate?: boolean) { 41 super(isFromMigrate); 42 } 43 44 async insertByHighAuthority(rdbStore: data_rdb.RdbStore, uri: string, values: data_rdb.ValuesBucket, callback: Function) { 45 if (!this.isFromMigrate) { 46 const callerName = getBundleNameByUri(uri); 47 initValueCreator(values, callerName); 48 } 49 const isEventExist = await isEventSameWithReminderId(rdbStore, values); 50 if (isEventExist) { 51 this.doInsert(rdbStore, uri, values, callback); 52 } else { 53 Log.warn(TAG, 'not support insert operation'); 54 const err: BusinessError = { 55 code: ErrorCode.UN_SUPPORT_OPERATION, 56 name: 'UnSupportedOperationException', 57 message: 'The calling application cannot insert an reminder without its own event' 58 }; 59 callback(err, -1); 60 } 61 } 62 63 async insertByLowAuthority(rdbStore: data_rdb.RdbStore, uri: string, values: data_rdb.ValuesBucket, callback: Function) { 64 if (!this.isFromMigrate) { 65 const callerName = getBundleNameByUri(uri); 66 initValueCreator(values, callerName); 67 } 68 const isEventCreatorExist = await isEventSameWithReminderCreator(rdbStore, values); 69 if (isEventCreatorExist) { 70 this.doInsert(rdbStore, uri, values, callback); 71 } else { 72 Log.warn(TAG, 'not support insert operation'); 73 const err: BusinessError = { 74 code: ErrorCode.UN_SUPPORT_OPERATION, 75 name: 'UnSupportedOperationException', 76 message: 'The calling application cannot insert an reminder with different creator from event' 77 }; 78 callback(err, -1); 79 } 80 } 81 82 async deleteByLowAuthority(rdbStore: data_rdb.RdbStore, uri: string, predicates: dataSharePredicates.DataSharePredicates, callback: Function) { 83 const callerName = getBundleNameByUri(uri); 84 initPredicateCreator(predicates, callerName); 85 this.doDelete(rdbStore, uri, predicates, callback); 86 } 87 88 async updateByHighAuthority(rdbStore: data_rdb.RdbStore, uri: string, values: data_rdb.ValuesBucket, predicates: dataSharePredicates.DataSharePredicates, callback: Function) { 89 values = deleteValueCreator(values); 90 this.doUpdate(rdbStore, uri, values, predicates, callback) 91 } 92 93 async updateByLowAuthority(rdbStore: data_rdb.RdbStore, uri: string, values: data_rdb.ValuesBucket, predicates: dataSharePredicates.DataSharePredicates, callback: Function) { 94 const callerName = getBundleNameByUri(uri); 95 values = deleteValueCreator(values); 96 initPredicateCreator(predicates, callerName); 97 this.doUpdate(rdbStore, uri, values, predicates, callback) 98 } 99 100 async queryByLowAuthority(rdbStore: data_rdb.RdbStore, uri: string, columns: Array<string>, predicates: dataSharePredicates.DataSharePredicates, callback: Function) { 101 const callerName = getBundleNameByUri(uri); 102 initPredicateCreator(predicates, callerName); 103 this.doQuery(rdbStore, uri, columns, predicates, callback); 104 } 105} 106/** 107 * 检查待插入的 reminder 与 event 表中相同 event_id 的元组是否拥有相同的 creator 108 * @param rdbStore rdb数据库 109 * @param values 插入操作的数据 110 * @return true 相同 false 不相同 111 */ 112async function isEventSameWithReminderCreator(rdbStore: data_rdb.RdbStore, values: data_rdb.ValuesBucket): Promise<boolean> { 113 Log.debug(TAG, 'isEventSameWithReminderCreator start'); 114 const reminderCreator = values[RemindersColumns.CREATOR]; 115 let resultSet = await queryEventIdAndCreatorByReminder(rdbStore, values); 116 if (resultSet === null || resultSet === undefined) { 117 return false; 118 } 119 try { 120 const eventIndexes: EventIndexes = parseIndexes(resultSet) as EventIndexes; 121 if (resultSet.goToFirstRow()) { 122 let events: Events | undefined = parseEvents(resultSet, eventIndexes); 123 if (events === null || events === undefined) { 124 return false; 125 } 126 if (events.creator === reminderCreator) { 127 return true; 128 } 129 } 130 } catch (err) { 131 Log.warn(TAG, `isEventSameWithReminderCreator err ${JSON.stringify(err)}`); 132 } finally { 133 if (resultSet) { 134 resultSet.close(); 135 } 136 } 137 return false; 138} 139 140/** 141 * 检查待插入的 reminder 与 event 表中是否存在相同 event_id 的元组 142 * @param rdbStore rdb数据库 143 * @param values 插入操作的数据 144 * @return true 相同 false 不相同 145 */ 146async function isEventSameWithReminderId(rdbStore: data_rdb.RdbStore, values: data_rdb.ValuesBucket): Promise<boolean> { 147 Log.debug(TAG, 'isEventSameWithReminderId start'); 148 let resultSet = await queryEventIdAndCreatorByReminder(rdbStore, values); 149 try { 150 if (resultSet === null || resultSet === undefined) { 151 return false; 152 } 153 if (resultSet.rowCount > 0) { 154 return true; 155 } 156 } catch (err) { 157 Log.warn(TAG, `isEventSameWithReminderId err ${JSON.stringify(err)}`); 158 } finally { 159 if (resultSet) { 160 resultSet.close(); 161 } 162 } 163 return false; 164} 165 166/** 167 * 查询待插入的 reminder 数据中 event_id 与 event 表相同的结果 168 * @param rdbStore rdb数据库 169 * @param values 插入操作的数据 170 * @return DataShareResultSet 171 */ 172async function queryEventIdAndCreatorByReminder(rdbStore: data_rdb.RdbStore, values: data_rdb.ValuesBucket): Promise<data_rdb.ResultSet> { 173 const eventId = values[RemindersColumns.EVENT_ID] as ValueType; 174 const columns = [EventColumns.ID, EventColumns.CREATOR]; 175 let predicates = new dataSharePredicates.DataSharePredicates(); 176 predicates.equalTo(EventColumns.ID, eventId); 177 let resultSet: data_rdb.ResultSet = {} as data_rdb.ResultSet; 178 try { 179 resultSet = await rdbStore.query(EventColumns.TABLE_NAME, predicates, columns); 180 } catch (err) { 181 Log.error(TAG, 'Event query data error'); 182 } 183 return resultSet; 184}