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