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 LinkedList from '@ohos.util.LinkedList';
20
21import { Log } from '@ohos/common/src/main/ets/utils/Log';
22import { Observable } from '@ohos/common/src/main/ets/observer/Observable';
23import { Observer, ObserverMessage } from '@ohos/common/src/main/ets/observer/Observer';
24import { hasNoError } from '@ohos/common/src/main/ets/utils/ErrorUtils';
25
26import {
27  notifyProviderChange,
28  OPERATION_INSERT,
29  OPERATION_UPDATE,
30  OPERATION_DELETE
31} from '../commonevents/notify/ProviderChangeNotifier';
32import { DatabaseProcessor } from './DatabaseProcessor';
33import getTableByUri from '../utils/CalendarUriHelper';
34import { AlertsMessage } from './alerts/AlertsMessage';
35import { BusinessError } from '@ohos.base';
36
37export const INSERT_OPERATION_NAME = 'insert';
38
39export const UPDATE_OPERATION_NAME = 'update';
40
41export const DELETE_OPERATION_NAME = 'delete';
42
43const TAG = 'DefaultProcessor';
44
45
46/**
47 * the default database Processors
48 *
49 * @since 2022-06-21
50 */
51export class DefaultProcessor implements DatabaseProcessor, Observable {
52  protected isFromMigrate: boolean = false;
53  protected logTag: string = TAG;
54  private mObserverList: LinkedList<Observer> = new LinkedList();
55
56  constructor(isFromMigrate: boolean = false) {
57    this.isFromMigrate = isFromMigrate;
58    this.initParas();
59    Log.info(this.logTag, `isFromMigrate is ${this.isFromMigrate}`);
60  }
61
62  protected initParas() {
63
64  }
65
66  insertByHighAuthority(rdbStore: data_rdb.RdbStore, uri: string,
67                        values: data_rdb.ValuesBucket, callback: Function) {
68    this.doInsert(rdbStore, uri, values, callback);
69  }
70
71  batchInsertByHighAuthority(rdbStore: data_rdb.RdbStore, uri: string, values: data_rdb.ValuesBucket[],
72                             callback: Function) {
73    this.doBatchInsert(rdbStore, uri, values, callback);
74  }
75
76  insertByLowAuthority(rdbStore: data_rdb.RdbStore, uri: string,
77                       values: data_rdb.ValuesBucket, callback: Function) {
78    this.doInsert(rdbStore, uri, values, callback);
79  }
80
81  batchInsertByLowAuthority(rdbStore: data_rdb.RdbStore, uri: string, values: data_rdb.ValuesBucket[],
82                            callback: Function) {
83    this.doBatchInsert(rdbStore, uri, values, callback);
84  }
85
86  deleteByHighAuthority(rdbStore: data_rdb.RdbStore, uri: string,
87                        predicates: dataSharePredicates.DataSharePredicates, callback: Function) {
88    this.doDelete(rdbStore, uri, predicates, callback);
89  }
90
91  deleteByLowAuthority(rdbStore: data_rdb.RdbStore, uri: string,
92                       predicates: dataSharePredicates.DataSharePredicates, callback: Function) {
93    this.doDelete(rdbStore, uri, predicates, callback);
94  }
95
96  updateByHighAuthority(rdbStore: data_rdb.RdbStore, uri: string, values: data_rdb.ValuesBucket,
97                        predicates: dataSharePredicates.DataSharePredicates, callback: Function) {
98    this.doUpdate(rdbStore, uri, values, predicates, callback);
99  }
100
101  updateByLowAuthority(rdbStore: data_rdb.RdbStore, uri: string, values: data_rdb.ValuesBucket,
102                       predicates: dataSharePredicates.DataSharePredicates, callback: Function) {
103    this.doUpdate(rdbStore, uri, values, predicates, callback);
104  }
105
106  queryByHighAuthority(rdbStore: data_rdb.RdbStore, uri: string, columns: Array<string>,
107                       predicates: dataSharePredicates.DataSharePredicates, callback: Function) {
108    this.doQuery(rdbStore, uri, columns, predicates, callback);
109  }
110
111  queryByLowAuthority(rdbStore: data_rdb.RdbStore, uri: string, columns: Array<string>,
112                      predicates: dataSharePredicates.DataSharePredicates, callback: Function) {
113    this.doQuery(rdbStore, uri, columns, predicates, callback);
114  }
115
116  /**
117   * 插入的公共方法
118   *
119   * @param rdbStore rdb数据库
120   * @param uri DataShare的uri
121   * @param values 插入的数据
122   * @param callback 回调方法
123   */
124  doInsert(rdbStore: data_rdb.RdbStore, uri: string, values: data_rdb.ValuesBucket, callback: Function) {
125    const table = getTableByUri(uri);
126    rdbStore.insert(table, values, (err, rowId) => {
127      Log.log(this.logTag, `insert ${table} before callback`);
128      callback(err, rowId);
129      if (hasNoError(err)) {
130        Log.log(this.logTag, `insert ${table} after callback: rowId = ` + rowId);
131        if (!this.isFromMigrate) {
132          notifyProviderChange(table, OPERATION_INSERT);
133          this.notifyAlertsChanges(INSERT_OPERATION_NAME, table, values);
134        }
135      } else {
136        Log.warn(this.logTag, `insert get err:${err?.code}, ${err?.message}`);
137      }
138    });
139  }
140
141  /**
142   * 批量插入的公共方法
143   *
144   * @param rdbStore rdb数据库
145   * @param uri DataShare的uri
146   * @param values 插入的数据
147   * @param callback 回调方法
148   */
149  doBatchInsert(rdbStore: data_rdb.RdbStore, uri: string, values: data_rdb.ValuesBucket[], callback: Function) {
150    const table = getTableByUri(uri);
151    rdbStore.batchInsert(table, values, (err, rowId) => {
152      Log.log(this.logTag, `insert ${table} before callback`);
153      callback(err, rowId);
154      if (hasNoError(err)) {
155        Log.log(this.logTag, `insert ${table} after callback: rowId = ` + rowId);
156        if (!this.isFromMigrate) {
157          notifyProviderChange(table, OPERATION_INSERT);
158          this.notifyAlertsChanges(INSERT_OPERATION_NAME, table, values);
159        }
160      } else {
161        Log.warn(this.logTag, `insert get err:${err?.code}, ${err?.message}`);
162      }
163    });
164  }
165
166  /**
167   * 删除的公共方法
168   *
169   * @param rdbStore rdb数据库
170   * @param uri DataShare的uri
171   * @param predicates 删除条件
172   * @param callback 回调方法
173   */
174  doDelete(rdbStore: data_rdb.RdbStore, uri: string,
175           predicates: dataSharePredicates.DataSharePredicates, callback: Function) {
176    const table = getTableByUri(uri);
177    rdbStore.delete(table, predicates, (err: BusinessError, count) => {
178      Log.log(this.logTag, `delete ${table} before callback`);
179      callback(err, count);
180      if (hasNoError(err)) {
181        Log.log(this.logTag, `delete ${table} after callback: count = ` + count);
182        notifyProviderChange(table, OPERATION_DELETE);
183        const deleteValue: data_rdb.ValuesBucket = {
184          'deleteCounts': count
185        }
186        Log.log(this.logTag, `deleteValue: [deleteCounts]: ${deleteValue['deleteCounts']}`);
187        this.notifyAlertsChanges(DELETE_OPERATION_NAME, table, deleteValue);
188      } else {
189        Log.error(this.logTag, `delete get err:${err?.code}, ${err?.message}`);
190      }
191    });
192  }
193
194  /**
195   * 更新的公共方法
196   *
197   * @param rdbStore rdb数据库
198   * @param uri DataShare的uri
199   * @param values 更新的数据
200   * @param predicates 更新条件
201   * @param callback 回调方法
202   */
203  doUpdate(rdbStore: data_rdb.RdbStore, uri: string, values: data_rdb.ValuesBucket,
204           predicates: dataSharePredicates.DataSharePredicates, callback: Function) {
205    const table = getTableByUri(uri);
206    rdbStore.update(table, values, predicates, (err, count) => {
207      Log.log(this.logTag, `update ${table} before callback`);
208      callback(err, count);
209      if (hasNoError(err)) {
210        Log.log(this.logTag, `update ${table} after callback: count = ` + count);
211        notifyProviderChange(table, OPERATION_UPDATE);
212        this.notifyAlertsChanges(UPDATE_OPERATION_NAME, table, values);
213      } else {
214        Log.warn(this.logTag, `update get err:${err?.code}, ${err?.message}`);
215      }
216    });
217  }
218
219  /**
220   * 查询的公共方法
221   *
222   * @param rdbStore rdb数据库
223   * @param uri DataShare的uri
224   * @param columns 查询的列名
225   * @param predicates 查询条件
226   * @param callback 回调方法
227   */
228  doQuery(rdbStore: data_rdb.RdbStore, uri: string, columns: Array<string>,
229          predicates: dataSharePredicates.DataSharePredicates, callback: Function) {
230    const table = getTableByUri(uri);
231    let queryInnerFun = (err: BusinessError, resultSet: data_rdb.ResultSet) => {
232      Log.log(this.logTag, `query ${table} before callback`);
233      callback(err, resultSet);
234      if (!hasNoError(err)) {
235        Log.warn(this.logTag, `query get err:${err?.code}, ${err?.message}`);
236      }
237    }
238    rdbStore.query(table, predicates, columns, queryInnerFun);
239  }
240
241  /**
242   * 增加一个观察者
243   */
244  addObserver(observer: Observer) {
245    this.mObserverList.add(observer);
246  }
247
248  /**
249   * 删除一个观察者
250   */
251  removeObserver(observer: Observer) {
252    this.mObserverList.remove(observer);
253  }
254
255  /**
256   * 被观察者状态发生改变后,通知d订阅的所有观察者更新
257   */
258  notifyChanges(message: ObserverMessage) {
259    this.mObserverList.forEach((observer) => {
260      observer.onChange(message);
261    })
262  }
263
264  notifyAlertsChanges(operationName: string, table: string,
265                      values?: data_rdb.ValuesBucket | data_rdb.ValuesBucket[]) {
266    let message = new AlertsMessage();
267    message.setOperationName(operationName);
268    message.setTableName(table);
269    if (values) {
270      message.setValues(values);
271    }
272    this.notifyChanges(message);
273  }
274}
275