5,699,997 members and growing! (14,147 online)
Email Password   helpLost your password?
Languages » C / C++ Language » General     Intermediate License: The Code Project Open License (CPOL)

An easy to use wrapper for SQLite3 (Totally free embedded database engine!)

By Daniel Cohen Gindi

I have created classes to wrap the SQLite3 library, to remove many headaches...
VC6, VC7, VC7.1, VC8.0, C++Windows, Win2K, WinXP, Win2003, Vista, SQL Server, MFC, VS.NET2002, VS.NET2003, VS2005, VS6, Visual Studio, DBA, Dev

Posted: 18 Aug 2007
Updated: 23 Dec 2007
Views: 24,313
Bookmarked: 47 times
Announcements
Loading...



Search    
Advanced Search
Sitemap
23 votes for this Article.
Popularity: 5.92 Rating: 4.35 out of 5
1 vote, 4.3%
1
1 vote, 4.3%
2
2 votes, 8.7%
3
4 votes, 17.4%
4
15 votes, 65.2%
5
Note: This is an unedited contribution. If this article is inappropriate, needs attention or copies someone else's work without reference then please Report This Article

Introduction

Recently I was looking for a solution for embedded SQL/Database library, so I won't have to redistribute DAO/Jet/SQL Server Express/ODBC or some other database driver...

I ran into SQLite3, which is a protable library, written completely in C,
that allows you to create/managae databases, with SQL statements,
it is open source, no need for any kind of license,
compact footprint (size depending on compiler optimization, but just about 200KB!)
and it has no external dependencies.

I immediatly downloaded SQLite3 (http://www.sqlite.org), and wanted to immediately start using it.

Wait a moment, no OOP??? (Object oriented programming, c++...)

As I mentioned before, the library is completely written in C,
And not only that - it also works with multi-byte UTF-8 encoding...

I found out immediately that I needed to create some classes to wrap the library,
so I will be able to use it without any headaches...

SQLite is a database engine that you can download, add to your project, and run! There's absolutly zero-configuration needed!

Using the code

There are basically two classes: Database and Table, under the namespace SQLite.

Later update: Another class TablePtr to wrap a pointer to Table class.

Both classes use TCHAR to support Unicode.

The use is very simple, everything is documented inside the code.

The classes expect sqlite3 in folder .\SQLite\, you can change it in the source code for wherever you want.

When a function is specified as 'Safe' it means that even if it is a null object (e.g. Table * pTbl=0) the show will go on...

In the Database class there are the following methods:

int Open( LPCTSTR strFileName ) - Opens a new database, creating it if it does not already exist.

void Close() - Closes the database...

bool IsOpen() - Is a database open? (Safe function)

sqlite3 * GetPtr() - Returns the handle to the sqlite3 database.

int GetLastError() - Returns last error...

void CleanError() - Clean last error...

Table QuerySQL( LPCTSTR strSQL ) - Executes an SQL query, returning the results in the Table class

TablePtr QuerySQL2( LPCTSTR strSQL ) - The same as above, except it returns a pointer to the Table class, wrapped in a TablePtr.

int ExecuteSQL( LPCTSTR strSQL ) - Executes an SQL query, without expecting any results.

bool IsSQLComplete() - Checks if an SQL statement is complete (by the sqlite3 ideas and specs...)

int GetLastChangesCount() - Returns the count of changes made by the last SQL statement.

int ReadBlob( LPCTSTR strSQL, BYTE ** pData, int * iLenBlob ) - Read a BLOB value into pData, the length of the blob goes into iLenBlob. Expects only 1 record, 1 column!

int WriteBlob( LPCTSTR strSQL, BYTE * pData, int iLenBlob ) - Write a BLOB value using an INSERT or UPDATE sql statement.

sqlite_int64 GetLastInsertRowID() - Get the Row-ID of the last row inserted using INSERT. See SQLite doumentation for more info.

Functions Open(), GetLastError() & ExecuteSQL() return an SQLITE_ error, see sqlite3.h in the library for error definitions.

In the Table class, there are the following methods:

int GetColCount() - Returns number of columns. Safe function

int GetRowCount() - Returns number of rows. Safe function

int GetCurRow() - Returns the current selected row. Safe function

LPCTSTR GetColName( int iCol ) - Returns the name of the column at index iCol.

bool GoFirst() - Naviagtes to first record, returning false if no records exists. Safe function (returns false if Table is null)

bool GoLast() / GoNext() / GoPrev() - Naviagtes through the records...

bool GoRow() - Naviagtes to a specific record. Safe function (returns false if Table is null or out of bounds)

LPCTSTR GetValue(LPCTSTR lpColName) - Gets the value of the current row, in the column specified by lpColName (name of column);

LPCTSTR GetValue(int iColIndex) - Gets the value of the current row, in the iColIndex column (by column index)

LPCTSTR operator [] (LPCTSTR lpColName) - Same as GetValue(), for using with []

LPCTSTR operator [] (int iColIndex) - Same as GetValue(), for using with []

void JoinTable(Table & tblJoin) - Adds the rows of tblJoin to this table, if the column count is equal (or empty).

In the TablePtr class:

Table * m_pTable - Public member which points to a Table class.

Table * Detach() - Detaches the class from the Table, and returns the Table that were just detached...

void Attach( Table * pTable) - Frees the current Table, and attaches the pTable.

operator () - Now you do not have to use TablePtr::m_pTable, you can just use TablePtr().

operator bool() - Now you do not have to check if m_pTable is valid. Just "if (TablePtr) {...}".

Points of Interest

You may have noticed that you can only get values as strings...

That is because sqlite3 does not restrict ant field to its data type... so you can put a float instead of a string or an integer, or a string instead of an integer for example...

But sqlite3 try to convert to the 'preferred' datatype when it is possible.

So you can always expect a string, then if you know that it should be an integer, use _ttoi() to convert, or _tstof() to convert to float...

Comments

If you have any comments, requests, bugs... Feel free to contact me, and I will update as soon as I can.

Updates

20/08/2007 - I have just added a basic interface for BLOB readings and writing,
see the comments in the source code.

25/08/2007 - I have added the TablePtr class to wrap a pointer to the Table class. Suggested by Douglas R. Keesler, thanks!

01/10/2007 - I have made some modifications to make the code more safe. Also implemented JoinTable() for joining to table classes, and an () operator for the TablePtr. Also the GetLastInsertRowID() is implemented now.

20/11/2007 - Added the simple GetCurRow() to the Table class... Also added the documentation about GoRow()

23/12/2007 - Added the bool operator for TablePtr, so you can "if (TablePtr) {...}" to check if the m_pTable member is valid.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Daniel Cohen Gindi



Occupation: Software Developer (Senior)
Location: Israel Israel

Other popular C / C++ Language articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 24 of 24 (Total in Forum: 24) (Refresh)FirstPrevNext
GeneralDetail in CSocketStackmemberKarstenK2:34 28 Jan '08  
GeneralRe: Detail in CSocketStackmemberDaniel Cohen Gindi8:59 28 Jan '08  
GeneralLack of Samplessupporteryarp6:19 15 Jan '08  
GeneralRe: Lack of SamplesmemberDaniel Cohen Gindi9:05 28 Jan '08  
GeneralComing soon, SQLite server/client!memberDaniel Cohen Gindi10:01 23 Dec '07  
GeneralRe: Coming soon, SQLite server/client!memberMember 238825711:55 23 Dec '07  
GeneralGuys, theres an update!memberDaniel Cohen Gindi1:37 1 Oct '07  
GeneralRe: Guys, theres an update!memberrajas6:11 2 Oct '07  
GeneralRe: Guys, theres an update!memberDaniel Cohen Gindi7:40 2 Oct '07  
GeneralRe: Guys, theres an update!membergnk14:50 3 Oct '07  
GeneralRe: Guys, theres an update!memberDaniel Cohen Gindi7:30 4 Oct '07  
GeneralRe: Guys, theres an update!memberDaniel Cohen Gindi2:48 14 Oct '07  
GeneralRe: Guys, theres an update!memberrajas5:22 19 Oct '07  
GeneralTwo Minor GlitchesmemberDouglas R. Keesler0:52 25 Aug '07  
GeneralRe: Two Minor GlitchesmemberDaniel Cohen Gindi8:07 25 Aug '07  
GeneralRe: Two Minor GlitchesmemberDaniel Cohen Gindi9:00 25 Aug '07  
GeneralRe: Two Minor GlitchesmemberDouglas R. Keesler9:14 25 Aug '07  
GeneralRe: Two Minor GlitchesmemberDouglas R. Keesler9:12 25 Aug '07  
QuestionConfusedmemberDave Cross3:36 24 Aug '07  
AnswerRe: ConfusedmemberDaniel Cohen Gindi3:49 24 Aug '07  
AnswerRe: ConfusedmemberDouglas R. Keesler0:11 25 Aug '07  
GeneralRe: ConfusedmemberDave Cross2:26 27 Aug '07  
GeneralRe: ConfusedmemberDouglas R. Keesler11:31 27 Aug '07  
GeneralI have just added a basic BLOB support (20/08/2007)memberDaniel Cohen Gindi7:13 20 Aug '07  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 23 Dec 2007
Editor:
Copyright 2007 by Daniel Cohen Gindi
Everything else Copyright © CodeProject, 1999-2008
Web11 | Advertise on the Code Project