Their finishing a SQLite3 database access C ++ class

Original Address: Their finishing a SQLite3 database access C ++ class Author: vigra
Recently, the use of SQLite3 were studied. Really worthy of a good embedded database, API interface is also very simple. Use substantially as long as the ports to accomplish the following operation of the database:
 
sqlite3_open()
sqlite3_prepare()
sqlite3_step()
sqlite3_column()
sqlite3_finalize()
sqlite3_close()
However, API approach is not consistent with customary database development. We are a C ++ programmer, package it.
 
More than the Internet to find a Rob Groves wrote in 2004 of "C ++ wrapper around the SQLite3 embedded database library." Basic available, but too complicated, is not conducive to learning.
 
So, I have them simplified, leaving only three categories:
 
TSQLite3Exception for exception handling
 
TSQLite3Query return data for processing with SQL statement
 
TSQLite3DB for the operation of the database itself
 
After this simplification, while ensuring the basic premise of database operations, the number of lines of code becomes 1/3 of the original, simple, easy to use and recommend it to everyone.
 
Also attached some applications, sample code, to facilitate use. I tested using SQLite3 version 3.7.3
 
//---------------------------------------------------------------------------
int __fastcall TDataModule1::UpdateFounds(String sCode, String sName, String sDate, String sValue)
{
char SqlStr[500];
TSQLite3DB *db;
// open the database file
db = new TSQLite3DB();
 
try
{
try
{
db->open("data.s3db");
//update record
sprintf(SqlStr, "UPDATE FOUNDS SET FOUND_NAME='%s', DATE='%s', VALUE='%s' WHERE CODE='%s'",
AnsiString(sName).c_str(), AnsiString(sDate).c_str(), AnsiString(sValue).c_str(), AnsiString(sCode).c_str());
db->execDML(SqlStr);
}
catch(const TSQLite3Exception &e)
{
ShowMessage (String ( "Failed to update record!") + E.errorMessage ());
}
catch(...)
{
return -1;
}
 
return 0;
}
 
__finally
{
delete db;
}
}
//---------------------------------------------------------------------------
int __fastcall TDataModule1::FillListViewFirst(TListView *ListView)
{
TListItem * pItem = NULL;
TSQLite3DB *db;
// open the database file
db = new TSQLite3DB();
 
try
{
try
{
db->open("data.s3db");
TSQLite3Query Results = db->execQuery("SELECT * FROM FOUNDS ORDER BY CODE");
ListView->Items->Clear();
 
for( ; !Results.eof(); Results.nextRow())
{
// If you do not show, skip
if(strncmp("是", Results.getStringField(4, ""), 2) == 0)
{
pItem = ListView->Items->Add();
// Column 1
pItem->Caption = String(Results.getStringField(0, ""));
// The first two
pItem->SubItems->Add(Results.getStringField(1, ""));
// The first three
pItem->SubItems->Add(Results.getStringField(2, ""));
// The first four
pItem->SubItems->Add(Results.getStringField(3, ""));
}
}
}
catch(const TSQLite3Exception &e)
{
ShowMessage (String ( "query record failed!") + E.errorMessage ());
}
catch(...)
{
return -1;
}
 
return 0;
}
 
__finally
{
delete db;
}
}
 
 
 
 
//---------------------------------------------------------------------------
 
#include <string.h>
#include <time.h>
#pragma hdrstop
 
#include "SQLite3_unit.h"
#pragma package(smart_init)
 
// Named constant for passing to TSQLite3Exception when passing it a string
// that cannot be deleted.
static const bool DONT_DELETE_MSG = false;
// Timeout values on busy or lock conditions
static const int SQLTM_TIMEOUT = 6000; // 6 seconds
 
////////////////////////////////////////////////////////////////////////////////
 
TSQLite3Exception::TSQLite3Exception(const int nErrCode,
char *szErrMess,
bool bDeleteMsg) :
mnErrCode (nErrCode)
{
mpszErrMess = sqlite3_mprintf("%s[%d]: %s",
errorCodeAsString(nErrCode),
nErrCode,
szErrMess ? szErrMess : "");
 
if(bDeleteMsg && szErrMess)
{
sqlite3_free(szErrMess);
}
}
//---------------------------------------------------------------------------
 
 
TSQLite3Exception::TSQLite3Exception(const TSQLite3Exception &e) :
mnErrCode(e.mnErrCode)
{
mpszErrMess = 0;
 
if(e.mpszErrMess)
{
mpszErrMess = sqlite3_mprintf("%s", e.mpszErrMess);
}
}
//---------------------------------------------------------------------------
 
 
const char *TSQLite3Exception::errorCodeAsString(int nErrCode)
{
switch(nErrCode)
{
case SQLITE_OK :
return "Successful result";
case SQLITE_ERROR :
return "SQL error or missing database";
case SQLITE_INTERNAL :
return "Internal logic error in SQLite ";
case SQLITE_PERM :
return "Access permission denied";
case SQLITE_ABORT :
return "Callback routine requested an abort";
case SQLITE_BUSY :
return "The database file is locked";
case SQLITE_LOCKED :
return "A table in the database is locked";
case SQLITE_NOMEM :
return "A malloc() failed";
case SQLITE_READONLY :
return "Attempt to write a readonly database";
case SQLITE_INTERRUPT :
return "Operation terminated by sqlite3_interrupt()";
case SQLITE_IOERR :
return "Some kind of disk I/O error occurred ";
case SQLITE_CORRUPT :
return "The database disk image is malformed";
case SQLITE_NOTFOUND :
return "NOT USED. Table or record not found";
case SQLITE_FULL :
return "Insertion failed because database is full";
case SQLITE_CANTOPEN :
return "Unable to open the database file";
case SQLITE_PROTOCOL :
return "Database lock protocol error";
case SQLITE_EMPTY :
return "Database is empty";
case SQLITE_SCHEMA :
return "The database schema changed";
SQLITE_TOOBIG case:
return "String or BLOB exceeds size limit";
case SQLITE_CONSTRAINT :
return "Abort due to constraint violation";
case SQLITE_MISMATCH :
return "Data type mismatch";
case SQLITE_MISUSE :
return "Library used incorrectly";
case SQLITE_NOLFS :
return "Uses OS features not supported on host";
case SQLITE_AUTH :
return "Authorization denied";
case SQLITE_FORMAT :
return "Auxiliary database format error";
case SQLITE_RANGE :
return "2nd parameter to sqlite3_bind out of range";
case SQLITE_NOTADB :
return "File opened that is not a database file";
case SQLITE_ROW :
return "sqlite3_step() has another row ready";
case SQLITE_DONE :
return "sqlite3_step() has finished executing";
case TSQLITE_ERROR :
return "TSQLITE_ERROR";
default:
return "UNKNOWN_ERROR";
}
}
//---------------------------------------------------------------------------
TSQLite3Exception::~TSQLite3Exception()
{
if(mpszErrMess)
{
sqlite3_free(mpszErrMess);
mpszErrMess = 0;
}
}
////////////////////////////////////////////////////////////////////////////////
//---------------------------------------------------------------------------
TSQLite3Query::TSQLite3Query()
{
mpDB = 0;
mpVM = 0;
mbEof = true;
mnCols = 0;
mbOwnVM = false;
}
//---------------------------------------------------------------------------
TSQLite3Query::TSQLite3Query(const TSQLite3Query &rQuery)
{
mpDB = rQuery.mpDB;
mpVM = rQuery.mpVM;
// Only one object can own the VM
const_cast<TSQLite3Query &>(rQuery).mpVM = 0;
mbEof = rQuery.mbEof;
mnCols = rQuery.mnCols;
mbOwnVM = rQuery.mbOwnVM;
}
//---------------------------------------------------------------------------
TSQLite3Query::TSQLite3Query(sqlite3 *pDB,
sqlite3_stmt *pVM,
bool bEof,
bool bOwnVM)
{
mpDB = pDB;
mpVM = pVM;
mbEof = bEof;
mnCols = sqlite3_column_count(mpVM);
mbOwnVM = bOwnVM;
}
//---------------------------------------------------------------------------
TSQLite3Query::~TSQLite3Query()
{
try
{
finalize();
}
catch(...)
{
}
}
//---------------------------------------------------------------------------
TSQLite3Query &TSQLite3Query::operator=(const TSQLite3Query &rQuery)
{
try
{
finalize();
}
catch(...)
{
}
 
mpDB = rQuery.mpDB;
mpVM = rQuery.mpVM;
// Only one object can own the VM
const_cast<TSQLite3Query &>(rQuery).mpVM = 0;
mbEof = rQuery.mbEof;
mnCols = rQuery.mnCols;
mbOwnVM = rQuery.mbOwnVM;
return *this;
}
//---------------------------------------------------------------------------
int TSQLite3Query::numFields()
{
checkVM();
return mnCols;
}
//---------------------------------------------------------------------------
const char *TSQLite3Query::fieldValue(int nField)
{
checkVM();
 
if(nField < 0 || nField > mnCols - 1)
{
throw TSQLite3Exception(TSQLITE_ERROR,
"Invalid field index requested",
DONT_DELETE_MSG);
}
 
return (const char *)sqlite3_column_text(mpVM, nField);
}
//---------------------------------------------------------------------------
const char *TSQLite3Query::fieldValue(const char *szField)
{
int nField = fieldIndex(szField);
return (const char *)sqlite3_column_text(mpVM, nField);
}
//---------------------------------------------------------------------------
int TSQLite3Query::getIntField(int nField, int nNullValue)
{
if(fieldDataType(nField) == SQLITE_NULL)
{
return nNullValue;
}
else
{
return sqlite3_column_int(mpVM, nField);
}
}
//---------------------------------------------------------------------------
int TSQLite3Query::getIntField(const char *szField, int nNullValue)
{
int nField = fieldIndex(szField);
return getIntField(nField, nNullValue);
}
//---------------------------------------------------------------------------
double TSQLite3Query::getFloatField(int nField, double fNullValue)
{
if(fieldDataType(nField) == SQLITE_NULL)
{
return fNullValue;
}
else
{
return sqlite3_column_double(mpVM, nField);
}
}
//---------------------------------------------------------------------------
double TSQLite3Query::getFloatField(const char *szField, double fNullValue)
{
int nField = fieldIndex(szField);
return getFloatField(nField, fNullValue);
}
//---------------------------------------------------------------------------
const char *TSQLite3Query::getStringField(int nField, const char *szNullValue)
{
if(fieldDataType(nField) == SQLITE_NULL)
{
return szNullValue;
}
else
{
return (const char *)sqlite3_column_text(mpVM, nField);
}
}
//---------------------------------------------------------------------------
const char *TSQLite3Query::getStringField(const char *szField, const char *szNullValue)
{
int nField = fieldIndex(szField);
return getStringField(nField, szNullValue);
}
//---------------------------------------------------------------------------
const unsigned char *TSQLite3Query::getBlobField(int nField, int &nLen)
{
checkVM();
 
if(nField < 0 || nField > mnCols - 1)
{
throw TSQLite3Exception(TSQLITE_ERROR,
"Invalid field index requested",
DONT_DELETE_MSG);
}
 
nLen = sqlite3_column_bytes(mpVM, nField);
return (const unsigned char *)sqlite3_column_blob(mpVM, nField);
}
//---------------------------------------------------------------------------
const unsigned char *TSQLite3Query::getBlobField(const char *szField, int &nLen)
{
int nField = fieldIndex(szField);
return getBlobField(nField, nLen);
}
//---------------------------------------------------------------------------
bool TSQLite3Query::fieldIsNull(int nField)
{
return (fieldDataType(nField) == SQLITE_NULL);
}
//---------------------------------------------------------------------------
bool TSQLite3Query::fieldIsNull(const char *szField)
{
int nField = fieldIndex(szField);
return (fieldDataType(nField) == SQLITE_NULL);
}
//---------------------------------------------------------------------------
int TSQLite3Query::fieldIndex(const char *szField)
{
checkVM();
 
if(szField)
{
for(int nField = 0; nField < mnCols; nField++)
{
const char *szTemp = sqlite3_column_name(mpVM, nField);
 
if(strcmp(szField, szTemp) == 0)
{
return nField;
}
}
}
 
throw TSQLite3Exception(TSQLITE_ERROR,
"Invalid field name requested",
DONT_DELETE_MSG);
}
//---------------------------------------------------------------------------
const char *TSQLite3Query::fieldName(int nCol)
{
checkVM();
 
if(nCol < 0 || nCol > mnCols - 1)
{
throw TSQLite3Exception(TSQLITE_ERROR,
"Invalid field index requested",
DONT_DELETE_MSG);
}
 
return sqlite3_column_name(mpVM, nCol);
}
//---------------------------------------------------------------------------
const char *TSQLite3Query::fieldDeclType(int nCol)
{
checkVM();
 
if(nCol < 0 || nCol > mnCols - 1)
{
throw TSQLite3Exception(TSQLITE_ERROR,
"Invalid field index requested",
DONT_DELETE_MSG);
}
 
return sqlite3_column_decltype(mpVM, nCol);
}
//---------------------------------------------------------------------------
int TSQLite3Query::fieldDataType(int nCol)
{
checkVM();
 
if(nCol < 0 || nCol > mnCols - 1)
{
throw TSQLite3Exception(TSQLITE_ERROR,
"Invalid field index requested",
DONT_DELETE_MSG);
}
 
return sqlite3_column_type(mpVM, nCol);
}
//---------------------------------------------------------------------------
bool TSQLite3Query::eof()
{
checkVM();
return mbEof;
}
//---------------------------------------------------------------------------
void TSQLite3Query::nextRow()
{
checkVM();
int nRet = sqlite3_step(mpVM);
 
if(nRet == SQLITE_DONE)
{
// no rows
mbEof = true;
}
else if(nRet == SQLITE_ROW)
{
// more rows, nothing to do
}
else
{
nRet = sqlite3_reset(mpVM);
mpVM = 0;
const char *szError = sqlite3_errmsg(mpDB);
throw TSQLite3Exception(nRet,
(char *)szError,
DONT_DELETE_MSG);
}
}
//---------------------------------------------------------------------------
void TSQLite3Query::finalize()
{
if(mpVM && mbOwnVM)
{
int nRet = sqlite3_finalize(mpVM);
mpVM = 0;
 
if(nRet != SQLITE_OK)
{
const char *szError = sqlite3_errmsg(mpDB);
throw TSQLite3Exception(nRet, (char *)szError, DONT_DELETE_MSG);
}
}
else if(mpVM && !mbOwnVM)
{
sqlite3_reset(mpVM);
}
}
//---------------------------------------------------------------------------
void TSQLite3Query::checkVM()
{
if(mpVM == 0)
{
throw TSQLite3Exception(TSQLITE_ERROR,
"Null Virtual Machine pointer",
DONT_DELETE_MSG);
}
}
////////////////////////////////////////////////////////////////////////////////
//---------------------------------------------------------------------------
TSQLite3DB :: TSQLite3DB ()
{
mpDB = 0;
mnBusyTimeoutMs = SQLTM_TIMEOUT;
}
//---------------------------------------------------------------------------
TSQLite3DB::TSQLite3DB(const TSQLite3DB &db)
{
mpDB = db.mpDB;
mnBusyTimeoutMs = SQLTM_TIMEOUT;
}
//---------------------------------------------------------------------------
TSQLite3DB :: ~ TSQLite3DB ()
{
close();
}
//---------------------------------------------------------------------------
TSQLite3DB &TSQLite3DB::operator=(const TSQLite3DB &db)
{
mpDB = db.mpDB;
mnBusyTimeoutMs = SQLTM_TIMEOUT;
return *this;
}
//---------------------------------------------------------------------------
void TSQLite3DB::open(const char *szFile)
{
int nRet = sqlite3_open(szFile, &mpDB);
 
if(nRet != SQLITE_OK)
{
const char *szError = sqlite3_errmsg(mpDB);
throw TSQLite3Exception(nRet, (char *)szError, DONT_DELETE_MSG);
}
 
setBusyTimeout(mnBusyTimeoutMs);
}
//---------------------------------------------------------------------------
void TSQLite3DB::close()
{
if(mpDB)
{
int Result = sqlite3_close(mpDB);
 
if(Result != SQLITE_OK)
{
const char *szError = sqlite3_errmsg(mpDB);
throw TSQLite3Exception(Result, (char *)szError, DONT_DELETE_MSG);
}
 
mpDB = 0;
}
}
//---------------------------------------------------------------------------
int TSQLite3DB::execDML(const char *szSQL)
{
checkDB();
char *szError = 0;
int nRet = sqlite3_exec(mpDB, szSQL, 0, 0, &szError);
 
if(nRet == SQLITE_OK)
{
return sqlite3_changes(mpDB);
}
else
{
throw TSQLite3Exception(nRet, szError);
}
}
//---------------------------------------------------------------------------
TSQLite3Query TSQLite3DB::execQuery(const char *szSQL)
{
checkDB();
sqlite3_stmt *pVM = compile(szSQL);
int nRet = sqlite3_step(pVM);
 
if(nRet == SQLITE_DONE)
{
// no rows
return TSQLite3Query(mpDB, pVM, true);
}
else if(nRet == SQLITE_ROW)
{
// at least 1 row
return TSQLite3Query(mpDB, pVM, false);
}
else
{
nRet = sqlite3_finalize(pVM);
const char *szError = sqlite3_errmsg(mpDB);
throw TSQLite3Exception(nRet, (char *)szError, DONT_DELETE_MSG);
}
}
//---------------------------------------------------------------------------
sqlite_int64 TSQLite3DB::lastRowId()
{
return sqlite3_last_insert_rowid(mpDB);
}
//---------------------------------------------------------------------------
void TSQLite3DB::setBusyTimeout(int nMillisecs)
{
mnBusyTimeoutMs = nMillisecs;
sqlite3_busy_timeout(mpDB, mnBusyTimeoutMs);
}
//---------------------------------------------------------------------------
void TSQLite3DB::checkDB()
{
if(!mpDB)
{
throw TSQLite3Exception(TSQLITE_ERROR,
"Database not open",
DONT_DELETE_MSG);
}
}
//---------------------------------------------------------------------------
sqlite3_stmt *TSQLite3DB::compile(const char *szSQL)
{
checkDB();
const char *szTail = 0;
sqlite3_stmt *pVM;
int nRet;
nRet = sqlite3_prepare_v2(mpDB, szSQL, -1, &pVM, &szTail);
 
if(nRet != SQLITE_OK)
{
const char *szError = sqlite3_errmsg(mpDB);
throw TSQLite3Exception(nRet,
(char *)szError,
DONT_DELETE_MSG);
}
 
return pVM;
}
//---------------------------------------------------------------------------
 
 
//---------------------------------------------------------------------------
 
#ifndef SQLite3_unitH
#define SQLite3_unitH
 
#include "sqlite3.h"
 
#define TSQLITE_ERROR 1000
 
//---------------------------------------------------------------------------
class TSQLite3Exception
{
public:
 
TSQLite3Exception(const int nErrCode,
char *szErrMess,
bool bDeleteMsg = true);
 
TSQLite3Exception(const TSQLite3Exception &e);
 
virtual ~TSQLite3Exception();
 
int errorCode() const
{
return mnErrCode;
}
 
char *errorMessage() const
{
return mpszErrMess;
}
 
static const char *errorCodeAsString(int nErrCode);
 
private:
 
int mnErrCode;
char *mpszErrMess;
};
//---------------------------------------------------------------------------
class TSQLite3Query
{
public:
 
TSQLite3Query();
 
TSQLite3Query(const TSQLite3Query &rQuery);
 
TSQLite3Query(sqlite3 *pDB,
sqlite3_stmt *pVM,
bool bEof,
bool bOwnVM = true);
 
TSQLite3Query &operator=(const TSQLite3Query &rQuery);
 
virtual ~TSQLite3Query();
 
int numFields();
 
int fieldIndex(const char *szField);
const char *fieldName(int nCol);
 
const char *fieldDeclType(int nCol);
int fieldDataType(int nCol);
 
const char *fieldValue(int nField);
const char *fieldValue(const char *szField);
 
int getIntField(int nField, int nNullValue = 0);
int getIntField(const char *szField, int nNullValue = 0);
 
double getFloatField(int nField, double fNullValue = 0.0);
double getFloatField(const char *szField, double fNullValue = 0.0);
 
const char *getStringField(int nField, const char *szNullValue = "");
const char *getStringField(const char *szField, const char *szNullValue = "");
 
const unsigned char *getBlobField(int nField, int &nLen);
const unsigned char *getBlobField(const char *szField, int &nLen);
 
bool fieldIsNull(int nField);
bool fieldIsNull(const char *szField);
 
bool eof();
void nextRow();
void finalize();
 
private:
 
void checkVM();
 
sqlite3 *mpDB;
sqlite3_stmt *mpVM;
bool mbEof;
int mnCols;
bool mbOwnVM;
};
//---------------------------------------------------------------------------
class TSQLite3DB
{
public:
TSQLite3DB ();
virtual ~TSQLite3DB();
void open(const char *szFile);
void close();
int execDML(const char *szSQL);
TSQLite3Query execQuery(const char *szSQL);
void setBusyTimeout(int nMillisecs);
sqlite_int64 lastRowId();
 
void interrupt()
{
sqlite3_interrupt(mpDB);
}
 
bool isAutoCommit()
{
return sqlite3_get_autocommit(mpDB) != 0;
}
 
static const char *SQLiteVersion()
{
return SQLITE_VERSION;
}
 
sqlite3 *getDB()
{
return mpDB;
}
private:
 
TSQLite3DB(const TSQLite3DB &db);
TSQLite3DB &operator=(const TSQLite3DB &db);
 
sqlite3_stmt *compile(const char *szSQL);
 
void checkDB();
 
sqlite3 *mpDB;
int mnBusyTimeoutMs;
};
 
//---------------------------------------------------------------------------
 
#endif
 
 
 

Guess you like

Origin www.cnblogs.com/blogpro/p/11426881.html