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, call **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, call **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**. <br>Example:
98
99   ```c
100   // Create an OH_Rdb_Config object.
101   OH_Rdb_Config config;
102   // The path is the application sandbox path.
103   config.dataBaseDir = "xxx";
104   // Database file name.
105   config.storeName = "RdbTest.db";
106   // Application bundle name.
107   config.bundleName = "xxx";
108   // Module name.
109   config.moduleName = "xxx";
110   // Security level of the database file.
111   config.securityLevel = OH_Rdb_SecurityLevel::S3;
112   // Whether the database is encrypted.
113   config.isEncrypt = false;
114   // Memory size occupied by config.
115   config.selfSize = sizeof(OH_Rdb_Config);
116   // Security level of the directory for storing the database file.
117   config.area = RDB_SECURITY_AREA_EL1;
118
119   int errCode = 0;
120   // Obtain an OH_Rdb_Store instance.
121   OH_Rdb_Store *store_ = OH_Rdb_GetOrOpen(&config, &errCode);
122   ```
123
1242. Call **OH_Rdb_Execute** to create a table, and call **OH_Rdb_Insert** to insert data to the table. <br>Example:
125
126   ```c
127   char createTableSql[] = "CREATE TABLE IF NOT EXISTS EMPLOYEE (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT NOT NULL, "
128                           "AGE INTEGER, SALARY REAL, CODES BLOB)";
129   // Create a table.
130   OH_Rdb_Execute(store_, createTableSql);
131
132   // Create a key-value (KV) pair instance.
133   OH_VBucket *valueBucket = OH_Rdb_CreateValuesBucket();
134   valueBucket->putText(valueBucket, "NAME", "Lisa");
135   valueBucket->putInt64(valueBucket, "AGE", 18);
136   valueBucket->putReal(valueBucket, "SALARY", 100.5);
137   uint8_t arr[] = {1, 2, 3, 4, 5};
138   int len = sizeof(arr) / sizeof(arr[0]);
139   valueBucket->putBlob(valueBucket, "CODES", arr, len);
140   // Insert data.
141   int rowId = OH_Rdb_Insert(store_, "EMPLOYEE", valueBucket);
142   // Destroy the KV pair instance.
143   valueBucket->destroy(valueBucket);
144   ```
145
146   > **NOTE**
147   >
148   > **RelationalStore** does not provide explicit flush operations for data persistence. The **insert()** API stores data persistently.
149
1503. Modify or delete data based on the conditions specified by **OH_Predicates**.
151
152   Call **OH_Rdb_Update** to modify data, and call **OH_Rdb_Delete** to delete data. <br>Example:
153
154   ```c
155   // Modify data.
156   OH_VBucket *valueBucket = OH_Rdb_CreateValuesBucket();
157   valueBucket->putText(valueBucket, "NAME", "Rose");
158   valueBucket->putInt64(valueBucket, "AGE", 22);
159   valueBucket->putReal(valueBucket, "SALARY", 200.5);
160   uint8_t arr[] = {1, 2, 3, 4, 5};
161   int len = sizeof(arr) / sizeof(arr[0]);
162   valueBucket->putBlob(valueBucket, "CODES", arr, len);
163
164   OH_Predicates *predicates = OH_Rdb_CreatePredicates("EMPLOYEE");
165   OH_VObject *valueObject = OH_Rdb_CreateValueObject();
166   const char *name = "Lisa";
167   valueObject->putText(valueObject, name);
168   predicates->equalTo(predicates, "NAME", valueObject)->andOperate(predicates);
169   uint32_t count = 1;
170   double salary = 100.5;
171   valueObject->putDouble(valueObject, &salary, count);
172   predicates->equalTo(predicates, "SALARY", valueObject);
173
174   int changeRows = OH_Rdb_Update(store_, valueBucket, predicates);
175   valueObject->destroy(valueObject);
176   valueBucket->destroy(valueBucket);
177   predicates->destroy(predicates);
178   ```
179
180   ```c
181   // Delete data.
182   OH_Predicates *predicates = OH_Rdb_CreatePredicates("EMPLOYEE");
183   OH_VObject *valueObject = OH_Rdb_CreateValueObject();
184   const char *name = "Lisa";
185   valueObject->putText(valueObject, name);
186   predicates->equalTo(predicates, "NAME", valueObject);
187   int deleteRows = OH_Rdb_Delete(store_, predicates);
188   valueObject->destroy(valueObject);
189   predicates->destroy(predicates);
190   ```
191
1924. Query data based on the conditions specified by **OH_Predicates**.
193
194   Call **OH_Rdb_Query** to query data. The data obtained is returned in an **OH_Cursor** object. <br>Example:
195
196   ```c
197   OH_Predicates *predicates = OH_Rdb_CreatePredicates("EMPLOYEE");
198
199   const char *columnNames[] = {"NAME", "AGE"};
200   int len = sizeof(columnNames) / sizeof(columnNames[0]);
201   OH_Cursor *cursor = OH_Rdb_Query(store_, predicates, columnNames, len);
202
203   int columnCount = 0;
204   cursor->getColumnCount(cursor, &columnCount);
205
206   // OH_Cursor is a cursor of a data set. By default, the cursor points to the -1st record. Valid data starts from 0.
207   int64_t age;
208   while (cursor->goToNextRow(cursor) == OH_Rdb_ErrCode::RDB_OK) {
209       cursor->getInt64(cursor, 1, &age);
210   }
211
212   // Destroy the OH_Predicates instance.
213   predicates->destroy(predicates);
214   // Destroy the result set.
215   cursor->destroy(cursor);
216   ```
217
2185. Insert data assets into a table.
219
220   ```c
221   // 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.
222   char createAssetTableSql[] = "CREATE TABLE IF NOT EXISTS asset_table (id INTEGER PRIMARY KEY AUTOINCREMENT, data1 asset, data2 assets );";
223   errCode = OH_Rdb_Execute(store_, createAssetTableSql);
224   Data_Asset *asset = OH_Data_Asset_CreateOne();
225   OH_Data_Asset_SetName(asset, "name0");
226   OH_Data_Asset_SetUri(asset, "uri0");
227   OH_Data_Asset_SetPath(asset, "path0");
228   OH_Data_Asset_SetCreateTime(asset, 1);
229   OH_Data_Asset_SetModifyTime(asset, 1);
230   OH_Data_Asset_SetSize(asset, 1);
231   OH_Data_Asset_SetStatus(asset, Data_AssetStatus::ASSET_NORMAL);
232   errCode = OH_VBucket_PutAsset(valueBucket, "data1", asset);
233
234   Data_Asset **assets = OH_Data_Asset_CreateMultiple(2);
235
236   OH_Data_Asset_SetName(assets[0], "name0");
237   OH_Data_Asset_SetUri(assets[0], "uri0");
238   OH_Data_Asset_SetPath(assets[0], "path0");
239   OH_Data_Asset_SetCreateTime(assets[0], 1);
240   OH_Data_Asset_SetModifyTime(assets[0], 1);
241   OH_Data_Asset_SetSize(assets[0], 1);
242   OH_Data_Asset_SetStatus(assets[0], Data_AssetStatus::ASSET_NORMAL);
243
244   OH_Data_Asset_SetName(assets[1], "name1");
245   OH_Data_Asset_SetUri(assets[1], "uri1");
246   OH_Data_Asset_SetPath(assets[1], "path1");
247   OH_Data_Asset_SetCreateTime(assets[1], 1);
248   OH_Data_Asset_SetModifyTime(assets[1], 1);
249   OH_Data_Asset_SetSize(assets[1], 1);
250   OH_Data_Asset_SetStatus(assets[1], Data_AssetStatus::ASSET_NORMAL);
251
252   errCode = OH_VBucket_PutAssets(valueBucket, "data2", assets, assetsCount);
253   int rowID = OH_Rdb_Insert(cursorTestRdbStore_, table, valueBucket);
254   // Destroy Data_Asset* and Data_Asset**.
255   OH_Data_Asset_DestroyMultiple(assets, 2);
256   OH_Data_Asset_DestroyOne(asset);
257   ```
258
2596. Read data assets from the result set.
260
261   ```c
262   OH_Predicates *predicates = OH_Rdb_CreatePredicates("asset_table");
263
264   OH_Cursor *cursor = OH_Rdb_Query(cursorTestRdbStore_, predicates, NULL, 0);
265   cursor->goToNextRow(cursor);
266
267   uint32_t assetCount = 0;
268   // assetCount is an output parameter that indicates the number of assets in this column.
269   errCode = cursor->getAssets(cursor, 2, nullptr, &assetCount);
270   Data_Asset **assets = OH_Data_Asset_CreateMultiple(assetCount);
271   errCode = cursor->getAssets(cursor, 2, assets, &assetCount);
272   Data_Asset *asset = assets[1];
273
274   char name[10] = "";
275   size_t nameLength = 10;
276   errCode = OH_Data_Asset_GetName(asset, name, &nameLength);
277
278   char uri[10] = "";
279   size_t uriLength = 10;
280   errCode = OH_Data_Asset_GetUri(asset, uri, &uriLength);
281
282   char path[10] = "";
283   size_t pathLength = 10;
284   errCode = OH_Data_Asset_GetPath(asset, path, &pathLength);
285
286   int64_t createTime = 0;
287   errCode = OH_Data_Asset_GetCreateTime(asset, &createTime);
288
289   int64_t modifyTime = 0;
290   errCode = OH_Data_Asset_GetModifyTime(asset, &modifyTime);
291
292   size_t size = 0;
293   errCode = OH_Data_Asset_GetSize(asset, &size);
294
295   Data_AssetStatus status = Data_AssetStatus::ASSET_NULL;
296   errCode = OH_Data_Asset_GetStatus(asset, &status);
297
298   predicates->destroy(predicates);
299   OH_Data_Asset_DestroyMultiple(assets, assetCount);
300   cursor->destroy(cursor);
301   ```
302
3037. Obtain the last modification time of data.
304
305   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. <br>Example:
306
307   ```c
308   OH_VObject *values = OH_Rdb_CreateValueObject();
309   int64_t keys[] = { 1 };
310   values->putInt64(values, keys, 1);
311   OH_Cursor *cursor;
312   cursor = OH_Rdb_FindModifyTime(store_, "EMPLOYEE", "ROWID", values);
313   ```
314
3158. Create distributed tables.
316
317   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. <br>Example:
318
319   ```c
320   constexpr int TABLE_COUNT = 1;
321   const char *table[TABLE_COUNT];
322   table[0] = "EMPLOYEE";
323   int errcode = OH_Rdb_SetDistributedTables(store_, table, TABLE_COUNT, Rdb_DistributedType::DISTRIBUTED_CLOUD, &config);
324   ```
325
3269. Manually perform device-cloud sync for the distributed tables.
327
328   Call **OH_Rdb_CloudSync** to perform device-cloud sync for the tables. Before using this API, ensure that the cloud service is available. <br>Example:
329
330   ```c
331   // Define a callback.
332   void CloudSyncObserverCallback(void *context, Rdb_ProgressDetails *progressDetails)
333   {
334    // Do something.
335   }
336   const Rdb_ProgressObserver observer = { .context = nullptr, .callback = CloudSyncObserverCallback };
337   OH_Rdb_CloudSync(store_, Rdb_SyncMode::SYNC_MODE_TIME_FIRST, table, TABLE_COUNT, &observer);
338   ```
339
34010. 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. Call **OH_Rdb_Subscribe** to subscribe to data changes. Before using this API, ensure that the cloud service is available. <br>Example:
341
342    ```c
343    // Define a callback.
344    void RdbSubscribeBriefCallback(void *context, const char *values[], uint32_t count)
345    {
346    // Do something.
347    }
348    Rdb_BriefObserver briefObserver;
349    const Rdb_BriefObserver briefObserver = { .context = nullptr, .callback = RdbSubscribeBriefCallback };
350    // Subscribe to data changes.
351    OH_Rdb_Subscribe(store_, Rdb_SubscribeType::RDB_SUBSCRIBE_TYPE_CLOUD, &briefObserver);
352    ```
353
354    Call **OH_Rdb_Subscribe** to subscribe to local database data changes. <br>Example:
355
356    ```c
357    // Define a callback.
358    void LocalDataChangeObserverCallback1(void *context, const Rdb_ChangeInfo **changeInfo, uint32_t count)
359    {
360       for (uint32_t i = 0; i < count; i++) {
361          EXPECT_EQ(DISTRIBUTED_CHANGE_INFO_VERSION, changeInfo[i]->version);
362          // The table name is employee.
363          changeInfo[i]->tableName;
364          changeInfo[i]->ChangeType;
365          // The number of added rows is 1.
366          changeInfo[i]->inserted.count;
367          // The number of updated rows is 0.
368          changeInfo[i]->updated.count;
369          // The number of deleted rows is 0.
370          changeInfo[i]->deleted.count;
371       }
372    }
373    Rdb_DetailsObserver callback = LocalDataChangeObserverCallback1;
374    Rdb_DataObserver observer = { nullptr, { callback } };
375    // Subscribe to the local database data changes.
376    OH_Rdb_Subscribe(store_, Rdb_SubscribeType::RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS, &observer);
377
378    OH_VBucket* valueBucket = OH_Rdb_CreateValuesBucket();
379    valueBucket->putText(valueBucket, "NAME", "Lisa");
380    valueBucket->putInt64(valueBucket, "AGE", 18);
381    valueBucket->putReal(valueBucket, "SALARY", 100.5);
382    uint8_t arr[] = {1, 2, 3, 4, 5};
383    int len = sizeof(arr) / sizeof(arr[0]);
384    valueBucket->putBlob(valueBucket, "CODES", arr, len);
385    // Insert data.
386    int rowId = OH_Rdb_Insert(store_, "EMPLOYEE", valueBucket);
387    // Destroy the KV pair instance.
388    valueBucket->destroy(valueBucket);
389    ```
390
39111. Unsubscribe from the events of the specified type for an RDB store. After that, the callback will not be invoked to process the observation. Call **OH_Rdb_Unsubscribe** to unsubscribe from data changes. Before using this API, ensure that the cloud service is available. <br>Example:
392
393     ```c
394     // Define a callback.
395     void RdbSubscribeBriefCallback(void *context, const char *values[], uint32_t count)
396     {
397     // Do something.
398     }
399     Rdb_BriefObserver briefObserver = RdbSubscribeBriefCallback;
400     const Rdb_DataObserver briefObs = { .context = nullptr, .callback.briefObserver = briefObserver };
401     // Unsubscribe from data changes.
402     OH_Rdb_Unsubscribe(store_, Rdb_SubscribeType::RDB_SUBSCRIBE_TYPE_CLOUD, &briefObs);
403     ```
404    Call **OH_Rdb_Unsubscribe** to unsubscribe from local database data changes. <br>Example:
405     ```c
406     // Define a callback.
407     void LocalDataChangeObserverCallback1(void *context, const Rdb_ChangeInfo **changeInfo, uint32_t count)
408     {
409     // Do something.
410     }
411     Rdb_DetailsObserver callback = LocalDataChangeObserverCallback1;
412     Rdb_DataObserver observer = { nullptr, { callback } };
413     // Unsubscribe from the local database data changes.
414     OH_Rdb_Unsubscribe(store_, Rdb_SubscribeType::RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS, &observer);
415     ```
416
417
41812. 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. Call **OH_Rdb_SubscribeAutoSyncProgress** to subscribe to the auto sync progress. Before using this API, ensure that the cloud service is available. <br>Example:
419
420    ```c
421    // Define a callback.
422    void RdbProgressObserverCallback(void *context, Rdb_ProgressDetails *progressDetails)
423    {
424    // Do something.
425    }
426    const Rdb_ProgressObserver observer = { .context = nullptr, .callback = RdbProgressObserverCallback };
427    OH_Rdb_SubscribeAutoSyncProgress(store_, &observer);
428    ```
429
43013. Unsubscribe from the auto sync progress from an RDB store. After that, the callback will not be invoked to process the observation. Call **OH_Rdb_UnsubscribeAutoSyncProgress** to unsubscribe from the auto sync progress. Before using this API, ensure that the cloud service is available. <br>Example:
431
432    ```c
433    // Define a callback.
434    void RdbProgressObserverCallback(void *context, Rdb_ProgressDetails *progressDetails)
435    {
436    // Do something.
437    }
438    const Rdb_ProgressObserver observer = { .context = nullptr, .callback = RdbProgressObserverCallback };
439    OH_Rdb_UnsubscribeAutoSyncProgress(store_, &observer);
440    ```
441
44214. Delete an RDB store.
443
444    Call **OH_Rdb_DeleteStore** to delete the RDB store and related database file. <br>Example:
445
446    ```c
447    // Close the database instance.
448    OH_Rdb_CloseStore(store_);
449    // Delete the database file.
450OH_Rdb_DeleteStore(&config);
451    ```
452
453
454
455
456
457
458