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