I’m here going to demonstrate a simple connection and query to a SQLite database using C.
First you need to download and build (if necessary) the SQLite code so you get the sqlite3.so (or sqlite3.lib on Windows) and the necessary header and c files (sqlite3.h, sqlite3.c). I will not go into how this is done here.
After the environment is setup we start with connecting to the SQLite database:
#include "sqlite3.h"
int main(int argc, char const *argv[]) {
sqlite3 *conn; // Database struct handle
const char *dbname = "test.db"; // Database file name
int dbhandle; // Resource handle
// Open database
dbhandle = sqlite3_open_v2(dbname, &conn, SQLITE_OPEN_READONLY, NULL);
if(dbhandle == SQLITE_OK) {
fprintf(stdout, "Database open\n");
}
else {
fprintf(stderr, "Could not open database: %s\n", sqlite3_errmsg(conn) );
return 1;
}
// Cleanup
sqlite3_close(conn);
return 0;
}
In short this code will do the following:
1. Create necessary variables for connection, resource handle and the database file name
2. Call sqlite3_open_v2() to open a read only connection to the SQLite database (test.db)
3. Check if we succeeded and report result to console
4. Cleanup connection object
I choose here to use the sqlite3_open_v2() function due to two main reasons:
1. I don’t want to create the database if it does not exist. This is the default behavior of sqlite3_open()
2. I want to be able to open the database as readonly (SQLITE_OPEN_READONLY) or as readwrite (SQLITE_OPEN_READWRITE)
Now we are also going to query the database and present the result. We start with adding a callback function to handle the output like this:
static int callback(void *NotUsed, int argc, char **argv, char **colname){
NotUsed = 0;
int i;
for (i = 0; i < argc; i++){
printf("%s = %s\n", colname[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
This function is going to be called from sqlite3_exec() function later. Once per row of results from query. It will print a list with “column name = cell value” rows
#include "sqlite3.h"
int main(int argc, char const *argv[]) {
// Connection variables
sqlite3 *conn; // Database struct handle
const char *dbname = "test.db"; // Database file name
int dbhandle;
// Query variables
int stmthandle; // Statement handel
char *errorMsg = 0; // Error message holder
const char *query = "SELECT * FROM user"; // Query to run
// Open database
dbhandle = sqlite3_open_v2(dbname, &conn, SQLITE_OPEN_READONLY, NULL);
if(dbhandle == SQLITE_OK) {
fprintf(stdout, "Database open\n");
}
else {
fprintf(stderr, "Could not open database: %s\n", sqlite3_errmsg(conn) );
return 1;
}
// Execute query
stmthandle = sqlite3_exec(conn, query, callback, 0, &errorMsg);
if (stmthandle == SQLITE_OK) {
fprintf(stdout, "Query successful\n");
}
else {
fprintf(stderr, "Could not run query: %s\n", errorMsg );
return 1;
}
// Cleanup
sqlite3_close(conn);
return 0;
}
I have now added the sqlite3_exec() wrapper function (it handles sqlite3_prepare_v2(), sqlite3_step() and sqlite3_finalize() all into one nifty function) and the necessary query variables (statement handle, error message holder and SQL statement).
The sqlite3_exec() function takes the following input:
1. Connection handle to the database
2. SQL query
3. Name of callback function to call for every row of results from database
4. First argument to callback function (the NotUsed argument in the callback function above)
5. Error message holder to return error messages in (if any)
After these arguments have all been satisfied, sqlite3_exec() will call the callback function with the results. Here is an example of output:
Database open
id = 1
login = anders
password = dator123
id = 2
login = niklas
password = dator123
id = 3
login = miew
password = dator123
Query successful
and that is it. We now have a small and simple example of how you connect and query a SQLite database using C.
NOTE: When compiling do not forget to add the -lsqlite3 argument to gcc:
gcc test.c -o test -lsqlite3 -Wall
This has been tested on SQLite 3.7.15.2, gcc 4.2 and OSX 10.7.5