database-mdds-guidelines.md 10.1 KB
Newer Older
A
Annie_wang 已提交
1 2 3 4 5 6 7 8
# Distributed Data Service Development

## When to Use

The Distributed Data Service (DDS) implements synchronization of application data across user devices. When data is added, deleted, or modified for an application on a device, the same application on another device can obtain the updated data. The DDS applies to the distributed gallery, messages, contacts, and file manager.


## Available APIs
A
Annie_wang 已提交
9

10
For details about the APIs, see [Distributed KV Store](../reference/apis/js-apis-distributedKVStore.md).
A
Annie_wang 已提交
11 12 13

**Table 1** APIs provided by the DDS

14 15
| API                                                    | Description                                                        |
| ------------------------------------------------------------ | ------------------------------------------------------------ |
16
| createKVManager(config: KVManagerConfig): KVManager | Creates a **KvManager** object for database management.           |
A
Annie_wang 已提交
17
| getKVStore&lt;T extends KVStore&gt;(storeId: string, options: Options, callback: AsyncCallback&lt;T&gt;): void<br>getKVStore&lt;T extends KVStore&gt;(storeId: string, options: Options): Promise&lt;T&gt; | Creates and obtains a KV store.|
18 19
| put(key: string, value: Uint8Array\|string\|number\|boolean, callback: AsyncCallback&lt;void&gt;): void<br>put(key: string, value: Uint8Array\|string\|number\|boolean): Promise&lt;void> | Inserts and updates data.                                            |
| delete(key: string, callback: AsyncCallback&lt;void&gt;): void<br>delete(key: string): Promise&lt;void> | Deletes data.                                                  |
A
Annie_wang 已提交
20
| get(key: string, callback: AsyncCallback&lt;Uint8Array\|string\|boolean\|number&gt;): void<br>get(key: string): Promise&lt;Uint8Array\|string\|boolean\|number> | Obtains data.                                                  |
21
| on(event: 'dataChange', type: SubscribeType, observer: Callback&lt;ChangeNotification&gt;): void<br>on(event: 'syncComplete', syncCallback: Callback&lt;Array&lt;[string,number]&gt;&gt;): void | Subscribes to data changes in the KV store.                                    |
A
Annie_wang 已提交
22
| sync(deviceIdList: string[], mode: SyncMode, delayMs?: number): void | Triggers database synchronization in manual mode.                              |
A
Annie_wang 已提交
23 24

## How to Develop
Z
zengyawen 已提交
25 26 27

The following uses a single KV store as an example to describe the development procedure.

A
Annie_wang 已提交
28
1. Import the distributed data module.
A
Annie_wang 已提交
29

A
Annie_wang 已提交
30
   ```js
31
   import distributedKVStore from '@ohos.data.distributedKVStore';
A
Annie_wang 已提交
32
   ```
33

A
Annie_wang 已提交
34
2. Apply for the required permission if data synchronization is required.
A
Annie_wang 已提交
35

A
Annie_wang 已提交
36 37 38
   Add the permission required (FA model) in the **config.json** file. The sample code is as follows:

    ```json
39 40 41 42 43 44 45 46 47
    {
      "module": {
          "reqPermissions": [
              {
                 "name": "ohos.permission.DISTRIBUTED_DATASYNC"
              }
          ]
      }
    }
A
Annie_wang 已提交
48
    ```
49

A
Annie_wang 已提交
50 51 52 53 54
   For the apps based on the stage model, see [Declaring Permissions](../security/accesstoken-guidelines.md#stage-model).

   This permission must also be granted by the user when the application is started for the first time. The sample code is as follows:

    ```js
A
Annie_wang 已提交
55
    // FA model
A
Annie_wang 已提交
56
    import featureAbility from '@ohos.ability.featureAbility';
57
   
A
Annie_wang 已提交
58
    function grantPermission() {
A
Annie_wang 已提交
59 60 61 62 63
    console.info('grantPermission');
    let context = featureAbility.getContext();
    context.requestPermissionsFromUser(['ohos.permission.DISTRIBUTED_DATASYNC'], 666).then((data) => {
        console.info('success: ${data}');
    }).catch((error) => {
A
Annie_wang 已提交
64
        console.error('failed: ${error}');
A
Annie_wang 已提交
65
    })
A
Annie_wang 已提交
66
    }
67
   
A
Annie_wang 已提交
68
    grantPermission();
69
   
A
Annie_wang 已提交
70
    // Stage model
A
Annie_wang 已提交
71 72
    import UIAbility from '@ohos.app.ability.UIAbility';
  
A
Annie_wang 已提交
73
    let context = null;
A
Annie_wang 已提交
74 75
  
    class EntryAbility extends UIAbility {
A
Annie_wang 已提交
76
      onWindowStageCreate(windowStage) {
A
Annie_wang 已提交
77
        let context = this.context;
A
Annie_wang 已提交
78
      }
A
Annie_wang 已提交
79
    }
A
Annie_wang 已提交
80
  
A
Annie_wang 已提交
81 82 83
    function grantPermission() {
      let permissions = ['ohos.permission.DISTRIBUTED_DATASYNC'];
      context.requestPermissionsFromUser(permissions).then((data) => {
A
Annie_wang 已提交
84
        console.log('success: ${data}');
A
Annie_wang 已提交
85 86 87
      }).catch((error) => {
        console.error('failed: ${error}');
      });
A
Annie_wang 已提交
88
    }
A
Annie_wang 已提交
89
  
A
Annie_wang 已提交
90 91 92
    grantPermission();
    ```

93
3. Create a **KvManager** instance based on the specified **KvManagerConfig** object.
A
Annie_wang 已提交
94 95

   1. Create a **kvManagerConfig** object based on the application context.
96
   2. Create a **KvManager** instance.
A
Annie_wang 已提交
97 98

   The sample code is as follows:
A
Annie_wang 已提交
99 100

   ```js
A
Annie_wang 已提交
101 102 103
   // Obtain the context of the FA model.
   import featureAbility from '@ohos.ability.featureAbility';
   let context = featureAbility.getContext();
104
   
A
Annie_wang 已提交
105
   // Obtain the context of the stage model.
A
Annie_wang 已提交
106
   import UIAbility from '@ohos.app.ability.UIAbility';
A
Annie_wang 已提交
107
   let context = null;
A
Annie_wang 已提交
108
   class EntryAbility extends UIAbility {
A
Annie_wang 已提交
109 110 111 112
      onWindowStageCreate(windowStage){
        context = this.context;
      }
   }
113
   
A
Annie_wang 已提交
114 115
   let kvManager;
   try {
A
Annie_wang 已提交
116 117
     const kvManagerConfig = {
       bundleName: 'com.example.datamanagertest',
118
       context:context,
A
Annie_wang 已提交
119
     }
120 121
     kvManager = distributedKVStore.createKVManager(kvManagerConfig);
     console.log("Created KVManager successfully");
A
Annie_wang 已提交
122
   } catch (e) {
123
     console.error(`Failed to create KVManager. Code is ${e.code}, message is ${e.message}`);
A
Annie_wang 已提交
124 125
   }
   ```
A
Annie_wang 已提交
126

A
Annie_wang 已提交
127
4. Create and obtain a single KV store.
A
Annie_wang 已提交
128

A
Annie_wang 已提交
129 130
   1. Declare the ID of the single KV store to create.
   2. Create a single KV store. You are advised to disable automatic synchronization (`autoSync:false`) and call `sync` when a synchronization is required.
A
Annie_wang 已提交
131 132

   The sample code is as follows:
A
Annie_wang 已提交
133

A
Annie_wang 已提交
134 135 136
   ```js
   let kvStore;
   try {
A
Annie_wang 已提交
137 138 139 140 141
     const options = {
       createIfMissing: true,
       encrypt: false,
       backup: false,
       autoSync: false,
142 143
       kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION,
       securityLevel: distributedKVStore.SecurityLevel.S1
A
Annie_wang 已提交
144 145 146
     };
     kvManager.getKVStore('storeId', options, function (err, store) {
       if (err) {
147
         console.error(`Failed to get KVStore: code is ${err.code}, message is ${err.message}`);
A
Annie_wang 已提交
148 149
         return;
       }
150
       console.log('Obtained KVStore successfully');
A
Annie_wang 已提交
151 152
       kvStore = store;
     });
A
Annie_wang 已提交
153
   } catch (e) {
154
     console.error(`An unexpected error occurred. Code is ${e.code}, message is ${e.message}`);
A
Annie_wang 已提交
155 156 157
   }
   ```

A
Annie_wang 已提交
158
   > **NOTE**<br>
A
Annie_wang 已提交
159 160
   >
   > For data synchronization between networked devices, you are advised to open the distributed KV store during application startup to obtain the database handle. With this database handle (`kvStore` in this example), you can perform operations, such as inserting data into the KV store, without creating the KV store repeatedly during the lifecycle of the handle.
161

A
Annie_wang 已提交
162
5. Subscribe to changes in the distributed data.
A
Annie_wang 已提交
163 164

   The following is the sample code for subscribing to the data changes of a single KV store:
A
Annie_wang 已提交
165

A
Annie_wang 已提交
166
   ```js
167 168 169 170 171
   try{
       kvStore.on('dataChange', distributedKVStore.SubscribeType.SUBSCRIBE_TYPE_ALL, function (data) {
           console.log(`dataChange callback call data: ${data}`);
       });
   }catch(e){
172
       console.error(`An unexpected error occured. Code is ${e.code}, message is ${e.message}`);
173
   }
A
Annie_wang 已提交
174 175
   ```

A
Annie_wang 已提交
176
6. Write data to the single KV store.
A
Annie_wang 已提交
177

A
Annie_wang 已提交
178 179
   1. Construct the `Key` and `Value` to be written into the single KV store.
   2. Write key-value pairs into the single KV store.
A
Annie_wang 已提交
180 181 182 183 184 185 186

   The following is the sample code for writing key-value pairs of the string type into the single KV store:

   ```js
   const KEY_TEST_STRING_ELEMENT = 'key_test_string';
   const VALUE_TEST_STRING_ELEMENT = 'value-test-string';
   try {
187
       kvStore.put(KEY_TEST_STRING_ELEMENT, VALUE_TEST_STRING_ELEMENT, function (err,data) {
A
Annie_wang 已提交
188
           if (err != undefined) {
189
               console.error(`Failed to put data. Code is ${err.code}, message is ${err.message}`);
A
Annie_wang 已提交
190 191
               return;
           }
192
           console.log("Put data successfully");
A
Annie_wang 已提交
193
       });
194
   }catch (e) {
195
       console.error(`An unexpected error occurred. Code is ${e.code}, message is ${e.message}`);
A
Annie_wang 已提交
196 197 198
   }
   ```

A
Annie_wang 已提交
199
7. Query data in the single KV store.
A
Annie_wang 已提交
200

A
Annie_wang 已提交
201 202
   1. Construct the `Key` to be queried from the single KV store.
   2. Query data from the single KV store.
A
Annie_wang 已提交
203 204

   The following is the sample code for querying data of the string type from the single KV store:
A
Annie_wang 已提交
205

A
Annie_wang 已提交
206 207 208 209
   ```js
   const KEY_TEST_STRING_ELEMENT = 'key_test_string';
   const VALUE_TEST_STRING_ELEMENT = 'value-test-string';
   try {
210
       kvStore.put(KEY_TEST_STRING_ELEMENT, VALUE_TEST_STRING_ELEMENT, function (err,data) {
A
Annie_wang 已提交
211
           if (err != undefined) {
212
               console.error(`Failed to put data. Code is ${err.code}, message is ${err.message}`);
A
Annie_wang 已提交
213 214
               return;
           }
215
           console.log("Put data successfully");
216 217
           kvStore.get(KEY_TEST_STRING_ELEMENT, function (err,data) {
           if (err != undefined) {
218
               console.error(`Failed to obtain data. Code is ${err.code}, message is ${err.message}`);
219 220 221
               return;
           }
               console.log(`Obtained data successfully:${data}`);
A
Annie_wang 已提交
222 223
           });
       });
224
   }catch (e) {
225
       console.error(`Failed to obtain data. Code is ${e.code}, message is ${e.message}`);
A
Annie_wang 已提交
226 227 228
   }
   ```

A
Annie_wang 已提交
229 230
8. Synchronize data to other devices.

A
Annie_wang 已提交
231 232
   Select the devices in the same network and the synchronization mode to synchronize data.

A
Annie_wang 已提交
233
   > **NOTE**<br>
A
Annie_wang 已提交
234 235
   >
   > The APIs of the `deviceManager` module are system interfaces.
236

A
Annie_wang 已提交
237
   The following is the example code for synchronizing data in a single KV store:
A
Annie_wang 已提交
238

A
Annie_wang 已提交
239 240 241 242 243
   ```js
   import deviceManager from '@ohos.distributedHardware.deviceManager';
   
   let devManager;
   // Create deviceManager.
A
Annie_wang 已提交
244
   deviceManager.createDeviceManager('bundleName', (err, value) => {
A
Annie_wang 已提交
245 246
       if (!err) {
           devManager = value;
A
Annie_wang 已提交
247
           // deviceIds is obtained by deviceManager by calling getTrustedDeviceListSync().
A
Annie_wang 已提交
248 249 250 251 252 253 254 255
           let deviceIds = [];
           if (devManager != null) {
               var devices = devManager.getTrustedDeviceListSync();
               for (var i = 0; i < devices.length; i++) {
                   deviceIds[i] = devices[i].deviceId;
               }
           }
           try{
A
Annie_wang 已提交
256
               // 1000 indicates that the maximum delay is 1000 ms.
257
               kvStore.sync(deviceIds, distributedKVStore.SyncMode.PUSH_ONLY, 1000);
A
Annie_wang 已提交
258
           } catch (e) {
259
                console.error(`An unexpected error occurred. Code is ${e.code}, message is ${e.message}`);
A
Annie_wang 已提交
260 261 262 263
           }
       }
   });
   ```