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