• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# RelationalStore Development (C/C++)
2
3
4## When to Use
5
6The **RelationalStore** module provides a complete mechanism for local database management. You can use the APIs to add, delete, modify, and query data, and execute SQL statements in complex scenarios.
7
8
9## Basic Concepts
10
11- **Predicates**: a representation of the property or feature of a data entity, or the relationship between data entities, used to define operation conditions.
12
13- **ResultSet**: a set of query results, which allows access to the required data in flexible modes.
14
15
16## Constraints
17
18- By default, the Write Ahead Log (WAL) and the **FULL** flushing mode are used.
19
20- A maximum of four connection pools are used for read operations.
21
22- To ensure data accuracy, only one write operation is allowed at a time.
23
24- Once an application is uninstalled, related database files and temporary files are automatically deleted from the device.
25
26- Before using the device-cloud sync APIs added in API version 11, ensure that the cloud service is available.
27
28
29## Available APIs
30
31For details about the interfaces, see [RDB](../reference/apis-arkdata/_r_d_b.md).
32
33| API| Description|
34| -------- | -------- |
35| OH_Rdb_GetOrOpen(const OH_Rdb_Config *config, int *errCode) | Obtains an **OH_Rdb_Store** instance for RDB store operations.|
36| OH_Rdb_Execute(OH_Rdb_Store *store, const char *sql) | Executes an SQL statement that contains specified arguments but returns no value.|
37| OH_Rdb_Insert(OH_Rdb_Store *store, const char *table, OH_VBucket *valuesBucket) | Inserts a row of data into a table.|
38| OH_Rdb_Update(OH_Rdb_Store *store, OH_VBucket *valuesBucket, OH_Predicates *predicates) | Updates data in an RDB store. |
39| OH_Rdb_Delete(OH_Rdb_Store *store, OH_Predicates *predicates) | Deletes data from an RDB store. |
40| OH_Rdb_Query(OH_Rdb_Store *store, OH_Predicates *predicates, const char *const *columnNames, int length) | Queries data in an RDB store. |
41| OH_Rdb_DeleteStore(const OH_Rdb_Config *config) | Deletes an RDB store.|
42| OH_VBucket_PutAsset(OH_VBucket *bucket, const char *field, Rdb_Asset *value) | Puts an RDB asset into an **OH_VBucket** object.|
43| OH_VBucket_PutAssets(OH_VBucket *bucket, const char *field, Rdb_Asset *value, uint32_t count) | Puts RDB assets into an **OH_VBucket** object.|
44| OH_Rdb_SetDistributedTables(OH_Rdb_Store *store, const char *tables[], uint32_t count, Rdb_DistributedType type, const Rdb_DistributedConfig *config) | Sets distributed database tables.|
45| OH_Rdb_FindModifyTime(OH_Rdb_Store *store, const char *tableName, const char *columnName, OH_VObject *values) | Obtains the last modification time of the data in the specified column of a table. |
46| OH_Rdb_CloudSync(OH_Rdb_Store *store, Rdb_SyncMode mode, const char *tables[], uint32_t count, const Rdb_ProgressObserver *observer) | Manually performs device-cloud sync for a table. The cloud service must be available. |
47| int OH_Data_Asset_SetName(Data_Asset *asset, const char *name) | Sets the name for a data asset.|
48| int OH_Data_Asset_SetUri(Data_Asset *asset, const char *uri) | Sets the absolute path for a data asset.|
49| int OH_Data_Asset_SetPath(Data_Asset *asset, const char *path) | Sets the relative path in the application sandbox directory for a data asset.|
50| int OH_Data_Asset_SetCreateTime(Data_Asset *asset, int64_t createTime) | Sets the creation time for a data asset.|
51| int OH_Data_Asset_SetModifyTime(Data_Asset *asset, int64_t modifyTime) | Sets the last modification time for a data asset.|
52| int OH_Data_Asset_SetSize(Data_Asset *asset, size_t size) | Sets the size of a data asset.|
53| int OH_Data_Asset_SetStatus(Data_Asset *asset, Data_AssetStatus status) | Sets the status for a data asset.|
54| int OH_Data_Asset_GetName(Data_Asset *asset, char *name, size_t *length) | Obtains the name of a data asset.|
55| int OH_Data_Asset_GetUri(Data_Asset *asset, char *uri, size_t *length) | Obtains the absolute path of a data asset.|
56| int OH_Data_Asset_GetPath(Data_Asset *asset, char *path, size_t *length) | Obtains the relative path of a data asset.|
57| int OH_Data_Asset_GetCreateTime(Data_Asset *asset, int64_t *createTime) | Obtains the creation time of a data asset.|
58| int OH_Data_Asset_GetModifyTime(Data_Asset *asset, int64_t *modifyTime) | Obtains the last modification time of a data asset.|
59| int OH_Data_Asset_GetSize(Data_Asset *asset, size_t *size) | Obtains the size of a data asset.|
60| int OH_Data_Asset_GetStatus(Data_Asset *asset, Data_AssetStatus *status) | Obtains the status of a data asset.|
61| Data_Asset *OH_Data_Asset_CreateOne() | Creates a data asset instance. When this data asset is no longer needed, use **OH_Data_Asset_DestroyOne** to destroy it. |
62| int OH_Data_Asset_DestroyOne(Data_Asset *asset) | Destroys a data asset instance to reclaim memory.|
63| Data_Asset **OH_Data_Asset_CreateMultiple(uint32_t count) | Creates an instance for multiple data assets. When the instance is no longer required, use **OH_Data_Asset_DestroyMultiple** to destroy it. |
64| int OH_Data_Asset_DestroyMultiple(Data_Asset **assets, uint32_t count) | Destroys multiple data assets to reclaim memory.|
65| int OH_Rdb_Subscribe(OH_Rdb_Store *store, Rdb_SubscribeType type, const Rdb_DataObserver *observer) | Registers an observer for an RDB store. When the data in the distributed database changes, a callback will be invoked to return the data change.|
66| int OH_Rdb_Unsubscribe(OH_Rdb_Store *store, Rdb_SubscribeType type, const Rdb_DataObserver *observer) | Unregisters the observer of the specified type.|
67| int OH_Rdb_SubscribeAutoSyncProgress(OH_Rdb_Store *store, const Rdb_ProgressObserver *observer) | Subscribes to the auto sync process of an RDB store. The registered callback will be invoked to return the auto sync progress received.|
68| int OH_Rdb_UnsubscribeAutoSyncProgress(OH_Rdb_Store *store, const Rdb_ProgressObserver *observer) | Unsubscribes from the auto sync process of an RDB store.|
69
70
71## How to Develop
72
73**Adding the Dynamic Link Library**
74
75Add the following library to **CMakeLists.txt**:
76
77```txt
78libnative_rdb_ndk.z.so
79```
80
81**Including Header Files**
82
83```c++
84#include <database/data/data_asset.h>
85#include <database/rdb/oh_cursor.h>
86#include <database/rdb/oh_predicates.h>
87#include <database/rdb/oh_value_object.h>
88#include <database/rdb/oh_values_bucket.h>
89#include <database/rdb/relational_store.h>
90#include <database/rdb/relational_store_error_code.h>
91```
92
931. Obtain an **OH_Rdb_Store** instance and create a database file.
94
95   The **dataBaseDir** variable specifies the application sandbox path. In the stage model, you are advised to use the database directory. For details, see the **databaseDir** attribute of [Context](../reference/apis-ability-kit/js-apis-inner-application-context.md). The FA model does not provide any API for obtaining the database sandbox path. Use the application directory instead. For details, see **getFilesDir** of [Context](../reference/apis-ability-kit/js-apis-inner-app-context.md).
96
97   **area** indicates the security level of the directory for database files. For details, see [contextConstant](../reference/apis-ability-kit/js-apis-app-ability-contextConstant.md). During development, you need to implement the conversion from **AreaMode** to **Rdb_SecurityArea**.
98
99   Example:
100
101   ```c
102   // Create an OH_Rdb_Config object.
103   OH_Rdb_Config config;
104   // The path is the application sandbox path.
105   config.dataBaseDir = "xxx";
106   // Database file name.
107   config.storeName = "RdbTest.db";
108   // Application bundle name.
109   config.bundleName = "xxx";
110   // Module name.
111   config.moduleName = "xxx";
112   // Security level of the database file.
113   config.securityLevel = OH_Rdb_SecurityLevel::S3;
114   // Whether the database is encrypted.
115   config.isEncrypt = false;
116   // Memory size occupied by config.
117   config.selfSize = sizeof(OH_Rdb_Config);
118   // Security level of the directory for storing the database file.
119   config.area = RDB_SECURITY_AREA_EL1;
120
121   int errCode = 0;
122   // Obtain an OH_Rdb_Store instance.
123   OH_Rdb_Store *store_ = OH_Rdb_GetOrOpen(&config, &errCode);
124   ```
125
1262. Call **OH_Rdb_Execute** to create a table, and call **OH_Rdb_Insert** to insert data to the table. <br>Example:
127
128   ```c
129   char createTableSql[] = "CREATE TABLE IF NOT EXISTS EMPLOYEE (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT NOT NULL, "
130                           "AGE INTEGER, SALARY REAL, CODES BLOB)";
131   // Create a table.
132   OH_Rdb_Execute(store_, createTableSql);
133
134   // Create a key-value (KV) pair instance.
135   OH_VBucket *valueBucket = OH_Rdb_CreateValuesBucket();
136   valueBucket->putText(valueBucket, "NAME", "Lisa");
137   valueBucket->putInt64(valueBucket, "AGE", 18);
138   valueBucket->putReal(valueBucket, "SALARY", 100.5);
139   uint8_t arr[] = {1, 2, 3, 4, 5};
140   int len = sizeof(arr) / sizeof(arr[0]);
141   valueBucket->putBlob(valueBucket, "CODES", arr, len);
142   // Insert data.
143   int rowId = OH_Rdb_Insert(store_, "EMPLOYEE", valueBucket);
144   // Destroy the KV pair instance.
145   valueBucket->destroy(valueBucket);
146   ```
147
148   > **NOTE**
149   >
150   > **RelationalStore** does not provide explicit flush operations for data persistence. The **insert()** API stores data persistently.
151
1523. Modify or delete data based on the conditions specified by **OH_Predicates**.
153
154   Call **OH_Rdb_Update** to modify data, and call **OH_Rdb_Delete** to delete data. <br>Example:
155
156   ```c
157   // Modify data.
158   OH_VBucket *valueBucket = OH_Rdb_CreateValuesBucket();
159   valueBucket->putText(valueBucket, "NAME", "Rose");
160   valueBucket->putInt64(valueBucket, "AGE", 22);
161   valueBucket->putReal(valueBucket, "SALARY", 200.5);
162   uint8_t arr[] = {1, 2, 3, 4, 5};
163   int len = sizeof(arr) / sizeof(arr[0]);
164   valueBucket->putBlob(valueBucket, "CODES", arr, len);
165
166   OH_Predicates *predicates = OH_Rdb_CreatePredicates("EMPLOYEE");
167   OH_VObject *valueObject = OH_Rdb_CreateValueObject();
168   const char *name = "Lisa";
169   valueObject->putText(valueObject, name);
170   predicates->equalTo(predicates, "NAME", valueObject)->andOperate(predicates);
171   uint32_t count = 1;
172   double salary = 100.5;
173   valueObject->putDouble(valueObject, &salary, count);
174   predicates->equalTo(predicates, "SALARY", valueObject);
175
176   int changeRows = OH_Rdb_Update(store_, valueBucket, predicates);
177   valueObject->destroy(valueObject);
178   valueBucket->destroy(valueBucket);
179   predicates->destroy(predicates);
180   ```
181
182   ```c
183   // Delete data.
184   OH_Predicates *predicates = OH_Rdb_CreatePredicates("EMPLOYEE");
185   OH_VObject *valueObject = OH_Rdb_CreateValueObject();
186   const char *name = "Lisa";
187   valueObject->putText(valueObject, name);
188   predicates->equalTo(predicates, "NAME", valueObject);
189   int deleteRows = OH_Rdb_Delete(store_, predicates);
190   valueObject->destroy(valueObject);
191   predicates->destroy(predicates);
192   ```
193
1944. Query data based on the conditions specified by **OH_Predicates**.
195
196   Call **OH_Rdb_Query** to query data. The data obtained is returned in an **OH_Cursor** object. <br>Example:
197
198   ```c
199   OH_Predicates *predicates = OH_Rdb_CreatePredicates("EMPLOYEE");
200
201   const char *columnNames[] = {"NAME", "AGE"};
202   int len = sizeof(columnNames) / sizeof(columnNames[0]);
203   OH_Cursor *cursor = OH_Rdb_Query(store_, predicates, columnNames, len);
204
205   int columnCount = 0;
206   cursor->getColumnCount(cursor, &columnCount);
207
208   // OH_Cursor is a cursor of a data set. By default, the cursor points to the -1st record. Valid data starts from 0.
209   int64_t age;
210   while (cursor->goToNextRow(cursor) == OH_Rdb_ErrCode::RDB_OK) {
211       cursor->getInt64(cursor, 1, &age);
212   }
213
214   // Destroy the OH_Predicates instance.
215   predicates->destroy(predicates);
216   // Destroy the result set.
217   cursor->destroy(cursor);
218   ```
219
2205. Insert data assets into a table.
221
222   ```c
223   // If the column attribute is a single asset, use asset in the SQL statements. If the column attribute is multiple assets, use assets in the SQL statements.
224   char createAssetTableSql[] = "CREATE TABLE IF NOT EXISTS asset_table (id INTEGER PRIMARY KEY AUTOINCREMENT, data1 asset, data2 assets );";
225   errCode = OH_Rdb_Execute(store_, createAssetTableSql);
226   Data_Asset *asset = OH_Data_Asset_CreateOne();
227   OH_Data_Asset_SetName(asset, "name0");
228   OH_Data_Asset_SetUri(asset, "uri0");
229   OH_Data_Asset_SetPath(asset, "path0");
230   OH_Data_Asset_SetCreateTime(asset, 1);
231   OH_Data_Asset_SetModifyTime(asset, 1);
232   OH_Data_Asset_SetSize(asset, 1);
233   OH_Data_Asset_SetStatus(asset, Data_AssetStatus::ASSET_NORMAL);
234   errCode = OH_VBucket_PutAsset(valueBucket, "data1", asset);
235
236   Data_Asset **assets = OH_Data_Asset_CreateMultiple(2);
237
238   OH_Data_Asset_SetName(assets[0], "name0");
239   OH_Data_Asset_SetUri(assets[0], "uri0");
240   OH_Data_Asset_SetPath(assets[0], "path0");
241   OH_Data_Asset_SetCreateTime(assets[0], 1);
242   OH_Data_Asset_SetModifyTime(assets[0], 1);
243   OH_Data_Asset_SetSize(assets[0], 1);
244   OH_Data_Asset_SetStatus(assets[0], Data_AssetStatus::ASSET_NORMAL);
245
246   OH_Data_Asset_SetName(assets[1], "name1");
247   OH_Data_Asset_SetUri(assets[1], "uri1");
248   OH_Data_Asset_SetPath(assets[1], "path1");
249   OH_Data_Asset_SetCreateTime(assets[1], 1);
250   OH_Data_Asset_SetModifyTime(assets[1], 1);
251   OH_Data_Asset_SetSize(assets[1], 1);
252   OH_Data_Asset_SetStatus(assets[1], Data_AssetStatus::ASSET_NORMAL);
253
254   errCode = OH_VBucket_PutAssets(valueBucket, "data2", assets, assetsCount);
255   int rowID = OH_Rdb_Insert(cursorTestRdbStore_, table, valueBucket);
256   // Destroy Data_Asset* and Data_Asset**.
257   OH_Data_Asset_DestroyMultiple(assets, 2);
258   OH_Data_Asset_DestroyOne(asset);
259   ```
260
2616. Read data assets from the result set.
262
263   ```c
264   OH_Predicates *predicates = OH_Rdb_CreatePredicates("asset_table");
265
266   OH_Cursor *cursor = OH_Rdb_Query(cursorTestRdbStore_, predicates, NULL, 0);
267   cursor->goToNextRow(cursor);
268
269   uint32_t assetCount = 0;
270   // assetCount is an output parameter that indicates the number of assets in this column.
271   errCode = cursor->getAssets(cursor, 2, nullptr, &assetCount);
272   Data_Asset **assets = OH_Data_Asset_CreateMultiple(assetCount);
273   errCode = cursor->getAssets(cursor, 2, assets, &assetCount);
274   Data_Asset *asset = assets[1];
275
276   char name[10] = "";
277   size_t nameLength = 10;
278   errCode = OH_Data_Asset_GetName(asset, name, &nameLength);
279
280   char uri[10] = "";
281   size_t uriLength = 10;
282   errCode = OH_Data_Asset_GetUri(asset, uri, &uriLength);
283
284   char path[10] = "";
285   size_t pathLength = 10;
286   errCode = OH_Data_Asset_GetPath(asset, path, &pathLength);
287
288   int64_t createTime = 0;
289   errCode = OH_Data_Asset_GetCreateTime(asset, &createTime);
290
291   int64_t modifyTime = 0;
292   errCode = OH_Data_Asset_GetModifyTime(asset, &modifyTime);
293
294   size_t size = 0;
295   errCode = OH_Data_Asset_GetSize(asset, &size);
296
297   Data_AssetStatus status = Data_AssetStatus::ASSET_NULL;
298   errCode = OH_Data_Asset_GetStatus(asset, &status);
299
300   predicates->destroy(predicates);
301   OH_Data_Asset_DestroyMultiple(assets, assetCount);
302   cursor->destroy(cursor);
303   ```
304
3057. Obtain the last modification time of data.
306
307   Call **OH_Rdb_FindModifyTime** to obtain the last modification time of data in the specified column of a table. This API returns an **OH_Cursor** object with two columns of data. The first column is the input primary key or row ID, and the second column is the last modification time.
308
309   Example:
310
311   ```c
312   OH_VObject *values = OH_Rdb_CreateValueObject();
313   int64_t keys[] = { 1 };
314   values->putInt64(values, keys, 1);
315   OH_Cursor *cursor;
316   cursor = OH_Rdb_FindModifyTime(store_, "EMPLOYEE", "ROWID", values);
317   ```
318
3198. Create distributed tables.
320
321   Call **OH_Rdb_SetDistributedTables** to set distributed tables for the table (created by using **OH_Rdb_Execute**). Before using this API, ensure that the cloud service is available.
322
323   Example:
324
325   ```c
326   constexpr int TABLE_COUNT = 1;
327   const char *table[TABLE_COUNT];
328   table[0] = "EMPLOYEE";
329   int errcode = OH_Rdb_SetDistributedTables(store_, table, TABLE_COUNT, Rdb_DistributedType::DISTRIBUTED_CLOUD, &config);
330   ```
331
3329. Manually perform device-cloud sync for the distributed tables.
333
334   Call **OH_Rdb_CloudSync** to perform device-cloud sync for the tables. Before using this API, ensure that the cloud service is available.
335
336   Example:
337
338   ```c
339   // Define a callback.
340   void CloudSyncObserverCallback(void *context, Rdb_ProgressDetails *progressDetails)
341   {
342    // Do something.
343   }
344   const Rdb_ProgressObserver observer = { .context = nullptr, .callback = CloudSyncObserverCallback };
345   OH_Rdb_CloudSync(store_, Rdb_SyncMode::SYNC_MODE_TIME_FIRST, table, TABLE_COUNT, &observer);
346   ```
347
34810. Register a data observer for the specified event type for an RDB store. When the data changes, the registered callback will be invoked to process the observation.
349
350    Call **OH_Rdb_Subscribe** to subscribe to data changes. Before using this API, ensure that the cloud service is available.
351
352    Example:
353
354    ```c
355    // Define a callback.
356    void RdbSubscribeBriefCallback(void *context, const char *values[], uint32_t count)
357    {
358    // Do something.
359    }
360    Rdb_BriefObserver briefObserver;
361    const Rdb_BriefObserver briefObserver = { .context = nullptr, .callback = RdbSubscribeBriefCallback };
362    // Subscribe to data changes.
363    OH_Rdb_Subscribe(store_, Rdb_SubscribeType::RDB_SUBSCRIBE_TYPE_CLOUD, &briefObserver);
364    ```
365
366    Call **OH_Rdb_Subscribe** to subscribe to local database data changes. <br>Example:
367
368    ```c
369    // Define a callback.
370    void LocalDataChangeObserverCallback1(void *context, const Rdb_ChangeInfo **changeInfo, uint32_t count)
371    {
372       for (uint32_t i = 0; i < count; i++) {
373          EXPECT_EQ(DISTRIBUTED_CHANGE_INFO_VERSION, changeInfo[i]->version);
374          // The table name is employee.
375          changeInfo[i]->tableName;
376          changeInfo[i]->ChangeType;
377          // The number of added rows is 1.
378          changeInfo[i]->inserted.count;
379          // The number of updated rows is 0.
380          changeInfo[i]->updated.count;
381          // The number of deleted rows is 0.
382          changeInfo[i]->deleted.count;
383       }
384    }
385    Rdb_DetailsObserver callback = LocalDataChangeObserverCallback1;
386    Rdb_DataObserver observer = { nullptr, { callback } };
387    // Subscribe to the local database data changes.
388    OH_Rdb_Subscribe(store_, Rdb_SubscribeType::RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS, &observer);
389
390    OH_VBucket* valueBucket = OH_Rdb_CreateValuesBucket();
391    valueBucket->putText(valueBucket, "NAME", "Lisa");
392    valueBucket->putInt64(valueBucket, "AGE", 18);
393    valueBucket->putReal(valueBucket, "SALARY", 100.5);
394    uint8_t arr[] = {1, 2, 3, 4, 5};
395    int len = sizeof(arr) / sizeof(arr[0]);
396    valueBucket->putBlob(valueBucket, "CODES", arr, len);
397    // Insert data.
398    int rowId = OH_Rdb_Insert(store_, "EMPLOYEE", valueBucket);
399    // Destroy the KV pair instance.
400    valueBucket->destroy(valueBucket);
401    ```
402
40311. Unsubscribe from the events of the specified type for an RDB store. After that, the callback will not be invoked to process the observation.
404
405    Call **OH_Rdb_Unsubscribe** to unsubscribe from data changes. Before using this API, ensure that the cloud service is available.
406
407    Example:
408
409    ```c
410     // Define a callback.
411     void RdbSubscribeBriefCallback(void *context, const char *values[], uint32_t count)
412     {
413     // Do something.
414     }
415     Rdb_BriefObserver briefObserver = RdbSubscribeBriefCallback;
416     const Rdb_DataObserver briefObs = { .context = nullptr, .callback.briefObserver = briefObserver };
417     // Unsubscribe from data changes.
418     OH_Rdb_Unsubscribe(store_, Rdb_SubscribeType::RDB_SUBSCRIBE_TYPE_CLOUD, &briefObs);
419    ```
420    Call **OH_Rdb_Unsubscribe** to unsubscribe from local database data changes.
421
422    Example:
423
424    ```c
425     // Define a callback.
426     void LocalDataChangeObserverCallback1(void *context, const Rdb_ChangeInfo **changeInfo, uint32_t count)
427     {
428     // Do something.
429     }
430     Rdb_DetailsObserver callback = LocalDataChangeObserverCallback1;
431     Rdb_DataObserver observer = { nullptr, { callback } };
432     // Unsubscribe from the local database data changes.
433     OH_Rdb_Unsubscribe(store_, Rdb_SubscribeType::RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS, &observer);
434    ```
435
436
43712. Register an observer for auto sync progress of an RDB store. When auto sync is performed on the RDB store, the registered callback will be invoked to process the observation.
438
439    Call **OH_Rdb_SubscribeAutoSyncProgress** to subscribe to the auto sync progress. Before using this API, ensure that the cloud service is available.
440
441    Example:
442
443    ```c
444    // Define a callback.
445    void RdbProgressObserverCallback(void *context, Rdb_ProgressDetails *progressDetails)
446    {
447    // Do something.
448}
449    const Rdb_ProgressObserver observer = { .context = nullptr, .callback = RdbProgressObserverCallback };
450    OH_Rdb_SubscribeAutoSyncProgress(store_, &observer);
451    ```
452
45313. Unsubscribe from the auto sync progress from an RDB store. After that, the callback will not be invoked to process the observation.
454
455    Call **OH_Rdb_UnsubscribeAutoSyncProgress** to unsubscribe from the auto sync progress. Before using this API, ensure that the cloud service is available.
456
457    Example:
458
459    ```c
460    // Define a callback.
461    void RdbProgressObserverCallback(void *context, Rdb_ProgressDetails *progressDetails)
462    {
463    // Do something.
464    }
465    const Rdb_ProgressObserver observer = { .context = nullptr, .callback = RdbProgressObserverCallback };
466    OH_Rdb_UnsubscribeAutoSyncProgress(store_, &observer);
467    ```
468
46914. Delete an RDB store.
470
471    Call **OH_Rdb_DeleteStore** to delete the RDB store and related database file.
472
473    Example:
474
475    ```c
476    // Close the database instance.
477    OH_Rdb_CloseStore(store_);
478    // Delete the database file.
479    OH_Rdb_DeleteStore(&config);
480    ```
481
482
483
484
485
486
487