1# Sharing Data Using DataShareExtensionAbility 2 3 4## When to Use 5 6If complex services are involved in cross-application data access, you can use **DataShareExtensionAbility** to start the application of the data provider to implement data access. 7 8You need to implement flexible service logics via callbacks of the service provider. 9 10 11## Working Principles 12 13There are two roles in **DataShare**: 14 15- Data provider: implements operations, such as adding, deleting, modifying, and querying data, and opening a file, using [DataShareExtensionAbility](../reference/apis/js-apis-application-dataShareExtensionAbility.md). 16 17- Data consumer: accesses the data provided by the provider using [createDataShareHelper()](../reference/apis/js-apis-data-dataShare.md#datasharecreatedatasharehelper). 18 19**Figure 1** Data sharing mechanism 20 21![dataShare](figures/dataShare.jpg) 22 23- The **DataShareExtensionAbility** module, as the data provider, implements services related to data sharing between applications. 24 25- The **DataShareHelper** module, as the data consumer, provides APIs for accessing data, including adding, deleting, modifying, and querying data. 26 27- The data consumer communicates with the data provider via inter-process communication (IPC). The data provider can be implemented through a database or other data storage. 28 29- The **ResultSet** module is implemented through shared memory. Shared memory stores the result sets, and interfaces are provided to traverse result sets. 30 31 32## How to Develop 33 34 35### Data Provider Application Development (Only for System Applications) 36 37[DataShareExtensionAbility](../reference/apis/js-apis-application-dataShareExtensionAbility.md) provides the following APIs. You can override these APIs as required. 38 39- **onCreate**: called by the server to initialize service logic when the DataShare client connects to the DataShareExtensionAbility server. 40 41- **insert**: called to insert data upon the request of the client. Data insertion must be implemented in this callback on the server. 42 43- **update**: called to update data upon the request of the client. Data update must be implemented in this callback on the server. 44 45- **delete**: called to delete data upon the request of the client. Data deletion must be implemented in this callback on the server. 46 47- **query**: called to query data upon the request of the client. Data query must be implemented in this callback on the server. 48 49- **batchInsert**: called to batch insert data upon the request of the client. Batch data insertion must be implemented in this callback on the server. 50 51- **normalizeUri**: converts the URI provided by the client to the URI used by the server. 52 53- **denormalizeUri**: converts the URI used by the server to the initial URI passed by the client. 54 55Before implementing a **DataShare** service, you need to create a **DataShareExtensionAbility** object in the DevEco Studio project as follows: 56 571. In the **ets** directory of the **Module** project, right-click and choose **New > Directory** to create a directory named **DataShareExtAbility**. 58 592. Right-click the **DataShareAbility** directory, and choose **New > TypeScript File** to create a file named **DataShareExtAbility.ts**. 60 613. Import **@ohos.application.DataShareExtensionAbility** and other dependencies to the **DataShareExtAbility.ts** file, and 62override the service implementation as required. For example, if the data provider provides only the data insertion, deletion, and query services, you can override only these APIs. 63 64 ```js 65 import Extension from '@ohos.application.DataShareExtensionAbility'; 66 import rdb from '@ohos.data.relationalStore'; 67 import dataSharePredicates from '@ohos.data.dataSharePredicates'; 68 ``` 69 704. Implement the data provider services. For example, implement data storage of the data provider by using a database, reading and writing files, or accessing the network. 71 72 ```js 73 const DB_NAME = 'DB00.db'; 74 const TBL_NAME = 'TBL00'; 75 const DDL_TBL_CREATE = "CREATE TABLE IF NOT EXISTS " 76 + TBL_NAME 77 + ' (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER, isStudent BOOLEAN, Binary BINARY)'; 78 79 let rdbStore; 80 let result; 81 82 export default class DataShareExtAbility extends Extension { 83 private rdbStore_; 84 85 // Override onCreate(). 86 onCreate(want, callback) { 87 result = this.context.cacheDir + '/datashare.txt'; 88 // Create an RDB store. 89 rdb.getRdbStore(this.context, { 90 name: DB_NAME, 91 securityLevel: rdb.SecurityLevel.S1 92 }, function (err, data) { 93 rdbStore = data; 94 rdbStore.executeSql(DDL_TBL_CREATE, [], (err) => { 95 console.info(`DataShareExtAbility onCreate, executeSql done err:${err}`); 96 }); 97 if (callback) { 98 callback(); 99 } 100 }); 101 } 102 103 // Override query(). 104 query(uri, predicates, columns, callback) { 105 if (predicates === null || predicates === undefined) { 106 console.info('invalid predicates'); 107 } 108 try { 109 rdbStore.query(TBL_NAME, predicates, columns, (err, resultSet) => { 110 if (resultSet !== undefined) { 111 console.info(`resultSet.rowCount:${resultSet.rowCount}`); 112 } 113 if (callback !== undefined) { 114 callback(err, resultSet); 115 } 116 }); 117 } catch (err) { 118 console.error(`Failed to query. Code:${err.code},message:${err.message}`); 119 } 120 } 121 // Override other APIs as required. 122 }; 123 ``` 124 1255. Define **DataShareExtensionAbility** in **module.json5**. 126 127 **Table 1** Fields in module.json5 128 129 | Field| Description| Mandatory| 130 | -------- | -------- | -------- | 131 | name | Ability name, corresponding to the **ExtensionAbility** class name derived from **Ability**.| Yes| 132 | type | Ability type. The value is **dataShare**, indicating the development is based on the **datashare** template.| Yes| 133 | uri | URI used for communication. It is the unique identifier for the data consumer to connect to the provider.| Yes| 134 | exported | Whether it is visible to other applications. Data sharing is allowed only when the value is **true**.| Yes| 135 | readPermission | Permission required for accessing data. If this parameter is not set, the read permission is not verified by default.| No| 136 | writePermission | Permission required for modifying data. If this parameter is not set, write permission verification is not performed by default.| No| 137 138 **module.json5 example** 139 140 141 ```json 142 "extensionAbilities": [ 143 { 144 "srcEntrance": "./ets/DataShareExtAbility/DataShareExtAbility.ts", 145 "name": "DataShareExtAbility", 146 "icon": "$media:icon", 147 "description": "$string:description_datashareextability", 148 "type": "dataShare", 149 "uri": "datashare://com.samples.datasharetest.DataShare", 150 "exported": true 151 } 152 ] 153 ``` 154 155 156### Data Consumer Application Development 157 1581. Import the dependencies. 159 160 ```js 161 import UIAbility from '@ohos.app.ability.UIAbility'; 162 import dataShare from '@ohos.data.dataShare'; 163 import dataSharePredicates from '@ohos.data.dataSharePredicates'; 164 ``` 165 1662. Define the URI string for communicating with the data provider. 167 168 ```js 169 // Different from the URI defined in the module.json5 file, the URI passed in the parameter has an extra slash (/), because there is a DeviceID parameter between the second and the third slash (/). 170 let dseUri = ('datashare:///com.samples.datasharetest.DataShare'); 171 ``` 172 1733. Create a **DataShareHelper** instance. 174 175 ```js 176 let dsHelper; 177 let abilityContext; 178 179 export default class EntryAbility extends UIAbility { 180 onWindowStageCreate(windowStage) { 181 abilityContext = this.context; 182 dataShare.createDataShareHelper(abilityContext, dseUri, (err, data) => { 183 dsHelper = data; 184 }); 185 } 186 } 187 ``` 188 1894. Use the APIs provided by **DataShareHelper** to access the services provided by the provider, for example, adding, deleting, modifying, and querying data. 190 191 ```js 192 // Construct a piece of data. 193 let valuesBucket = { 'name': 'ZhangSan', 'age': 21, 'isStudent': false, 'Binary': new Uint8Array([1, 2, 3]) }; 194 let updateBucket = { 'name': 'LiSi', 'age': 18, 'isStudent': true, 'Binary': new Uint8Array([1, 2, 3]) }; 195 let predicates = new dataSharePredicates.DataSharePredicates(); 196 let valArray = ['*']; 197 // Insert a piece of data. 198 dsHelper.insert(dseUri, valuesBucket, (err, data) => { 199 console.info(`dsHelper insert result:${data}`); 200 }); 201 // Update data. 202 dsHelper.update(dseUri, predicates, updateBucket, (err, data) => { 203 console.info(`dsHelper update result:${data}`); 204 }); 205 // Query data. 206 dsHelper.query(dseUri, predicates, valArray, (err, data) => { 207 console.info(`dsHelper query result:${data}`); 208 }); 209 // Delete data. 210 dsHelper.delete(dseUri, predicates, (err, data) => { 211 console.info(`dsHelper delete result:${data}`); 212 }); 213 ``` 214