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
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
INSERT INTO employee VALUES ('Wilma Flinstone','Finance','Analyst');
INSERT into employee values ('Barney Rubble','Sales','Neighbor');
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
BEGIN TRANSACTION;
CREATE TABLE employee (Name varchar(20),Dept varchar(20),jobTitle varchar(20));
INSERT INTO "employee" VALUES('Fred Flinstone','Quarry Worker','Rock Digger');
INSERT INTO "employee" VALUES('Wilma Flinstone','Finance','Analyst');
INSERT INTO "employee" VALUES('Barney Rubble','Sales','Neighbor');
INSERT INTO "employee" VALUES('Betty Rubble','IT','Neighbor');
COMMIT;
Upgrading the SQLite database:
sqlite test.db .dump | sqlite3 testV3.db
SQLite Information:
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
#include <iostream>
#include <sqlite3.h>
#include <stdlib.h>
// g++ AccessTableEmployee.cpp -lsqlite3
using namespace std;
static int callback(void *NotUsed, int argc, char **argv, char **azColName)
{
int i;
cout << "Number of args= " << argc << endl;
for(i=0; i<argc; i++)
{
cout << azColName[i] << " = " << (argv[i] ? argv[i] : "NULL") << endl;
}
cout << endl;
return 0;
}
int main(int argc, char **argv)
{
sqlite3 *db; // Declare pointer to sqlite database structure
char *zErrMsg = 0;
// Open Database
int rc = sqlite3_open("/tmp/bedrock.db", &db);
if( rc )
{
cerr << "Can't open database: " << sqlite3_errmsg(db) << endl;
sqlite3_close(db);
exit(1);
}
// Insert data into database
const char *zSql = "INSERT INTO employee(Name, Dept, jobTitle) VALUES('Barney Rubble','Sales','Neighbor')";
sqlite3_stmt *ppStmt;
const char **pzTail;
if( sqlite3_prepare_v2(db, zSql, strlen(zSql)+1, &ppStmt, pzTail) != SQLITE_OK )
{
cerr << "db error: " << sqlite3_errmsg(db) << endl;
}
if(ppStmt)
{
sqlite3_step(ppStmt);
sqlite3_finalize(ppStmt);
sqlite3_exec(db, "COMMIT", NULL, NULL, NULL);
}
else
{
cerr << "Error: ppStmt is NULL" << endl;
}
// Select from database
rc = sqlite3_exec(db,"select * from employee", callback, 0, &zErrMsg);
if( rc!=SQLITE_OK )
{
cerr << "SQL error: " << zErrMsg << endl;
sqlite3_free(zErrMsg);
}
// Close
sqlite3_close(db);
return 0;
}
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
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
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <sqlite3.h>
#include <time.h>
using namespace std;
// Store gmtime data structure as a blob
// See man pages for information on gmtime data structure: man gmtime
static int callback(void *NotUsed, int argc, char **argv, char **azColName)
{
struct tm blob;
for(int i=0; i<argc; i++)
{
if(!strcmp(azColName[i],"MyData"))
{ // Handle Blob data
memcpy(&blob, argv[i], sizeof(struct tm));
cout << "Year retrieved from blob: " << blob.tm_year+1900 << endl;
}
else
{ // All other database collumns
cout << azColName[i] << " = " << (argv[i] ? argv[i] : "NULL") << endl;
}
}
cout << endl;
return 0;
}
int main(int argc, char **argv)
{
sqlite3 *db;
char *zErrMsg = 0;
time_t tt = 0;
time_t now = time(&tt); // seconds since the Epoch
struct tm *blob = gmtime(&now); // Create the blob to store in the database
cout << "Year stored: " << blob->tm_year+1900 << endl;
cout << endl;
int rc = sqlite3_open("/tmp/bedrock.db", &db);
if( rc )
{
cerr << "Can't open database: " << sqlite3_errmsg(db) << endl;
exit(1);
}
// Insert blob data into database
const char *zSql = "INSERT INTO btest(ID, MyData) VALUES('1',?)";
sqlite3_stmt *ppStmt;
const char **pzTail;
if( sqlite3_prepare_v2(db, zSql, strlen(zSql)+1, &ppStmt, pzTail) != SQLITE_OK )
{
cerr << "db error: " << sqlite3_errmsg(db) << endl;
sqlite3_close(db);
exit(1);
}
if(ppStmt)
{
// For Blob collumn bind 1
sqlite3_bind_blob(ppStmt, 1, blob, sizeof(struct tm), SQLITE_TRANSIENT);
sqlite3_step(ppStmt);
sqlite3_finalize(ppStmt);
sqlite3_exec(db, "COMMIT", NULL, NULL, NULL);
}
else
{
cerr << "Error: ppStmt is NULL" << endl;
sqlite3_close(db);
exit(1);
}
// Select rows from database
// Note: sqlite3_exec() does sqlite3_prepare_v2(), sqlite3_step() and sqlite3_finalize() into a single function call
rc = sqlite3_exec(db,"SELECT * FROM btest", callback, 0, &zErrMsg);
if( rc!=SQLITE_OK )
{
cerr << "SQL error: " << zErrMsg << endl;
sqlite3_free(zErrMsg);
sqlite3_close(db);
exit(1);
}
sqlite3_exec(db, "END", NULL, NULL, NULL);
// Close database
sqlite3_close(db);
return 0;
}
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
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <sqlite3.h>
#include <time.h>
using namespace std;
// Store gmtime data structure as a blob
// See man pages for information on gmtime data structure: man gmtime
int main(int argc, char **argv)
{
sqlite3 *db;
sqlite3_stmt *ppStmt;
char *zErrMsg = 0;
const char *zSql = "INSERT INTO btest(ID, MyData) VALUES('1',?)";
time_t tt = 0;
time_t now = time(&tt); // seconds since the Epoch
struct tm *blob = gmtime(&now); // Create the blob to store in the database
cout << "Year stored: " << blob->tm_year+1900 << endl;
cout << endl;
int rc = sqlite3_open("/tmp/bedrock.db", &db);
if( rc )
{
cerr << "Can't open database: " << sqlite3_errmsg(db) << endl;
exit(1);
}
// Insert blob data into database
if( sqlite3_prepare_v2(db, zSql, -1, &ppStmt, NULL) != SQLITE_OK )
{
cerr << "db error: " << sqlite3_errmsg(db) << endl;
sqlite3_close(db);
exit(1);
}
if(ppStmt)
{
// For Blob collumn bind 1
sqlite3_bind_blob(ppStmt, 1, blob, sizeof(struct tm), SQLITE_TRANSIENT);
sqlite3_step(ppStmt);
sqlite3_finalize(ppStmt);
sqlite3_exec(db, "COMMIT", NULL, NULL, NULL);
}
else
{
cerr << "Error: ppStmt is NULL" << endl;
sqlite3_close(db);
exit(1);
}
// Select rows from database
const char *zSqlSelect = "select * from btest";
if( sqlite3_prepare_v2(db, zSqlSelect, -1, &ppStmt, NULL) != SQLITE_OK )
{
cerr << "db error: " << sqlite3_errmsg(db) << endl;
sqlite3_close(db);
exit(1);
}
// Name of DB table
cout << sqlite3_column_table_name(ppStmt,0) << endl;
// For each row returned
while (sqlite3_step(ppStmt) == SQLITE_ROW)
{
// For each collumn
for(int jj=0; jj < sqlite3_column_count(ppStmt); jj++)
{
// Print collumn name
cout << sqlite3_column_name(ppStmt,jj) << " = ";
// Print collumn data
switch(sqlite3_column_type(ppStmt, jj))
{
case SQLITE_INTEGER: cout << sqlite3_column_int(ppStmt, jj) << endl;
break;
case SQLITE_FLOAT: cout << sqlite3_column_double(ppStmt, jj) << endl;
break;
case SQLITE_TEXT: cout << sqlite3_column_text(ppStmt, jj) << endl;
break;
case SQLITE_BLOB: cout << "BLOB " << endl;
cout << "Size of blob: " << sqlite3_column_bytes(ppStmt, jj) << endl;
struct tm *blobRetreived;
blobRetreived = (struct tm *) sqlite3_column_blob(ppStmt, jj);
cout << "Year retrieved from blob: " << blobRetreived->tm_year+1900 << endl;
break;
case SQLITE_NULL: cout << "NULL " << endl;
break;
default: cout << "default " << endl;
break;
}
}
}
sqlite3_finalize(ppStmt);
sqlite3_exec(db, "END", NULL, NULL, NULL);
// Close database
sqlite3_close(db);
return 0;
}
Run: ./a.out
Result:
Year stored: 2010 btest ID = 1 MyData = BLOB Size of blob: 44 Year retrieved from blob: 2010Notes:
- 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>().
SQLite Database Admin Tools:
- SQLiteman - Qt, Cross platform
- SQLiteGui - SQLite browser GUI (C++/Qt)
- sqlite-manager - UIL Firefox extension
- SQLite Studio - cross platform, multi-language support, Tcl/Tk
- TkSQLite - Tcl/Tk
- SQL Db Manager - developed in Delphi-7
- wxSQLite - C+/wxWidgets (fr)
- SQLite Db Browser
- Web Admin Tools:
- SQLite Manager - PHP4/5
- Bazdig - PHP
- SQLiteWeb.sh - shell script CGI [cache]
- SQLite web
SQLite Software Development Links:
- sqlite-sdbc-driver - Open Office
- DB_Sqlite_Tools - PHP Pear package
- SQLiteDB - PHP class
- Perl Parse-Dia-SQL - Perl CPAN module
- Javascript API for SQLite
- Ruby API for SQLite
- knoda KDE driver library
Related SQLite Links:


Books:




