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