1# Data Ability Development 2 3## When to Use 4 5A Data ability helps applications manage access to data stored by themselves and other applications. It also provides APIs for sharing data with other applications either on the same device or across devices. 6 7Data ability providers can customize data access-related APIs such as data inserting, deleting, updating, and querying, as well as file opening, and share data with other applications through these open APIs. 8 9## URI Introduction 10 11A Uniform Resource Identifier (URI) is used to identify a specific data item, such as a table in the database or a file on the disk. URIs used in OpenHarmony comply with the commonly used URI standard. A URI consists of the components: 12 13![fa-dataability-uri](figures/fa-dataability-uri.png) 14 15- **scheme**: name of the scheme used by the Data ability. The value is fixed at **dataability**. 16- **authority**: device ID. To access data on a remote device, set this component to the ID of the remote device. To access data on the local device, leave this component empty. 17- **path**: location of the specific resource to access. 18- **query**: query parameters. 19- **fragment**: subordinate resources to access. 20 21Example URIs: 22 23- Cross-device communication: **dataability://***device_id***/***com.domainname.dataability.persondata***/***person***/***10* 24- Local-device communication: **dataability:///***com.domainname.dataability.persondata***/***person***/***10* 25 26> **NOTE** 27> 28> In the case of local-device communication, **device_id** is empty, and therefore, there are three slashes (/) after **dataability:**. 29 30## Available APIs 31 32**Table 1** Data ability lifecycle APIs 33|API|Description| 34|:------|:------| 35|onInitialized(info: AbilityInfo): void|Called during ability initialization to initialize the relational database (RDB).| 36|update(uri: string, valueBucket: rdb.ValuesBucket, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback\<number>): void|Updates data in the database.| 37|query(uri: string, columns: Array\<string>, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback\<ResultSet>): void|Queries data in the database.| 38|delete(uri: string, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback\<number>): void|Deletes one or more data records from the database.| 39|normalizeUri(uri: string, callback: AsyncCallback\<string>): void|Normalizes the URI. A normalized URI applies to cross-device use, persistence, backup, and restore. When the context changes, it ensures that the same data item can be referenced.| 40|batchInsert(uri: string, valueBuckets: Array\<rdb.ValuesBucket>, callback: AsyncCallback\<number>): void|Inserts multiple data records into the database.| 41|denormalizeUri(uri: string, callback: AsyncCallback\<string>): void|Converts a normalized URI generated by **normalizeUri** into a denormalized URI.| 42|insert(uri: string, valueBucket: rdb.ValuesBucket, callback: AsyncCallback\<number>): void|Inserts a data record into the database.| 43|openFile(uri: string, mode: string, callback: AsyncCallback\<number>): void|Opens a file.| 44|getFileTypes(uri: string, mimeTypeFilter: string, callback: AsyncCallback\<Array\<string>>): void|Obtains the MIME type of a file.| 45|getType(uri: string, callback: AsyncCallback\<string>): void|Obtains the MIME type matching the data specified by the URI.| 46|executeBatch(ops: Array\<DataAbilityOperation>, callback: AsyncCallback\<Array\<DataAbilityResult>>): void|Operates data in the database in batches.| 47|call(method: string, arg: string, extras: PacMap, callback: AsyncCallback\<PacMap>): void|Calls a custom API.| 48 49 50## How to Develop 51### Creating a Data Ability 52 531. To meet the basic requirements of the database storage service, implement the **Insert**, **Query**, **Update**, and **Delete** APIs in the **Data** class. The **BatchInsert** and **ExecuteBatch** APIs have already implemented the traversal logic, but not batch data processing. 54 55 The following code snippet shows how to create a Data ability: 56 57 ```javascript 58 import featureAbility from '@ohos.ability.featureAbility' 59 import dataAbility from '@ohos.data.dataAbility' 60 import dataRdb from '@ohos.data.rdb' 61 62 const TABLE_NAME = 'book' 63 const STORE_CONFIG = { name: 'book.db' } 64 const SQL_CREATE_TABLE = 'CREATE TABLE IF NOT EXISTS book(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, introduction TEXT NOT NULL)' 65 let rdbStore: dataRdb.RdbStore = undefined 66 67 export default { 68 onInitialized(abilityInfo) { 69 console.info('DataAbility onInitialized, abilityInfo:' + abilityInfo.bundleName) 70 let context = featureAbility.getContext() 71 dataRdb.getRdbStore(context, STORE_CONFIG, 1, (err, store) => { 72 console.info('DataAbility getRdbStore callback') 73 store.executeSql(SQL_CREATE_TABLE, []) 74 rdbStore = store 75 }); 76 }, 77 insert(uri, valueBucket, callback) { 78 console.info('DataAbility insert start') 79 rdbStore.insert(TABLE_NAME, valueBucket, callback) 80 }, 81 batchInsert(uri, valueBuckets, callback) { 82 console.info('DataAbility batch insert start') 83 for (let i = 0;i < valueBuckets.length; i++) { 84 console.info('DataAbility batch insert i=' + i) 85 if (i < valueBuckets.length - 1) { 86 rdbStore.insert(TABLE_NAME, valueBuckets[i], (err: any, num: number) => { 87 console.info('DataAbility batch insert ret=' + num) 88 }) 89 } else { 90 rdbStore.insert(TABLE_NAME, valueBuckets[i], callback) 91 } 92 } 93 }, 94 query(uri, columns, predicates, callback) { 95 console.info('DataAbility query start') 96 let rdbPredicates = dataAbility.createRdbPredicates(TABLE_NAME, predicates) 97 rdbStore.query(rdbPredicates, columns, callback) 98 }, 99 update(uri, valueBucket, predicates, callback) { 100 console.info('DataAbilityupdate start') 101 let rdbPredicates = dataAbility.createRdbPredicates(TABLE_NAME, predicates) 102 rdbStore.update(valueBucket, rdbPredicates, callback) 103 }, 104 delete(uri, predicates, callback) { 105 console.info('DataAbilitydelete start') 106 let rdbPredicates = dataAbility.createRdbPredicates(TABLE_NAME, predicates) 107 rdbStore.delete(rdbPredicates, callback) 108 } 109 }; 110 ``` 111 1122. Configure the submodule. 113 114 | JSON Field| Description | 115 | ------------ | ------------------------------------------------------------ | 116 | "name" | Ability name, corresponding to the **Data** class name derived from **Ability**. | 117 | "type" | Ability type, which is **Data** for a Data ability. | 118 | "uri" | URI used for communication. | 119 | "exported" | Whether the Data ability is visible to other applications. When this parameter is set to **true**, the Data ability can communicate with other applications.| 120 121 **config.json configuration example** 122 123 ```json 124 "abilities":[{ 125 "srcPath": "DataAbility", 126 "name": ".DataAbility", 127 "icon": "$media:icon", 128 "srcLanguage": "ets", 129 "description": "$string:description_dataability", 130 "type": "data", 131 "exported": true, 132 "uri": "dataability://ohos.samples.etsdataability.DataAbility" 133 }] 134 ``` 135 136### Accessing a Data ability 137#### Development Preparations 138 139Import the basic dependency packages and obtain the URI string for communicating with the Data submodule. 140 141The basic dependency packages include: 142- @ohos.ability.featureAbility 143- @ohos.data.dataAbility 144- @ohos.data.rdb 145 146#### Data Ability API Development 147 148 1491. Create a Data ability helper. 150 151 For details about the APIs provided by **DataAbilityHelper**, see [DataAbilityHelper Module](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md). 152 ```js 153 // Different from the URI defined in the config.json file, the URI passed in the parameter has an extra slash (/), because there is a DeviceID parameter between the second and the third slash (/). 154 import featureAbility from '@ohos.ability.featureAbility' 155 import ohos_data_ability from '@ohos.data.dataAbility' 156 import ohos_data_rdb from '@ohos.data.rdb' 157 158 var urivar = "dataability:///com.ix.DataAbility" 159 var DAHelper = featureAbility.acquireDataAbilityHelper( 160 urivar 161 ); 162 ``` 1632. Construct RDB data. 164 ```js 165 var valuesBucket = {"name": "gaolu"} 166 var da = new ohos_data_ability.DataAbilityPredicates() 167 var valArray =new Array("value1"); 168 var cars = new Array({"batchInsert1" : "value1",}); 169 ``` 1703. Use **insert** to insert data to the Data submodule. 171 ```js 172 // Callback mode: 173 DAHelper.insert( 174 urivar, 175 valuesBucket, 176 (error, data) => { 177 console.log("DAHelper insert result: " + data) 178 } 179 ); 180 ``` 181 182 ```js 183 // Promise mode: 184 var datainsert = await DAHelper.insert( 185 urivar, 186 valuesBucket 187 ); 188 ``` 1894. Use **delete** to delete data from the Data submodule. 190 ```js 191 // Callback mode: 192 DAHelper.delete( 193 urivar, 194 da, 195 (error, data) => { 196 console.log("DAHelper delete result: " + data) 197 } 198 ); 199 ``` 200 201 ```js 202 // Promise mode: 203 var datadelete = await DAHelper.delete( 204 urivar, 205 da, 206 ); 207 ``` 2085. Use **update** to update data in the Data submodule. 209 ```js 210 // Callback mode: 211 DAHelper.update( 212 urivar 213 valuesBucket, 214 da, 215 (error, data) => { 216 console.log("DAHelper update result: " + data) 217 } 218 ); 219 ``` 220 221 ```js 222 // Promise mode: 223 var dataupdate = await DAHelper.update( 224 urivar, 225 valuesBucket, 226 da, 227 ); 228 ``` 2296. Use **query** to query data in the Data submodule. 230 ```js 231 // Callback mode: 232 DAHelper.query( 233 urivar, 234 valArray, 235 da, 236 (error, data) => { 237 console.log("DAHelper query result: " + data) 238 } 239 ); 240 ``` 241 242 ```js 243 // Promise mode: 244 var dataquery = await DAHelper.query( 245 urivar, 246 valArray, 247 da 248 ); 249 ``` 2507. Use **batchInsert** to insert data in batches to the Data submodule. 251 ```js 252 // Callback mode: 253 DAHelper.batchInsert( 254 urivar, 255 cars, 256 (error, data) => { 257 console.log("DAHelper batchInsert result: " + data) 258 } 259 ); 260 ``` 261 262 ```js 263 // Promise mode: 264 var databatchInsert = await DAHelper.batchInsert( 265 urivar, 266 cars 267 ); 268 ``` 2698. Use **executeBatch** to process data in batches in the Data submodule. 270 ```js 271 // Callback mode: 272 DAHelper.executeBatch( 273 urivar, 274 [ 275 { 276 uri: urivar, 277 type: featureAbility.DataAbilityOperationType.TYPE_INSERT, 278 valuesBucket: {"executeBatch" : "value1",}, 279 predicates: da, 280 expectedCount:0, 281 predicatesBackReferences: null, 282 interrupted:true, 283 } 284 ], 285 (error, data) => { 286 console.log("DAHelper executeBatch result: " + data) 287 } 288 ); 289 ``` 290 291 ```js 292 // Promise mode: 293 var dataexecuteBatch = await DAHelper.executeBatch( 294 urivar, 295 [ 296 { 297 uri: urivar, 298 type: featureAbility.DataAbilityOperationType.TYPE_INSERT, 299 valuesBucket: 300 { 301 "executeBatch" : "value1", 302 }, 303 predicates: da, 304 expectedCount:0, 305 predicatesBackReferences: null, 306 interrupted:true, 307 } 308 ] 309 ); 310 ``` 311