The homepage for SQLite claims that it is the most deployed widely SQL database in the world. I don’t know if that is true but SQLite is a powerful light-weight SQL database.
http://sqlite.org/
I discovered this library while I was talking to some folks on IRC (#C++ on EFNET). I was working on my own MP3 player at the time and needed a “default” database. The first version of the program I wrote required the MSDE to be installed which was way too heavy / hard to configure for end users. I dug into SQLite (version 3.x) and one immediate downside was that I had to get the source code and hack around before I could use it. Even though the documentation wasn’t great I was pleased with the result.
Setup
Start off by just downloading the DLL. On the download page grab the version for Windows that says “This is a DLL of the SQLite library without the TCL bindings”. After downloading the zip, you’ll notice there is only a .DLL and a .DEF file. You’ll need a header and a .lib file in order to compile against the DLL.
Open up the Visual Studio command prompt and navigate to the folder you unzipped the DLL/DEF to. You can then run this command:
lib /machine:i386 /def:sqlite3.def
This will generate the .lib and .exp for the DLL. What I did to find the header is download the source code for the library itself. I grabbed the “sqlite3.h” header file from the source code that was grouped as “individual source files”. Once you grab the header just add the link to the .lib file in your compiler and you’re ready.
Opening and closing the database
#include "sqlite3.h"
sqlite3* db;
if (sqlite3_open("my_database.db", &db)) {
printf("Can't open database: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
}
When you’re done using the database, close it using:
sqlite3_close(db);
Executing Non-Queries
std::string sql = "UPDATE Song SET AlbumID = NULL;";
if (sqlite3_exec(db,sql.c_str(), 0, 0, 0)) {
printf("Failed to update rows: %s\n", sqlite3_errmsg(db));
}
Executing Queries (SELECTing data)
Executing SELECT queries in SQLite is pretty horrible in my opinion. You execute it the same way as you do a non-query, except you will need to use the callback parameter.
sqlite3_exec(db, sql_query_here, callback_here, NULL, 0);
int SampleCallback(void* data, int argc, char** argv, char** ColName) {
int SongID = atoi(argv[0]);
std::string SongName = std::string(argv[1]);
return 0;
}
Other notes
In my experience SQLite is pretty slow. If you’re after performance you’ll definitely want to choose MS SQL Server, Oracle, or MySQL. SQLite only allows for one “connection” so to speak. You’ll want to wrap a mutex around your DB calls or else you’ll get unexpected behavior.
If you’re a big MS SQL Server programmer like I am, you are probably used to getting the ID of the entry you just inserted. This is possible in SQLite. For example, if I insert a Song into my database and I want to get the identity of the Song entry that was just inserted… in SQL Server (in a stored procedure) you would use SCOPE_IDENTITY(). I had to ask around and then I found the SQLite function:
int myRowId = sqlite3_last_insert_rowid(db);