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 Want from '@ohos.app.ability.Want';
18import Extension from '@ohos.application.DataShareExtensionAbility';
19import dataSharePredicates from '@ohos.data.dataSharePredicates';
20import relationalStore from '@ohos.data.relationalStore';
21
22import { Log } from '@ohos/common/src/main/ets/utils/Log';
23import dataShareProxy from '@ohos/dataprovider/src/main/ets/DataShareAbilityAuthenticateProxy';
24import { Permissions } from '@ohos.privacyManager';
25import { GlobalThis } from '@ohos/common/src/main/ets/utils/GlobalThis';
26
27const TAG = 'DataShareExtAbility';
28
29let isDatabaseInitializing = false;
30
31let isDatabaseInitComplete = false;
32
33const WRITE_CALENDAR: Permissions = "ohos.permission.WRITE_CALENDAR";
34const READ_CALENDAR: Permissions = "ohos.permission.READ_CALENDAR";
35
36export default class DataShareExtAbility extends Extension {
37  onCreate(want: Want, callback: Function) {
38    Log.info(TAG, '[onCreate] enter');
39    try {
40      GlobalThis.setExtensionContext(this.context);
41      callback();
42    } catch (err) {
43      Log.error(TAG, `err=${err?.message}`);
44    }
45    Log.info(TAG, '[onCreate] leave');
46  }
47
48  insert(uri: string, value: relationalStore.ValuesBucket, callback: Function) {
49    if (isDatabaseInitComplete) {
50      // If the database has been created, perform data operations directly
51      this.doInsert(uri, value, callback);
52    } else {
53      // If the table is not created, try to create the database
54      this.tryInitDatabase();
55      // Recursively check whether the database is built, per 100ms
56      setTimeout(() => {
57        this.insert(uri, value, callback);
58      }, 100);
59    }
60  }
61
62 batchInsert(uri: string, value: relationalStore.ValuesBucket[], callback: Function) {
63    if (isDatabaseInitComplete) {
64      // If the database has been created, perform data operations directly
65      this.doBachInsert(uri, value, callback);
66    } else {
67      // If the table is not created, try to create the database
68      this.tryInitDatabase();
69      // Recursively check whether the database is built, per 100ms
70      setTimeout(() => {
71        this.batchInsert(uri, value, callback);
72      }, 100);
73    }
74  }
75  
76  update(uri: string, predicates: dataSharePredicates.DataSharePredicates, value: relationalStore.ValuesBucket, callback: Function) {
77    if (isDatabaseInitComplete) {
78      this.doUpdate(uri, predicates, value, callback);
79    } else {
80      this.tryInitDatabase();
81      setTimeout(() => {
82        this.update(uri, predicates, value, callback);
83      }, 100);
84    }
85  }
86
87  query(uri: string, predicates: dataSharePredicates.DataSharePredicates, columns: Array<string>, callback: Function) {
88    if (isDatabaseInitComplete) {
89      this.doQuery(uri, predicates, columns, callback);
90    } else {
91      this.tryInitDatabase();
92      setTimeout(() => {
93        this.query(uri, predicates, columns, callback);
94      }, 100);
95    }
96  }
97
98  delete(uri: string, predicates: dataSharePredicates.DataSharePredicates, callback: Function) {
99    if (isDatabaseInitComplete) {
100      this.doDelete(uri, predicates, callback);
101    } else {
102      this.tryInitDatabase();
103      setTimeout(() => {
104        this.delete(uri, predicates, callback);
105      }, 100);
106    }
107  }
108
109  doInsert(uri: string, value: relationalStore.ValuesBucket, callback: Function) {
110    Log.info(TAG, '[insert] enter');
111    try {
112      dataShareProxy.insertByProxy(uri, value, WRITE_CALENDAR, callback);
113    } catch (err) {
114      Log.error(TAG, `err=${err?.message}`);
115    }
116    Log.info(TAG, '[insert] leave');
117  }
118
119  doBachInsert(uri: string, value: relationalStore.ValuesBucket[], callback: Function) {
120    Log.info(TAG, '[insert] enter');
121    try {
122      dataShareProxy.insertByProxy(uri, value, WRITE_CALENDAR, callback);
123    } catch (err) {
124      Log.error(TAG, `err=${err?.message}`);
125    }
126    Log.info(TAG, '[insert] leave');
127  }
128
129  doDelete(uri: string, predicates: dataSharePredicates.DataSharePredicates, callback: Function) {
130    Log.info(TAG, '[delete] enter');
131    try {
132      dataShareProxy.deleteByProxy(uri, predicates, WRITE_CALENDAR, callback);
133    } catch (err) {
134      Log.error(TAG, `err=${err?.message}`);
135    }
136    Log.info(TAG, '[delete] leave');
137  }
138
139  doUpdate(uri: string, predicates: dataSharePredicates.DataSharePredicates, value: relationalStore.ValuesBucket, callback: Function) {
140    Log.info(TAG, '[update] enter');
141    try {
142      dataShareProxy.updateByProxy(uri, value, predicates, WRITE_CALENDAR, callback)
143    } catch (err) {
144      Log.error(TAG, `err=${err?.message}`);
145    }
146    Log.info(TAG, '[update] leave');
147  }
148
149  doQuery(uri: string, predicates: dataSharePredicates.DataSharePredicates, columns: Array<string>, callback: Function) {
150    Log.info(TAG, '[query] enter');
151    try {
152      dataShareProxy.queryByProxy(uri, columns, predicates, READ_CALENDAR, callback);
153    } catch (err) {
154      Log.error(TAG, `err=${err?.message}`);
155    }
156    Log.info(TAG, '[query] leave');
157  }
158
159  private tryInitDatabase() {
160    // If a table is being created, return directly
161    if (isDatabaseInitializing) {
162      return;
163    }
164    // Change the status of isDatabaseInitializing
165    isDatabaseInitializing = true;
166    this.initDatabase();
167  }
168
169  async initDatabase() {
170    try {
171      // Change the status of isDatabaseInitializing and isDatabaseInitComplete
172      isDatabaseInitComplete = await dataShareProxy.init();
173    } finally {
174      isDatabaseInitializing = false;
175    }
176  }
177}