1# RelationalStore Development Guide 2 3 4## When to Use 5 6RelationalStore provides a complete mechanism for local database management. It offers a series of interfaces for adding, deleting, modifying, and querying data in an RDB store. To satisfy different needs in complicated scenarios, RelationalStore also supports direct execution of SQL statements. 7 8 9## Basic concepts 10 11- **OH_Predicates**: A representation of the property or feature of a data entity, or the relationship between data entities. It is used to define operation conditions. 12 13- **OH_Cursor**: A set of query results, which allows access to the required data in flexible modes. 14 15 16## Restrictions 17 18- The default logging mode is Write Ahead Log (WAL), and the default flushing mode is **FULL** mode. 19 20- RelationalStore supports a maximum of four connection pools to manage read and write 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 on the device are automatically deleted. 25 26 27## Available APIs 28 29For details about the APIs, see [RDB](../reference/native-apis/_r_d_b.md). 30 31| API| Description| 32| -------- | -------- | 33| OH_Rdb_GetOrOpen(const OH_Rdb_Config *config, int *errCode) | Obtains an OH_Rdb_Store instance for RDB store operations.| 34| OH_Rdb_Execute(OH_Rdb_Store *store, const char *sql) | Executes an SQL statement that contains specified arguments but returns no value.| 35| OH_Rdb_Insert(OH_Rdb_Store *store, const char *table, OH_VBucket *valuesBucket) | Inserts a row of data into a table.| 36| OH_Rdb_Update(OH_Rdb_Store *store, OH_VBucket *valuesBucket, OH_Predicates *predicates); | Updates data in the RDB store based on the specified OH_Predicates instance.| 37| OH_Rdb_Delete(OH_Rdb_Store *store, OH_Predicates *predicates) | Deletes data from the RDB store based on the specified OH_Predicates instance.| 38| OH_Rdb_Query(OH_Rdb_Store *store, OH_Predicates *predicates, const char *const *columnNames, int length) | Queries data in the RDB store based on specified conditions.| 39| OH_Rdb_DeleteStore(const OH_Rdb_Config *config) | Deletes an RDB store.| 40 41 42## How to Develop 43 44**Adding the Dynamic Library** 45 46Add the following lib to **CMakeLists.txt**. 47```txt 48native_rdb_ndk_header.so 49``` 50 51**Including Header Files** 52 53```c++ 54#include <oh_cursor.h> 55#include <oh_predicates.h> 56#include <oh_value_object.h> 57#include <oh_values_bucket.h> 58#include <relational_store.h> 59#include <relational_store_error_code.h> 60 61``` 62 631. Obtain an OH_Rdb_Store instance and create a database file. 64 65 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/js-apis-inner-application-context.md). In the FA model, there is no interface for obtaining the database sandbox path. Use the directory of the application. For details, see **getFilesDir** of [Context](../reference/apis/js-apis-inner-app-context.md). 66 67 Example: 68 69 ```c 70 // Create an OH_Rdb_Config object. 71 OH_Rdb_Config config; 72 // The path is the application sandbox path. 73 config.dataBaseDir = "xxx"; 74 // Database file name. 75 config.storeName = "RdbTest.db"; 76 // Application bundle name. 77 config.bundleName = "xxx"; 78 // Module name. 79 config.moduleName = "xxx"; 80 // Security level of the database file. 81 config.securityLevel = OH_Rdb_SecurityLevel::S1; 82 // Whether the database is encrypted. 83 config.isEncrypt = false; 84 // Memory size occupied by config. 85 config.selfSize = sizeof(OH_Rdb_Config); 86 87 int errCode = 0; 88 // Obtain the OH_Rdb_Store instance. 89 OH_Rdb_Store *store_ = OH_Rdb_GetOrOpen(&config, &errCode); 90 ``` 91 922. After obtaining the OH_Rdb_Store instance, call **OH_Rdb_Execute** to create a table and call **OH_Rdb_Insert** to insert data to the table created. 93 94 Example: 95 96 ```c 97 char createTableSql[] = "CREATE TABLE IF NOT EXISTS EMPLOYEE (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT NOT NULL, " 98 "AGE INTEGER, SALARY REAL, CODES BLOB)"; 99 // Create a table. 100 OH_Rdb_Execute(store_, createTableSql); 101 102 // Create a key-value pair instance. 103 OH_VBucket *valueBucket = OH_Rdb_CreateValuesBucket(); 104 valueBucket->putText(valueBucket, "NAME", "Lisa"); 105 valueBucket->putInt64(valueBucket, "AGE", 18); 106 valueBucket->putReal(valueBucket, "SALARY", 100.5); 107 uint8_t arr[] = {1, 2, 3, 4, 5}; 108 int len = sizeof(arr) / sizeof(arr[0]); 109 valueBucket->putBlob(valueBucket, "CODES", arr, len); 110 // Insert data. 111 int rowId = OH_Rdb_Insert(store_, "EMPLOYEE", valueBucket); 112 // Destroy the KV pair instance. 113 valueBucket->destroy(valueBucket); 114 ``` 115 116 > **NOTE** 117 > 118 > **RelationalStore** does not provide explicit flush operations for data persistence. **insert()** stores data in a file persistently. 119 1203. Modify or delete data based on the specified **Predicates** instance. 121 122 Call **OH_Rdb_Update** to modify data and call **OH_Rdb_Delete** to delete data. 123 124 Example: 125 126 ```c 127 // Modify data. 128 OH_VBucket *valueBucket = OH_Rdb_CreateValuesBucket(); 129 valueBucket->putText(valueBucket, "NAME", "Rose"); 130 valueBucket->putInt64(valueBucket, "AGE", 22); 131 valueBucket->putReal(valueBucket, "SALARY", 200.5); 132 uint8_t arr[] = {1, 2, 3, 4, 5}; 133 int len = sizeof(arr) / sizeof(arr[0]); 134 valueBucket->putBlob(valueBucket, "CODES", arr, len); 135 136 OH_Predicates *predicates = OH_Rdb_CreatePredicates("EMPLOYEE"); 137 OH_VObject *valueObject = OH_Rdb_CreateValueObject(); 138 const char *name = "Lisa"; 139 valueObject->putText(valueObject, name); 140 predicates->equalTo(predicates, "NAME", valueObject)->andOperate(predicates); 141 uint32_t count = 1; 142 double salary = 100.5; 143 valueObject->putDouble(valueObject, &salary, count); 144 predicates->equalTo(predicates, "SALARY", valueObject); 145 146 int changeRows = OH_Rdb_Update(store_, valueBucket, predicates); 147 valueObject->destroy(valueObject); 148 valueBucket->destroy(valueBucket); 149 predicates->destroy(predicates); 150 ``` 151 152 ```c 153 // Delete data. 154 OH_Predicates *predicates = OH_Rdb_CreatePredicates("EMPLOYEE"); 155 OH_VObject *valueObject = OH_Rdb_CreateValueObject(); 156 const char *name = "Lisa"; 157 valueObject->putText(valueObject, name); 158 predicates->equalTo(predicates, "NAME", valueObject); 159 int deleteRows = OH_Rdb_Delete(store_, predicates); 160 valueObject->destroy(valueObject); 161 predicates->destroy(predicates); 162 ``` 163 1644. Query data based on the conditions specified by **Predicates**. 165 166 Call **OH_Rdb_Query** to query data. The data obtained is returned in a **OH_Cursor** object. 167 168 Example: 169 170 ```c 171 OH_Predicates *predicates = OH_Rdb_CreatePredicates("EMPLOYEE"); 172 173 const char *columnNames[] = {"NAME", "AGE"}; 174 int len = sizeof(columnNames) / sizeof(columnNames[0]); 175 OH_Cursor *cursor = OH_Rdb_Query(store_, predicates, columnNames, len); 176 177 int columnCount = 0; 178 cursor->getColumnCount(cursor, &columnCount); 179 180 // OH_Cursor is a cursor of a data set. By default, the cursor points to the -1st record. Valid data starts from 0. 181 int64_t age; 182 while (cursor->goToNextRow(cursor) == OH_Rdb_ErrCode::RDB_OK) { 183 cursor->getInt64(cursor, 1, &age); 184 } 185 186 // Destroy the Predicates instance. 187 predicates->destroy(predicates); 188 // Destroy the result set. 189 cursor->destroy(cursor); 190 ``` 191 1925. Delete the database. 193 194 Call **OH_Rdb_DeleteStore** to delete an RDB store and related database files. 195 196 Example: 197 198 199 ```c 200 // Close the database instance. 201 OH_Rdb_CloseStore(store_); 202 // Delete the database file. 203 OH_Rdb_DeleteStore(&config); 204 ``` 205 206 207