Use of database

2014/08/21 10:04
Number of readings 261

TBOX currently supports sqlite3 and mysql relational databases (the corresponding libsqlite3. a and libmysql. a need to be linked), and encapsulates their interfaces. It is more convenient and simple to use, and you can switch to other database engines at any time without changing the interfaces.

Here is a simple example:

 /*Initialize a MySQL database * *Localhost: hostname, or ip address *Type: the type of database. Currently, it supports two types: mysql and sqlite3 *Username: database user name *Password: database user password *Database: The name of the database to be accessed. If not set, the default database will be automatically connected * *If you specify a port reversely, the incoming port can be displayed: * " sql://localhost:3306/?type=mysql&username=xxxx&password=xxxx&database=xxxx " * *The database access url of sqlite3 is: * " sql:///home/file.sqlitedb?type=sqlite3 " * *Or directly transfer the file path: * "/home/file.sqlite3" * " file:///home/file.sqlitedb " * "C://home/file.sqlite3" */ tb_database_sql_ref_t database = tb_database_sql_init(" sql://localhost/?type=mysql&username=xxxx&password=xxxx&database=test "); if (database) { //Open Database if (tb_database_sql_open(database)) { //Execute SQL statement and query if (tb_database_sql_done(database, "select * from test")) { /*Load result set * *If insert, update and other non select statements are executed, tb_null is returned at this time, indicating that there is no result set * *This result set completely adopts the iterator pattern, which is convenient for fast iterative access. * *The following parameter tb_true indicates that all results should be loaded into memory as soon as possible. If successful *You can get the actual number of result set rows through tb_iterator_size (result). * *If one-time loading fails or tb_false is passed in, it means that you can only fetch rows of rollback data *In this way, the resources that occupy memory are less, but the actual number of rows cannot be obtained in advance. At this time, tb_iterator_size (result) *A super value is returned */ tb_iterator_ref_t result = tb_database_sql_result_load(database, tb_true); if (result) { //If the one-time loading is successful, the actual number of result lines will be returned tb_trace_i("row: size: %lu", tb_iterator_size(result)); //Traverse all rows tb_for_all_if (tb_iterator_ref_t, row, result, row) { //Display the number of columns in the row tb_trace_i("[row: %lu, col: size: %lu]: ", row_itor, tb_iterator_size(row)); //Traverse all values in this row tb_for_all_if (tb_database_sql_value_t*, value, row, value) { /*Tb_database_sql_value_name (value): get the column name corresponding to the value *Tb_database_sql_value_text (value): Get the text data of the value, if it is of text type *Tb_database_sql_value_type (value): Gets the type of the value * * ... */ tb_tracet_i("[%s:%s] ", tb_database_sql_value_name(value), tb_database_sql_value_text(value)); } } //Release result set data tb_database_sql_result_exit(database, result); } } else { //Execution failed, displaying failure status and reason tb_trace_e("done %s failed, error: %s", sql, tb_state_cstr(tb_database_sql_state(database))); } } else { //Opening failed, displaying the failure status and reason tb_trace_e("open failed: %s", tb_state_cstr(tb_database_sql_state(database))); } //Exit Database tb_database_sql_exit(database); }

The above example cannot process binary data. If you want to process binary data, such as inserting an image data, you can use the statement mode to pre compile an SQL statement, This method is more flexible and more efficient for frequent processing of a certain SQL statement, because it saves the process of parsing the SQL syntax every time.

The specific use process is also very simple. Here is an example of insert binary data:

 // done tb_database_sql_statement_ref_t     stmt = tb_null; tb_stream_ref_t                     stream = tb_null; do { //To initialize an insert statement, you need to customize the parameters passed in with the? Replace and pre compile if (! (stmt = tb_database_sql_statement_init(database, "insert into table2 values(?, ?, ?, ?, ?, ?, ?)"))) { // trace tb_trace_e("stmt: init %s failed, error: %s", sql, tb_state_cstr(tb_database_sql_state(database))); break ; } //Initialize a large image data stream stream = tb_stream_init_from_url("/tmp/large_image.png"); tb_assert_and_check_break(stream); //Open Stream if (! tb_stream_open(stream)) break; //Parameter list tb_database_sql_value_t list[7]; //Bind a parameter of type text, and the sql corresponds to: text tb_database_sql_value_set_text(&list[0], "hello", 0); //Bind a uint16 blob data parameter. Since it is a small piece of data, stream is not used. The SQL statement corresponds to: blob tb_database_sql_value_set_blob16(&list[1], data, size); //Bind an ultra small data block of uint8 size to save storage space. In SQL, it corresponds to: tinyblob tb_database_sql_value_set_blob8(&list[2], data, size); //Bind a huge uint32 data block. In SQL, the corresponding: longblob tb_database_sql_value_set_blob32(&list[3],  data, size, tb_null); //Bind a huge uint32 data stream to save memory. Data will not be loaded into memory for processing at one time. The corresponding SQL statement is: longblob tb_database_sql_value_set_blob32(&list[4],  tb_null, 0, stream); //Bind an int32 integer, which corresponds to int in SQL tb_database_sql_value_set_int32(&list[5], number); //Bind an int16 integer, which corresponds to smallint in SQL tb_database_sql_value_set_int16(&list[6], snumber); //Binding parameter list if (! tb_database_sql_statement_bind(database, stmt, list, tb_arrayn(list))) { // trace tb_trace_e("stmt: bind %s failed, error: %s", sql, tb_state_cstr(tb_database_sql_state(database))); break ; } //Execute pre compiled sql statements if (! tb_database_sql_statement_done(database, stmt)) { // trace tb_trace_e("stmt: done %s failed, error: %s", sql, tb_state_cstr(tb_database_sql_state(database))); break ; } } while (0); //Delete sql statement object if (stmt) tb_database_sql_statement_exit(database, stmt); //Exit Data Flow if (stream) tb_stream_exit(stream);

For obtaining the corresponding result set data, the interface used is the same as the first example. You can directly iterate or directly access the data of a column through the index:

 //Load result set in rollback mode tb_iterator_ref_t result = tb_database_sql_result_load(database, tb_false); if (result) { //Traverse rows tb_for_all_if (tb_iterator_ref_t, row, result, row) { //Get text data tb_database_sql_value_t const* name = tb_iterator_item(row, 0); tb_assert_and_check_break(name); tb_tracet_i("[%s:%s] ", tb_database_sql_value_name(name), tb_database_sql_value_text(name)); //Get blob16 data tb_database_sql_value_t const* data = tb_iterator_item(row, 1); tb_assert_and_check_break(data); tb_tracet_i("[%s:%s] ", tb_database_sql_value_name(data), tb_database_sql_value_blob(data)); //Get blob32 data tb_database_sql_value_t const* ldata = tb_iterator_item(row, 4); tb_assert_and_check_break(ldata); { /*Try to get the data buffer first, if it exists * *Optimized for small pieces of data, even the blob32 data, if the data size *It is not big, and will be directly stored in the memory buffer for fast reading */ tb_stream_ref_t     stream = tb_null; if (tb_database_sql_value_blob(ldata)) { //Get data and size tb_byte_t const*    data = tb_database_sql_value_blob(ldata); tb_size             size = tb_database_sql_value_size(ldata); // ... } //If the data buffer cannot be obtained, it indicates that the data volume is large. Try to obtain the data stream for processing else if ((stream = tb_database_sql_value_blob_stream(ldata))) { //Read the data from the stream. Note: This stream does not support write operations and can only be used for reading // ... } } //Get int32 data. If it is int8, int16 or float type data, it will be forced automatically tb_database_sql_value_t const* number = tb_iterator_item(row, 5); tb_assert_and_check_break(number); tb_tracet_i("[%s:%d] ", tb_database_sql_value_name(number), tb_database_sql_value_int32(number)); } //Exit Result Set tb_database_sql_result_exit(database, result); }

Expand to read the full text
Loading
Click to lead the topic 📣 Post and join the discussion 🔥
Reward
zero comment
one Collection
zero fabulous
 Back to top
Top