SQLite:
SQLite is a software library that implements a self-contained, serverless, zero-configuration, transactional SQL relational database management system (RDBMS).
This tutorial covers the command line interface and the SQLite C/C++ database programming API.
SQLite comes with Linux: (example of package list on RHEL)
- sqlite
- sqlite-devel
- python-sqlite
SQLite Command Line Interface:
Basic SQLite: Create database, create a database table and insert a database record.
[prompt]$ sqlite3 /tmp/bedrock.db
sqlite> .help
sqlite> CREATE TABLE employee (Name varchar(20),Dept varchar(20),jobTitle varchar(20));
sqlite> .schema employee
CREATE TABLE employee (Name varchar(20),Dept varchar(20),jobTitle varchar(20));
sqlite> INSERT INTO employee VALUES ('Fred Flinstone','Quarry Worker','Rock Digger');
sqlite> .exit
Populate a database from a SQL command file:
File:
employeeFile.sql
1 | INSERT INTO employee VALUES ( 'Wilma Flinstone' , 'Finance' , 'Analyst' ); |
2 | INSERT into employee values ( 'Barney Rubble' , 'Sales' , 'Neighbor' ); |
3 | INSERT INTO employee VALUES ( 'Betty Rubble' , 'IT' , 'Neighbor' ); |
Load SQL file, execute a select and delete a record:
[prompt]$ sqlite3 /tmp/bedrock.db
sqlite> .tables
employee
sqlite> .read employeeFile.sql
sqlite> SELECT Name FROM employee WHERE dept='Sales';
Barney Rubble
sqlite> SELECT * FROM employee;
Fred Flinstone|Quarry Worker|Rock Digger
Wilma Flinstone|Finance|Analyst
Barney Rubble|Sales|Neighbor
Betty Rubble|IT|Neighbor
sqlite> DELETE FROM employee WHERE dept='Sales';
sqlite> .exit
Generate an ASCII file dump of the database:
[prompt]$ sqlite3 /tmp/bedrock.db
sqlite> .show
echo: off
explain: off
headers: off
mode: list
nullvalue: ""
output: stdout
separator: "|"
width:
sqlite> .output /tmp/bedrock.sql
sqlite> .dump
sqlite> .exit
This generates the following file:
/tmp/bedrock.sql
2 | CREATE TABLE employee ( Name varchar (20),Dept varchar (20),jobTitle varchar (20)); |
3 | INSERT INTO "employee" VALUES ( 'Fred Flinstone' , 'Quarry Worker' , 'Rock Digger' ); |
4 | INSERT INTO "employee" VALUES ( 'Wilma Flinstone' , 'Finance' , 'Analyst' ); |
5 | INSERT INTO "employee" VALUES ( 'Barney Rubble' , 'Sales' , 'Neighbor' ); |
6 | INSERT INTO "employee" VALUES ( 'Betty Rubble' , 'IT' , 'Neighbor' ); |
Upgrading the SQLite database:
sqlite test.db .dump | sqlite3 testV3.db
SQLite Information:
C/C++ SQLite Programming API:
Accessing SQLite with C/C++ API:
Function | Description |
sqlite3_open() | Opens specified database file. If the database file does not already exist, it is created. |
sqlite3_close() | Closes a previously opened database file. |
sqlite3_prepare_v2() | Prepares a SQL statement ready for execution. |
sqlite3_step() | Executes a SQL statement previously prepared by the sqlite3_prepare_v2() function. |
sqlite3_column_<type>() | Returns a data field from the results of a SQL retrieval operation where <type> is replaced by the data type of the data to be extracted (text, blob, bytes, int, int16 etc). |
sqlite3_finalize() | Deletes a previously prepared SQL statement from memory. |
sqlite3_exec() | Combines the functionality of sqlite3_prepare_v2(), sqlite3_step() and sqlite3_finalize() into a single function call. |
Database access example:
File:
accessTableEmployee.cpp
09 | static int callback( void *NotUsed, int argc, char **argv, char **azColName) |
12 | cout << "Number of args= " << argc << endl; |
16 | cout << azColName[i] << " = " << (argv[i] ? argv[i] : "NULL" ) << endl; |
22 | int main( int argc, char **argv) |
29 | int rc = sqlite3_open( "/tmp/bedrock.db" , &db); |
32 | cerr << "Can't open database: " << sqlite3_errmsg(db) << endl; |
39 | const char *zSql = "INSERT INTO employee(Name, Dept, jobTitle) VALUES('Barney Rubble','Sales','Neighbor')" ; |
44 | if ( sqlite3_prepare_v2(db, zSql, strlen (zSql)+1, &ppStmt, pzTail) != SQLITE_OK ) |
46 | cerr << "db error: " << sqlite3_errmsg(db) << endl; |
52 | sqlite3_finalize(ppStmt); |
53 | sqlite3_exec(db, "COMMIT" , NULL, NULL, NULL); |
57 | cerr << "Error: ppStmt is NULL" << endl; |
62 | rc = sqlite3_exec(db, "select * from employee" , callback, 0, &zErrMsg); |
65 | cerr << "SQL error: " << zErrMsg << endl; |
66 | sqlite3_free(zErrMsg); |
Compile:
g++ AccessTableEmployee.cpp -lsqlite3
Run: a.out
Number of args= 3
Name = Wilma Flinstone
Dept = Finance
jobTitle = Analyst
Number of args= 3
Name = Betty Rubble
Dept = IT
jobTitle = Neighbor
Number of args= 3
Name = Barney Rubble
Dept = Sales
jobTitle = Neighbor
Creating and Accessing SQLite BLOBS with C/C++:
Blobs: (binary objects eg images or C data structures)
Create a database table "btest" with one BLOB collumn called "MyData":
[prompt]$ sqlite3 /tmp/bedrock.db
sqlite> create table btest(ID INTEGER, MyData BLOB);
Insert a blob into the database. Select the blob using the sqlite3_exec() API call.
File:
sqliteBlobExampleExec.cpp
12 | static int callback( void *NotUsed, int argc, char **argv, char **azColName) |
16 | for ( int i=0; i<argc; i++) |
18 | if (! strcmp (azColName[i], "MyData" )) |
20 | memcpy (&blob, argv[i], sizeof ( struct tm )); |
21 | cout << "Year retrieved from blob: " << blob.tm_year+1900 << endl; |
25 | cout << azColName[i] << " = " << (argv[i] ? argv[i] : "NULL" ) << endl; |
33 | int main( int argc, char **argv) |
39 | time_t now = time (&tt); |
40 | struct tm *blob = gmtime (&now); |
42 | cout << "Year stored: " << blob->tm_year+1900 << endl; |
45 | int rc = sqlite3_open( "/tmp/bedrock.db" , &db); |
48 | cerr << "Can't open database: " << sqlite3_errmsg(db) << endl; |
54 | const char *zSql = "INSERT INTO btest(ID, MyData) VALUES('1',?)" ; |
58 | if ( sqlite3_prepare_v2(db, zSql, strlen (zSql)+1, &ppStmt, pzTail) != SQLITE_OK ) |
60 | cerr << "db error: " << sqlite3_errmsg(db) << endl; |
68 | sqlite3_bind_blob(ppStmt, 1, blob, sizeof ( struct tm ), SQLITE_TRANSIENT); |
70 | sqlite3_finalize(ppStmt); |
71 | sqlite3_exec(db, "COMMIT" , NULL, NULL, NULL); |
75 | cerr << "Error: ppStmt is NULL" << endl; |
84 | rc = sqlite3_exec(db, "SELECT * FROM btest" , callback, 0, &zErrMsg); |
87 | cerr << "SQL error: " << zErrMsg << endl; |
88 | sqlite3_free(zErrMsg); |
93 | sqlite3_exec(db, "END" , NULL, NULL, NULL); |
Compile:
g++ sqliteBlobExampleExec.cpp -lsqlite3
Run:
./a.out
Result:
Year stored: 2010
ID = 1
Year retrieved from blob: 2010
Insert a blob into the database. Select the blob using the sqlite3_step() API call.
File:
sqliteBlobExample.cpp
012 | int main( int argc, char **argv) |
015 | sqlite3_stmt *ppStmt; |
017 | const char *zSql = "INSERT INTO btest(ID, MyData) VALUES('1',?)" ; |
020 | time_t now = time (&tt); |
021 | struct tm *blob = gmtime (&now); |
023 | cout << "Year stored: " << blob->tm_year+1900 << endl; |
026 | int rc = sqlite3_open( "/tmp/bedrock.db" , &db); |
029 | cerr << "Can't open database: " << sqlite3_errmsg(db) << endl; |
035 | if ( sqlite3_prepare_v2(db, zSql, -1, &ppStmt, NULL) != SQLITE_OK ) |
037 | cerr << "db error: " << sqlite3_errmsg(db) << endl; |
045 | sqlite3_bind_blob(ppStmt, 1, blob, sizeof ( struct tm ), SQLITE_TRANSIENT); |
046 | sqlite3_step(ppStmt); |
047 | sqlite3_finalize(ppStmt); |
048 | sqlite3_exec(db, "COMMIT" , NULL, NULL, NULL); |
052 | cerr << "Error: ppStmt is NULL" << endl; |
059 | const char *zSqlSelect = "select * from btest" ; |
060 | if ( sqlite3_prepare_v2(db, zSqlSelect, -1, &ppStmt, NULL) != SQLITE_OK ) |
062 | cerr << "db error: " << sqlite3_errmsg(db) << endl; |
068 | cout << sqlite3_column_table_name(ppStmt,0) << endl; |
071 | while (sqlite3_step(ppStmt) == SQLITE_ROW) |
074 | for ( int jj=0; jj < sqlite3_column_count(ppStmt); jj++) |
077 | cout << sqlite3_column_name(ppStmt,jj) << " = " ; |
080 | switch (sqlite3_column_type(ppStmt, jj)) |
082 | case SQLITE_INTEGER: cout << sqlite3_column_int(ppStmt, jj) << endl; |
084 | case SQLITE_FLOAT: cout << sqlite3_column_double(ppStmt, jj) << endl; |
086 | case SQLITE_TEXT: cout << sqlite3_column_text(ppStmt, jj) << endl; |
088 | case SQLITE_BLOB: cout << "BLOB " << endl; |
089 | cout << "Size of blob: " << sqlite3_column_bytes(ppStmt, jj) << endl; |
090 | struct tm *blobRetreived; |
091 | blobRetreived = ( struct tm *) sqlite3_column_blob(ppStmt, jj); |
092 | cout << "Year retrieved from blob: " << blobRetreived->tm_year+1900 << endl; |
094 | case SQLITE_NULL: cout << "NULL " << endl; |
096 | default : cout << "default " << endl; |
101 | sqlite3_finalize(ppStmt); |
103 | sqlite3_exec(db, "END" , NULL, NULL, NULL); |
Compile:
g++ sqliteBlobExample.cpp -lsqlite3
Run:
./a.out
Result:
Year stored: 2010
btest
ID = 1
MyData = BLOB
Size of blob: 44
Year retrieved from blob: 2010
Notes:
- Calls to sqlite3_step() and sqlite3_finalize() clear out allocated memory returned by sqlite3_column_<type>().
Thus do not free memory returned by sqlite3_column_blob() or for any of the calls to sqlite3_column_<type>().
Links:
SQLite Database Admin Tools:
SQLite Software Development Links:
Related SQLite Links:

Books: