database-mdds-guidelines.md 9.8 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
For details about the APIs, see [Distributed Data Management](../reference/apis/js-apis-distributed-data.md).
A
Annie_wang 已提交
10

A
Annie_wang 已提交
11 12 13

**Table 1** APIs provided by the DDS

A
Annie_wang 已提交
14 15
| API                                                    | Description                                           |
| ------------------------------------------------------------ | ----------------------------------------------- |
A
Annie_wang 已提交
16 17 18 19 20 21 22
| createKVManager(config: KVManagerConfig, callback: AsyncCallback&lt;KVManager&gt;): void<br>createKVManager(config: KVManagerConfig): Promise&lt;KVManager> | Creates a **KVManager** object for database management.|
| getKVStore&lt;TextendsKVStore&gt;(storeId: string, options: Options, callback: AsyncCallback&lt;T&gt;): void<br>getKVStore&lt;TextendsKVStore&gt;(storeId: string, options: Options): Promise&lt;T&gt; | Obtains a KV store with the specified **Options** and **storeId**.|
| 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.                                     |
| get(key: string, callback: AsyncCallback&lt;Uint8Array\|string\|boolean\|number&gt;): void<br>get(key: string): Promise&lt;Uint8Array\|string\|boolean\|number> | Queries data.                                     |
| 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.                       |
| sync(deviceIdList: string[], mode: SyncMode, allowedDelayMs?: 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 31 32
   ```js
   import distributedData from '@ohos.data.distributedData';
   ```
A
Annie_wang 已提交
33
2. Apply for the required permission if data synchronization is required.
A
Annie_wang 已提交
34

A
Annie_wang 已提交
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
   Add the permission required (FA model) in the **config.json** file. The sample code is as follows:

    ```json
     {
       "module": {
           "reqPermissions": [
               {
                  "name": "ohos.permission.DISTRIBUTED_DATASYNC"
               }
           ]
       }
     }
    ```
   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 已提交
53
    // FA model
A
Annie_wang 已提交
54
    import featureAbility from '@ohos.ability.featureAbility';
A
Annie_wang 已提交
55

A
Annie_wang 已提交
56
    function grantPermission() {
A
Annie_wang 已提交
57 58 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) => {
        console.info('failed: ${error}');
    })
A
Annie_wang 已提交
64
    }
A
Annie_wang 已提交
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87

    grantPermission();

    // Stage model
    import Ability from '@ohos.application.Ability';

    let context = null;

    function grantPermission() {
    class MainAbility extends Ability {
        onWindowStageCreate(windowStage) {
        let context = this.context;
        }
    }

    let permissions = ['ohos.permission.DISTRIBUTED_DATASYNC'];
    context.requestPermissionsFromUser(permissions).then((data) => {
        console.log('success: ${data}');
    }).catch((error) => {
        console.log('failed: ${error}');
    });
    }

A
Annie_wang 已提交
88 89 90 91 92 93 94
    grantPermission();
    ```

3. Create a **kvManager** instance based on the specified **kvManagerConfig** object.

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

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

   ```js
A
Annie_wang 已提交
99 100 101 102 103 104 105 106 107 108 109 110 111
   // Obtain the context of the FA model.
   import featureAbility from '@ohos.ability.featureAbility';
   let context = featureAbility.getContext();

   // Obtain the context of the stage model.
   import AbilityStage from '@ohos.application.Ability';
   let context = null;
   class MainAbility extends AbilityStage{
      onWindowStageCreate(windowStage){
        context = this.context;
      }
   }

A
Annie_wang 已提交
112 113
   let kvManager;
   try {
A
Annie_wang 已提交
114 115 116
     const kvManagerConfig = {
       bundleName: 'com.example.datamanagertest',
       userInfo: {
A
Annie_wang 已提交
117
         context:context,
A
Annie_wang 已提交
118 119
         userId: '0',
         userType: distributedData.UserType.SAME_USER_ID
A
Annie_wang 已提交
120
       }
A
Annie_wang 已提交
121 122 123
     }
     distributedData.createKVManager(kvManagerConfig, function (err, manager) {
       if (err) {
A
Annie_wang 已提交
124
         console.log('Failed to create KVManager: ${error}');
A
Annie_wang 已提交
125 126
         return;
       }
A
Annie_wang 已提交
127
       console.log('Created KVManager successfully');
A
Annie_wang 已提交
128 129
       kvManager = manager;
     });
A
Annie_wang 已提交
130
   } catch (e) {
A
Annie_wang 已提交
131
     console.log('An unexpected error occurred. Error:  ${e}');
A
Annie_wang 已提交
132 133
   }
   ```
A
Annie_wang 已提交
134

A
Annie_wang 已提交
135
4. Create and obtain a single KV store.
A
Annie_wang 已提交
136

A
Annie_wang 已提交
137 138
   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 已提交
139 140

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

A
Annie_wang 已提交
142 143 144
   ```js
   let kvStore;
   try {
A
Annie_wang 已提交
145 146 147 148 149 150 151 152 153 154
     const options = {
       createIfMissing: true,
       encrypt: false,
       backup: false,
       autoSync: false,
       kvStoreType: distributedData.KVStoreType.SINGLE_VERSION,
       securityLevel: distributedData.SecurityLevel.S0
     };
     kvManager.getKVStore('storeId', options, function (err, store) {
       if (err) {
A
Annie_wang 已提交
155
         console.log('Failed to get KVStore: ${err}');
A
Annie_wang 已提交
156 157
         return;
       }
A
Annie_wang 已提交
158
       console.log('Got KVStore successfully');
A
Annie_wang 已提交
159 160
       kvStore = store;
     });
A
Annie_wang 已提交
161
   } catch (e) {
A
Annie_wang 已提交
162
     console.log('An unexpected error occurred. Error:  ${e}');
A
Annie_wang 已提交
163 164 165
   }
   ```

A
Annie_wang 已提交
166
   > **NOTE**<br>
A
Annie_wang 已提交
167 168
   >
   > 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.
A
Annie_wang 已提交
169 170
   
5. Subscribe to changes in the distributed data.
A
Annie_wang 已提交
171 172

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

A
Annie_wang 已提交
174 175
   ```js
   kvStore.on('dataChange', distributedData.SubscribeType.SUBSCRIBE_TYPE_ALL, function (data) {
A
Annie_wang 已提交
176
       console.log("dataChange callback call data:  ${data}");
A
Annie_wang 已提交
177 178 179
   });
   ```

A
Annie_wang 已提交
180
6. Write data to the single KV store.
A
Annie_wang 已提交
181

A
Annie_wang 已提交
182 183
   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 已提交
184 185 186 187 188 189 190

   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 {
A
Annie_wang 已提交
191
       kvStore.put(KEY_TEST_STRING_ELEMENT, VALUE_TEST_STRING_ELEMENT, function (err, data) {
A
Annie_wang 已提交
192
           if (err != undefined) {
A
Annie_wang 已提交
193
               console.log('Failed to put data:  ${error}');
A
Annie_wang 已提交
194 195
               return;
           }
A
Annie_wang 已提交
196
           console.log('Put data successfully');
A
Annie_wang 已提交
197
       });
A
Annie_wang 已提交
198
   } catch (e) {
A
Annie_wang 已提交
199
       console.log('An unexpected error occurred. Error:  ${e}');
A
Annie_wang 已提交
200 201 202
   }
   ```

A
Annie_wang 已提交
203
7. Query data in the single KV store.
A
Annie_wang 已提交
204

A
Annie_wang 已提交
205 206
   1. Construct the `Key` to be queried from the single KV store.
   2. Query data from the single KV store.
A
Annie_wang 已提交
207 208

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

A
Annie_wang 已提交
210 211 212 213
   ```js
   const KEY_TEST_STRING_ELEMENT = 'key_test_string';
   const VALUE_TEST_STRING_ELEMENT = 'value-test-string';
   try {
A
Annie_wang 已提交
214
       kvStore.put(KEY_TEST_STRING_ELEMENT, VALUE_TEST_STRING_ELEMENT, function (err, data) {
A
Annie_wang 已提交
215
           if (err != undefined) {
A
Annie_wang 已提交
216
               console.log('Failed to put data:  ${error}');
A
Annie_wang 已提交
217 218
               return;
           }
A
Annie_wang 已提交
219
           console.log('Put data successfully');
A
Annie_wang 已提交
220
           kvStore.get(KEY_TEST_STRING_ELEMENT, function (err, data) {
A
Annie_wang 已提交
221
               console.log('Got data successfully:  ${data}');
A
Annie_wang 已提交
222 223
           });
       });
A
Annie_wang 已提交
224
   } catch (e) {
A
Annie_wang 已提交
225
       console.log('An unexpected error occurred. Error:  ${e}');
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.
A
Annie_wang 已提交
236 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.
A
Annie_wang 已提交
257
               kvStore.sync(deviceIds, distributedData.SyncMode.PUSH_ONLY, 1000);
A
Annie_wang 已提交
258
           } catch (e) {
A
Annie_wang 已提交
259
                console.log('An unexpected error occurred. Error:  ${e}');
A
Annie_wang 已提交
260 261 262 263
           }
       }
   });
   ```